﻿/*********************************************
autofilltopic.js
autofill functionality for the search boxes
************************************************/

/******DECLARATIONS***************************/
var diveInvisible = "aflist_div_invisible";
var divvisible = "aflist_div_visible";
var listitemhead = "aflist_item_head";
var webServiceUrl = "/webservices/AutoFillTopicSearvice.svc";//TopicListService.asmx";
var textXmlMime = "text/xml";
var responseValueTagName = "string";
var divName = "AFList";
var itemIdSuffix = "_item";
var listitemHighlighted = "aflist_item_highlighted";
var listitemNormal = "aflist_item_normal"; 
var UPARROW = 38;
var DOWNARROW = 40;
var ENTER = 13;
var HEAD_HTML, FOOT_HTML;
var _head_html = "<img id=\"AutoFillListBanner\" src=\"/img/encybeta/dropdown_beta_bar.gif\" />";
var req;        //THE XML REQUEST OBJECT
var itemlist;   //the list of strings to fill the dropdown
var _clientid;  //the client id to the aspx control
var _hiddenid;  //client id of the hiddenfield for the search term

/**********string builders**************/

//create request url to WCF service
function createAFRequestUrl( startswith,  count)
{
    return "/webservices/AutoFillTopicSearvice.svc/GetAutoFillList?prefixText=" + startswith + "&count=" + count;//TopicListService.asmx";
}

//create the button's client id
function createButtonId(clientid)
{
    return clientid.replace("_TextBoxSearchTerm","") + "_ButtonFindTopic";
}

//create the dropdown's div client id
function createDivId(clientid)
{
    return clientid + "_aflistDiv";
}

//create list item id
function createAflistItemId(divid, itemnumber)
{
    return divid + itemIdSuffix + itemnumber.toString();
}

//create the search box's client id
function createSearchBoxId(clientid)
{
    return clientid + "_searchbox";
}

//create the SOAP envelope to the ASMX service
function createEnvelope(startswith,count)
{
    return '<?xml version="1.0" encoding="utf-8"?><soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"><soap12:Body><GetAutoFillList xmlns="http://tempuri.org/"><prefixText>' + startswith + '</prefixText><count>' + count + '</count></GetAutoFillList></soap12:Body></soap12:Envelope>'
}

/*************UTILS**********************/

//get the event source (cross browser)
function getEventSource(ev)
{
	var res = null;
    if(ev && ev.target)			//Moz
    {
        res = ev.target;
    }
	
	if(!res && window.event)	//IE
    {
        res = window.event.srcElement;
    }
    
    return res;
}

//reset variables
function resetAutoFill()
{
    tbstr = "";
    req = null;
    pos = -1;
}

//create an XMLHTTPRequest (cross browser)
function createrequest()
{
    var ua = navigator.userAgent.toLowerCase();
   if (!window.ActiveXObject)
     req = new XMLHttpRequest();
   else if (ua.indexOf('msie 5') == -1)
     req = new ActiveXObject("Msxml2.XMLHTTP");
   else
     req = new ActiveXObject("Microsoft.XMLHTTP");
     
}

//create an XMLDocument (cross browser)
function createXmlDoc()
{
    var doc;
    
        try
        {
            doc = new DOMParser();
        }
        catch(e)
        {
            doc = new ActiveXObject("Microsoft.XMLDOM");
        }
        
        if(doc)
            doc.async=false;
        
    return doc;
}

//get event's keycode (cross browser)
function getKeyCode(e)
{
    var key;
    if(window.event)
        key = window.event.keyCode; 
    else
         key = e.which;
    return key;
}


/************UI FUNCTIONS******************/

//handle up, down and enter keys
function afKeyDown(clientid,e)
{
    _clientid = clientid;
    var key = getKeyCode(e);
    var divid = createDivId(clientid);
    
    switch(key)
    {
        case UPARROW: 
            moveUp(divid);
            break;
        case DOWNARROW: 
            moveDown(divid);
            break;
        case ENTER: 
            goToSelected(divid);
            break;
    }
}

//send the akax request to update the list 
//based on the current searchbox value
function beginUpdateList(kpe)
{
     //get keycode value
   var key = getKeyCode(kpe);;
    
    if(key == 13
    || key == 38
    || key == 40)
        return;
        
     //get textbox value
    var tb = getEventSource(kpe);
    if(!tb)
        return;
        
   var sw = tb.value;
        
    //get request
    createrequest();
    
    if(!req)
        return;
        
   

    //open the request to the web service
    req.open("GET",createAFRequestUrl( sw,  10));
      //set up onreadystatechange event
    req.onreadystatechange = handleReqProgress;
    //send the request
    req.send(null);
    //hack for async calls in FF without firebug or when firebug's dissabled
    try //breaks in IE 
    {
        if(req.onreadystatechange == null)
            handleReqProgress();
     }catch(e){}
        
    
}

