//Global variable and methods that keeps track of all ASB 
//javascript objects on the page

var g_isIE = false;
var g_searchBoxes;
var g_isDrawerMoving = false;

if ( navigator.appName.indexOf('Microsoft') != -1 )
{
    g_isIE = true;    
};

function addObj(textBoxID, textBox)
{    
	if (typeof(g_searchBoxes) == "undefined")
	{
	    g_searchBoxes=new Array();	    
	}
			
	g_searchBoxes[textBoxID]=textBox;
}


function getObj(textBoxID)
{	    
	return g_searchBoxes[textBoxID];
}

//Mouse over function
function suggestOver(div_value) 
{
    div_value.className = 'suggest_link_over';
}
//Mouse out function
function suggestOut(div_value) 
{    
    div_value.className = 'suggest_link';        
}

// Leave selectSubmitUrl as null or '' to not submit
function searchObject(inputFieldID, ajaxURL, doPostBack, selectSubmitUrl, enterSubmitUrl)
{            
    this.suggestOver                = suggestOver;
    this.suggestOut                 = suggestOut;    
    this.keyEvent                   = keyEvent;
    this.hideDiv                    = hideDiv;
    this.getXmlHttpRequestObject    = getXmlHttpRequestObject;
    this.getSelectedSpanNum         = getSelectedSpanNum;
    this.setSelectedSpan            = setSelectedSpan;
    this.setupResults               = setupResults;
    this.handleSearchSuggest        = handleSearchSuggest;    
    this.mainLoop                   = mainLoop;
    this.showSearch                 = showSearch;     
    this.buildSuggest               = buildSuggest;
        
    this.inputFieldID = inputFieldID;
    this.ajaxURL = ajaxURL;
    this.resultsIFrame = null;
    this.selectSubmitUrl = selectSubmitUrl;
    this.enterSubmitUrl = enterSubmitUrl;   
    this.lastKeyPressTime = new Date();
    this.lastSelSpanNum = -1;    
    this.itemSelected = false;
    this.doPostBack = doPostBack;    
    
    this.searchCache = new Array();
                                                                                        
    this.inputField = document.getElementById(inputFieldID);   
        
    // clear it out, only needs to be called once for first init
    this.inputField.onfocus = '';    
            
    if ( this.inputField != null )
    {
        var _this = this;            
        this.inputField.onblur = function () 
        { 
            // use _this scope for the call back
            _this.hideDiv();         
        }
                    
        this.inputField.onkeydown = function (evt) 
        {                 
           // use _this scope for the call back
           _this.keyEvent(evt);       
        }
                    
        this.searchReq = this.getXmlHttpRequestObject();     
                
        this.resultsDiv = null;
        this.setupResults();
        
        // start the pump
        this.mainLoop();                
    }     
}


//Gets the browser specific XmlHttpRequest Object
function getXmlHttpRequestObject() 
{
    if (window.XMLHttpRequest) 
    {
	    return new XMLHttpRequest();
    } 
    else if(window.ActiveXObject) 
    {
	    return new ActiveXObject("Microsoft.XMLHTTP");
    }
    else
    {
        return null;
    } 
}


/**
This is the function that monitors the queryField, and calls the lookup
functions when the queryField value changes.
*/

function mainLoop()
{            
    var searchWord = this.inputField.value;
    
    if ( searchWord == '' )
    {
      var val = document.getElementById(this.outputEntityIDField);
      if ( val )
      {
        val.value = '';      
      }
    }     
              
    // if the field value has changed and we're not currently waiting for
    // a lookup result to be returned, do a lookup (or use the cache, if
    // we can)     
    
    if ( searchWord.length > 0)
    { 
        if( (this.searchReq.readyState == 4 || this.searchReq.readyState == 0) && searchWord.length > 0 )
        {                    	  	                     
            if ( this.lastSearchWord != searchWord )
            {
                if ( this.searchCache[searchWord] != null )
                {
                    // call directly                              
                    this.lastSearchWord = searchWord;                
                    this.handleSearchSuggest(this.searchCache[searchWord]);
                }
                else
                {
                    // only do search if the have stopped typing for 1/2 a second.  No need
                    // to go out to the DB and grab for each character
                    var currDateTime = new Date();
                    if ( currDateTime - this.lastKeyPressTime > 500 ) 
                    {        
						//set the var so we can scope the callback
                        var _this = this;                
                                            
                        var url = this.ajaxURL + searchWord;               
                        this.searchReq.open("GET", url, true);        
                        this.searchReq.onreadystatechange = function() { _this.handleSearchSuggest(null); }
                                    
                        this.lastSearchWord = searchWord;   
                       
                        this.searchReq.send(null);                                              
                    }
                }      
            }  
        }	
    }
    else
    {            
        this.lastSearchWord = searchWord;                                   
        this.hideDiv();                
    }
  
    // pump on the instance mainLoop
    var func = "getObj('" + this.inputFieldID + "').mainLoop()";       
    setTimeout(func, 100);            
            
    return true;
}

