function BowStIncrementalSearch()
{
    this.currentID = 1;
    this.xmlHttp = null;
    this.pendingTimerID = null;
    this.keystrokeDelay = 500; // milliseconds
    this.maxViewResults = 10;
}

if (!BowStIncrementalSearch.instance)
{
// Don't re-define all this stuff if we've been pulled in before.


BowStIncrementalSearch.prototype.getChoices = function(el, url)
{
    if (!document.getElementById || !el.value)
    {
        return;
    }   
    if (!el.id)
    {
        el.id = "_bst_el" + this.currentID++;
    }
    
    if (this.pendingTimerID)
    {
        window.clearTimeout(this.pendingTimerID);
        this.pendingTimerID = null;
    }
        
    this.pendingID = el.id;
    this.pendingValue = el.value;
    this.pendingURL = url;
  
    this.pendingTimerID = window.setTimeout("BowStIncrementalSearch.instance.doServiceCall()", this.keystrokeDelay);
}

BowStIncrementalSearch.prototype.doServiceCall = function()
{
    this.callService(this.pendingID, this.pendingValue, this.pendingURL);
}

BowStIncrementalSearch.prototype.makeChoice = function(sel, txtid)
{
    var txt = document.getElementById(txtid);
    var selTxt = sel.options ? sel.options[sel.selectedIndex].text : sel.value;
    txt.value = selTxt;
    var selid = "_bst_incremental_selector";
    var c = document.getElementById(selid);
    c.innerHTML = "";
    
    if (txt.postSelectAction || postSelectAction) {
    	var theAction = (txt.postSelectAction) ? txt.postSelectAction : postSelectAction; 
    	//post form and execute action
    	//alert("Before:\n" + theAction + "\nthe field value after selection\n" + txt.value);
    	
    	var theActiveForm = txt.form;
    	theActiveForm.action = theAction;
    	theActiveForm.target = "_self";
    	if (!theActiveForm.onsubmit || theActiveForm.onsubmit())
    		theActiveForm.submit();
    	    	
    	//alert("After");
    }
}

BowStIncrementalSearch.prototype.calculateOffsetLeft = function(el)
{
  return this.getOffset(el, "offsetLeft")
}

BowStIncrementalSearch.prototype.calculateOffsetTop = function(el)
{
  return this.getOffset(el, "offsetTop") + 24;
}

BowStIncrementalSearch.prototype.getOffset = function(el, attr)
{
  var off = 0;
  while (el)
  {
    off += el[attr]; 
    el = el.offsetParent;
  }
  return off;
}
// Attempt to get an object capable of calling back to the server.
BowStIncrementalSearch.prototype.getXMLHTTP = function()
{
    var xh = null;
    try {
        xh = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (noMsxml2) {
      try {
        xh = new ActiveXObject("Microsoft.XMLHTTP");
      } catch(noActiveXObject) {
        xh = null;
      }
    }
    if (!xh && typeof XMLHttpRequest != "undefined") {
        xh = new XMLHttpRequest();
    }
    return xh;
}
// Call the service to get a list of results.
BowStIncrementalSearch.prototype.callService = function(id, pat, url)
{
    // If there is a pending request, cancel it.
    if (this.xmlHttp && this.xmlHttp.readyState!=0)
    {
        this.xmlHttp.abort();
    }
    if (pat == null) pat = "";
    this.xmlHttp=this.getXMLHTTP();
    if (this.xmlHttp)
    {
        var iq = url.indexOf("?");
        var us = iq < 0 ? "?" : "&";
        this.xmlHttp.open("POST", url, true);
        this.xmlHttp.onreadystatechange = function()
        {
          var xmlHttp = BowStIncrementalSearch.instance.xmlHttp;
      
          if (xmlHttp.readyState == 4 && xmlHttp.responseText)
          {       
              var prog = "BowStIncrementalSearch.instance.handleServiceResult(" + xmlHttp.responseText + ")";                      
              eval(prog);
          }
        }

        this.xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");         
        this.xmlHttp.send("pat=" + encodeURIComponent(pat) + "&id=" + encodeURIComponent(id));
    }
}
// Called when service results are available.
BowStIncrementalSearch.prototype.handleServiceResult = function(id, results)
{
    var selid = "_bst_incremental_selector";
    var el = document.getElementById(id);
    var c = document.getElementById(selid);
    
    if (!c)
    {
        c = document.createElement("DIV");
        c.id = selid;
        c.style.position = "absolute";
        document.body.appendChild(c);
    }
    
    c.style.left = this.calculateOffsetLeft(el) + "px";
    c.style.top = this.calculateOffsetTop(el) + "px";
    var z = this.getMaxZ(el, 1);
    c.style.zIndex = z + 1;
    
    var h = "";
       
    if (results && results.length > 0)
    {
        // There are results: build a select to display them.
        var selSize = results.length;
        if (selSize > this.maxViewResults)
            selSize = this.maxViewResults;
        var onclickHandler = "onclick='BowStIncrementalSearch.instance.makeChoice(this, \"" + id + "\")'";      
        if (selSize > 1)
        {
            h = "<select size='" + selSize + "' " + onclickHandler + " >";
            for (var i = 0; i < results.length; i++)
            {
                h += "<option>" + results[i] + "</option>";
            }
            h += "</select>";
        }
        else
        {
            h = "<input type='text' readonly='true' value='" + results[0] + "' " + onclickHandler + " >";
        }
    }
     
    c.innerHTML = h;    
}
BowStIncrementalSearch.prototype.getMaxZ = function(el, maxSoFar) {
   while (el) {
       if (el.style) {
           var z = el.style.zIndex;
           if (z > maxSoFar) maxSoFar = z;
       }
       el = el.parentNode;
   }
   return maxSoFar;
}
BowStIncrementalSearch.instance = new BowStIncrementalSearch();
}  
    