//handle the onreadystatechange event of the xmlhttprequest
function handleReqProgress()
{
    //we only care when it's done
    if(!req || req.readyState != 4 )
        return;
    
    //make sure there's response text
    if(req.responseText)
    {
        //get the returned object from the response's json
        //the list is actually a member of the object
        var _list  = eval('(' + req.responseText + ')');
        //make sure there's a list
        if(_list && _list.d)
            itemlist = _list.d; //assign to itemlist
        else
            itemlist = null;    //or make sure its empty
    }
    
    //write results or hide the list
    if(itemlist && itemlist.length > 0)
    {
        writeList();
    }
    else
    {
        hidelist();
    }
    
}

//hide the autofill div
function hidelist()
{
    if(!_clientid)
        return;
        
    var divname = createDivId(_clientid);
    var div = document.getElementById(divname);
    if(!div)
        return;
        
    div.className = diveInvisible;
       
}

//write contents of itemlist to the dropdown list
function writeList()
{
    var str;    //holds the innerhtml of the div
    var divname = createDivId(_clientid);
    var selname = getCurrentItemId(divname);
    var ulname = divname + "_ul"; 
    str = '<ul class="' + divName + '" id="' + ulname + '" >';
    var liid;
    var listart;
    if(itemlist && itemlist.length > 0)
    {
        if(HEAD_HTML)
        {
            str +="<li id=\"" + createAflistItemId(divname,"_head") + "\" class=\"" + listitemhead + "\" >" + _head_html + "</li>";
        }
        
        for(var x = 0; x < itemlist.length;x++)
        {
            liid = createAflistItemId(divname,x);
            if(liid == selname)
                listart = "<li id=\"" + liid + "\" class=\"" +  listitemHighlighted + "\"";
            else
                listart = "<li id=\"" + liid + "\" class=\"" +  listitemNormal + "\"";
                
            listart += " onmouseover=\"AfMouseOver('"+ liid + "')\" onmouseout=\"AfMouseOut('" + liid + "')\" onClick=\"AfItemClick('" + liid + "')\" >";
            
            str += listart + itemlist[x][0] + "</il>";
            
//            liid = createAflistItemId(divname,x);
//            if(liid == selname)
//                listart = "<li id=\"" + liid + "\" class=\"" +  listitemHighlighted + "\""
//            else
//                listart = "<li id=\"" + liid + "\" class=\"" +  listitemNormal + "\"";
//                
//            listart += " onmouseover=\"AfMouseOver('"+ liid + "')\" onmouseout=\"AfMouseOut('" + liid + "')\" onClick=\"AfItemClick('" + liid + "')\" >"
//            
//            str += listart + itemlist[x] + "</il>";
        }
    }
    
    str = str + "</ul>";
    
    //get the div
    var div = document.getElementById(divname);
    if(!div)
        return;

    //make the div visible
    div.className  = divvisible;
    

    //set the inner html to the list's html
   div.innerHTML = str;
 
}

//unselect an item as the mouse leaves it
function AfMouseOut(itemId)
{
    var li = document.getElementById(itemId);
    if(!li)
        return;
    
    li.className = listitemNormal;
}

//select an item when the mouse entersa it
function AfMouseOver(itemId)
{
    //get the list item that's getting hovered over
    var li = document.getElementById(itemId);
    if(!li)
        return;
    
    //make sure any item selected my the mouse or up down keys is deselected
    clearSelection();
    //select the list item
    li.className = listitemHighlighted;
}

//clear all selected list items
function clearSelection()
{
    if(!itemlist || itemlist.length == 0)
        return null;
        
    var divid = createDivId(_clientid);
    var item = null;    
    for(var x = 0;x < itemlist.length;x++)
    {
        item = document.getElementById(createAflistItemId(divid,x));
        if(item)
        {
            item.className = listitemNormal;
        }
    }
        
}

//handle the list item's click event
function AfItemClick(itemId)
{
    //note: itemId is obsolete.
    //the item will slready be selected by the hover event
    //so just move go there
    goToSelected(createDivId(_clientid));
}