/**
This is the key handler function, for when a user presses the up arrow,
down arrow, tab key, or enter key from the input field.
*/
function keyEvent(evt)
{          
  // if this key isn't one of the ones we care about, just return
  var KEYUP = 38;
  var KEYDOWN = 40;
  var KEYENTER = 13;
  var KEYTAB = 9;                    
    
  this.lastKeyPressTime = null;
  this.lastKeyPressTime = new Date();   
    
  // make sure we have a valid event variable
  // make sure we have a valid event variable
  if(!evt && window.event) {
    evt = window.event;
  }
  var key = evt.keyCode;    
      
  var div = document.getElementById(this.inputFieldID + 'resultsDiv');       
    
  // get the span that's currently selected, and perform an appropriate action
  var selNum = this.getSelectedSpanNum(div);        
    
  // must be hitting enter on the input and nothing selected in suggest  
  if (selNum == -1 && key == KEYENTER && this.inputField.value.length > 0)
  {    
    if ( this.doPostBack == true)     
    {        
        // use the ASP.NET postback        
        __doPostBack(this.inputFieldID, 'Selected');        
    }   
    else if ( this.enterSubmitUrl != null && this.enterSubmitUrl.length > 0 )
    {                
        evt.returnValue = false;   
        evt.cancelBubble=true;   
        window.location = this.enterSubmitUrl + this.inputField.value;                 
        return false;  
    }
  }
            
  if ((key != KEYUP) && (key != KEYDOWN) && (key != KEYENTER) && (key != KEYTAB))
    return true;
            
  if ((key == KEYENTER) || (key == KEYTAB)) 
  {    
    var selSpan = this.setSelectedSpan(div, selNum);  
    if (selSpan)
    {      
      selSpan.onmousedown();      
    }
       
    if ( key == KEYENTER )
    {
        evt.returnValue = false;  
        evt.cancelBubble=true;
    }
    return false;
  } 
  else 
  {
    if (key == KEYUP)
    {
      selSpan = this.setSelectedSpan(div, selNum - 1);
    }
    else if (key == KEYDOWN)
    {
      selSpan = this.setSelectedSpan(div, selNum + 1);            
    }        
  }
  
  // scroll div in to view  
  if ( selSpan )
    this.resultsDiv.scrollTop = selSpan.offsetTop - 10;
      
  return true;
}

function getSelectedSpanNum (div)
{  
  var spans = div.getElementsByTagName("div");
  if (spans) 
  {
    for (var i = 0; i < spans.length; i++) 
    {      
      if (spans[i].className == 'suggest_link_over')
      {        
        return i;
      }
    }
  }
  
  return -1;
}


/**
Select/highlight the result at the given position
*/

function setSelectedSpan (div, spanNum)
{  
  var thisSpan = null;
  var spans = div.getElementsByTagName("div");
  if (spans) 
  {
    for (var i = 0; i < spans.length; i++) 
    {
      if (i == spanNum) 
      {                
        suggestOver(spans[i])     
        thisSpan = spans[i];   
      } 
      else 
      {
        suggestOut(spans[i]);
      }
    }
  }
  
  return thisSpan;
}

function setupResults()
{

  if ( !this.resultsIFrame && g_isIE)
  {    
    var iFrameNode = document.createElement("iframe");
    var frameID = this.inputFieldID + 'ieFrame';
        
    iFrameNode.setAttribute("id", frameID);
    iFrameNode.className = "resultsIFrame";    
    iFrameNode.setAttribute("src", "javascript:false;");
    iFrameNode.setAttribute("frameborder", "0");
    iFrameNode.setAttribute("scrolling", "no");
    iFrameNode.style.height = 0;
    
    document.body.appendChild(iFrameNode);                   
    this.resultsIFrame = document.getElementById(frameID);        
  };   
  
  if (!this.resultsDiv) 
  {       
    // if the div doesn't exist on the page already, create it
    if (!document.getElementById(this.inputFieldID + 'resultsDiv')) 
    {
      var newNode = document.createElement("div");
      newNode.setAttribute("id", this.inputFieldID + 'resultsDiv');
      document.body.appendChild(newNode);
    }
    
    // set the resultsDiv reference
    this.resultsDiv = document.getElementById(this.inputFieldID + 'resultsDiv');        
    
    var _this = this;
    this.resultsDiv.onblur = function ()
    {
        this.lastSelSpanNum = -1;
        _this.hideDiv();
    }
    
    // figure out where the top corner of the div should be, based on the
    // bottom left corner of the input field
    var x = this.inputField.offsetLeft;    
    var y = this.inputField.offsetTop + this.inputField.offsetHeight;
    var parent = this.inputField;
    while (parent.offsetParent) 
    {
      parent = parent.offsetParent;
      x += parent.offsetLeft;
      y += parent.offsetTop;
    }        
    if (g_isIE)
    {
		x += 2;
		y += 4;
    }
                    
    this.resultsDiv.className = "resultsDiv";    
    this.resultsDiv.style.left = x + "px";
    this.resultsDiv.style.top = y + "px";          
    
    if ( g_isIE )
    {        
		this.resultsIFrame.style.left = this.resultsDiv.style.left;       
        this.resultsIFrame.style.top = this.resultsDiv.style.top;          
    }
  }
}

function buildSuggest(delimitedStr)
{
	var suggest = '';
    var strArray = delimitedStr.split("<br>");				
    var count = strArray.length - 1;    
    if ( count > 0 )
    {                                        		
        var recordsToShow = Math.min(10, count);
        this.resultsDiv.style.height = ((recordsToShow * 23)) + "px";      

        if ( g_isIE )
        {                                        
            // adjust for the border + 2 so the div border shows
            this.resultsIFrame.style.height = ((recordsToShow * 23) + 2) + "px";	  
            this.resultsIFrame.style.left = this.resultsDiv.style.left;                		                               
            this.resultsIFrame.style.top = this.resultsDiv.style.top;
        }
    	            	                                                    
        var _this = this;	        	        		    			
        for(i=0; i < count; i++) 
        {
				var name = strArray[i];		           		            
                suggest += "<div ";
                suggest += "onmousedown=doSelect('" + escape(this.inputFieldID) + "','" + escape(name) + "'); ";
                suggest += "class=suggest_link>";
                suggest += "<span style=\"float:left\">";
                suggest += name;
                suggest += "</span>";
                suggest += "</div><br/>"; 		                                
        }
    }
    return suggest;
}

//Called when the AJAX response is returned.
function handleSearchSuggest(optionalResults) 
{        
    try
    {                      
        if ( optionalResults != null )
        {
            // use the cache if we can
		    this.resultsDiv.innerHTML = this.buildSuggest(optionalResults);		    
		    this.showSearch(this.resultsDiv.innerHTML != '', false);	
        }
        else
        {
			// for some reason, this throws a JS error (calling this.searchReq.status).  have to put try catch
            if (this.searchReq.readyState == 4 && this.searchReq.status == "200") 
            {
				// remove any results that are already there with new ones                
				this.resultsDiv.innerHTML = this.buildSuggest(this.searchReq.responseText);
	            this.searchCache[this.lastSearchWord] = this.searchReq.responseText; 
	            this.showSearch(this.resultsDiv.innerHTML != '', false);	
            }
        }
    }
    catch (e)
    {
		alert(e);
        // do nothing        
    }                 
}

// For use by onblur to support all browsers
function hideDiv ()
{    
  this.showSearch(false, false);
  
  if ( this.resultsDiv )
    this.resultsDiv.scrollTop = 0;
}

function showSearch(show, force)
{             
    if ( this.resultsDiv )
    {
        if ( this.resultsDiv != document.activeElement || force )
        {        
            if ( show )
            {                   
				this.resultsDiv.style.visibility = 'visible';
                
                // this is to fix a strange bug in firefox/Mac
                this.resultsDiv.style.overflow = 'auto';                 
                
                if ( g_isIE )
                {
                    // we always have to reset these
                    this.resultsIFrame.style.visibility = 'visible'; 
                    this.resultsIFrame.style.left = this.resultsDiv.style.left;                		                               
                    this.resultsIFrame.style.top = this.resultsDiv.style.top;   
                }                                
            }
            else
            {                                          
                this.resultsDiv.style.visibility = 'hidden';
                
                // this is to fix a strange bug in firefox/Mac
                this.resultsDiv.style.overflow = 'hidden';
                                              
                if ( g_isIE )
                {           
                    this.resultsIFrame.style.visibility = 'hidden';    
                    this.resultsIFrame.style.left = "-1000px";
                }
            };                    
        }
    }
}

//Click function
function doSelect(inputID, name) 
{                               
    getObj(inputID).itemSelected = true;
    
    var input = document.getElementById(unescape(inputID));    
    input.value = unescape(name);                                
                    
    // set last search word to this so we don't drop down the results again
    getObj(inputID).lastSearchWord = unescape(name);        
    getObj(inputID).showSearch(false, true);            
    
    return true;        
}