//move the selection to the next list item down
function moveDown()
{
    if(!itemlist || itemlist.length == 0)
        return;
        
    
    var divid = createDivId(_clientid);
    
    //get current position
    var cpos = getCurrentPosition(divid);
    
    //check to see if we're at the end
    if(itemlist && cpos >= itemlist.length - 1)
        return;
        
    //move to next position
    switchToItem(divid,cpos + 1);
    
    //writeList();
}

//move the selection to the next item up
function moveUp()
{

     if(!itemlist || itemlist.length == 0)
        return;
        
    var divid = createDivId(_clientid);
    
    //get current position
    var cpos = getCurrentPosition(divid);
    
    //check to see if we're at the end
    if(cpos == -1)
        return;
        
    //move to next position
    switchToItem(divid,cpos - 1);
}

//set the search term to the selected item and 
//call the button's click event to postback
function goToSelected(divid)
{
    //get selected index
        var index = getCurrentPosition(divid);

    //no items, perform search
    if(!itemlist || itemlist.length == 0 || index < 0)
    {
        var tb = document.getElementById(createSearchBoxId(_clientid));
        if(!tb)
            return;
            
        //get the button
        var btn = document.getElementById(createButtonId(_clientid));
        if(!btn)
            return;
        
        var term;
        if(tb.textContent)
            term = tb.textContent;
        else if(tb.innerText)
            term = tb.innerText;
        else if(tb.value)
            term = tb.value;
        
        //click the button
        btn.click();
        // for some reason if you uncomment the following line there's a near certainty that 
        // the resulting postback will be to the current page (ruining url rewriting in the process) without running a search
        // when in firefox
       // __doPostBack("SEARCH:" + createButtonId(_clientid),term?term:"");
    }
    else
    {
          
          //get the text and url
          var term = itemlist[index][0]
          var href = itemlist[index][1];
          
          //if both values are presant (if not, something bad has happened, do nothing)
          //set the search term textbox and do a postback to the page with the correct info
          if(term && href)
          {
              //set serch term
              setSearchTerm(_clientid,term);
              
              //postback to server with the search term for redirect
             __doPostBack("TOPIC:" + term,href);
         }
     }
     
}

//set the text of the search box
function setSearchTerm(clientid,term)
{
    var tb = document.getElementById(createSearchBoxId(clientid));
    if(!tb || !term)
        return;
        
     try{tb.value = term;}catch(er1){}
       try{tb.textContent = term;}catch(er2){}
       try{tb.innerText = term;}catch(er3){}
       
     
}

//select a given item in the list
function switchToItem(divid, index)
{
    //get id to current item
    var oldsel = document.getElementById(getCurrentItemId(divid));
    var newsel = document.getElementById(createAflistItemId(divid,index));
   
   clearSelection();
   
   if(oldsel)
        oldsel.className = listitemNormal;
        
    if(newsel && index >= 0)
        newsel.className = listitemHighlighted;
}

//get the id of the currently selected item
function getCurrentItemId(divid)
{

     if(!itemlist || itemlist.length == 0)
        return null;
        
    var found;
    found = false;
    var item;
    for(var x = 0;x < itemlist.length;x++)
    {
        item = document.getElementById(createAflistItemId(divid,x));
        if(item)
        {
            if(item.className == listitemHighlighted)
            {
                found = true;
                break;
            }
        }
    }
    
    if(!found)
        return null;
    else
        return item.id;
}

//get the sext of the currently selected item
function getCurrentSelectedText(divid)
{
     if(!itemlist || itemlist.length == 0)
        return null;
        
    var found;
    found = false;
    var item;
    for(var x = 0;x < itemlist.length;x++)
    {
        item = document.getElementById(createAflistItemId(divid,x));
        if(item)
        {
            if(item.className == listitemHighlighted)
            {
                found = true;
                break;
            }
        }
    }
    
    if(!found)
        return null;
    else if(item.innerText)//IE
    {
        return item.innerText;
    }
    else if(item.textContent)//FF
    {
        return item.textContent;
    }
        
}

//get the current selected index
function getCurrentPosition(divid)
{
     if(!itemlist || itemlist.length == 0)
        return -1;
        
    var index ;
    index = -1;
    var found;
    found = false;
    var item;
    for(var x = 0;x < itemlist.length;x++)
    {
        item = document.getElementById(createAflistItemId(divid,x));
        if(item)
        {
            if(item.className == listitemHighlighted)
            {
                index = x;
                found = true;
                break;
            }
        }
    }
    
    if(!found)
        return -1;
    else
        return index;
}



