
var tPickList = new Array(50);
var nbPickList = 0;
var curDoc;
var szcurDoc = "";
var curWindow;
var curformname = "";
var UNDEFINED;  // do not assign!

function GetElementForm(szName)
{
var k;
for(k=0;k<curDoc.forms[curformname].elements.length;k++)
{

if(curDoc.forms[curformname].elements[k].name == szName)
return(curDoc.forms[curformname].elements[k]);
}
return(null);
}

function addPickList(szName)
{
tPickList[nbPickList] = szName;
nbPickList = nbPickList +1;
}
function setupAllPickList(szFrameName,szFormName)
{
if(szFrameName!="") 
{
curDoc = frames[szFrameName].document;
szcurDoc = "frames['" + szFrameName +"'].document";
curWindow = frames[szFrameName].window;
}
else
{
curDoc = document;
szcurDoc = "document";
curWindow = window;
}
curformname = szFormName;


for(k=0;k<nbPickList;k++)
{

setupPicklist(GetElementForm(tPickList[k]));

}
resetPickList();
}
function resetPickList()
{
nbPickList = 0;
}
function getX(obj)
{
   return( obj.offsetParent==null ? obj.offsetLeft : obj.offsetLeft+getX(obj.offsetParent) );
}

function getY(obj)
{
   return( obj.offsetParent==null ? obj.offsetTop : obj.offsetTop+getY(obj.offsetParent) );
}

function isvalidchar(achar,validstr)
{
   if ( !validstr ) validstr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 `~!@#$%^&*()_-+={}[]|:;'<>,./?\\\"";
   return( validstr.toUpperCase().indexOf(achar.toString().toUpperCase(),0) >= 0 );
}

function getQualifiedName(formElement)
{
   var formName = formElement.form.name;
   if ( formName=="" ) formName=0;  // best guess since it is indeterminate for netscape
   return szcurDoc + '.forms["' + formName + '"].elements["' + formElement.name + '"]';
}


function getTooltipDiv()
{
   if ( curDoc.getElementById )
      return curDoc.getElementById('divPicklistTooltip');
   else if ( curDoc.all )
      return curDoc.all.divPicklistTooltip;
   else return null;
}


function createTooltipDiv(objSel)
{
   if ( !getTooltipDiv() )  // if this is the first time this function is
   {                        // called then create the tooltip text window.
      var tooltipDiv = "<DIV id='divPicklistTooltip' style='position:absolute;top:0px;left:0px;visibility:hidden'></div>";

      if ( curDoc.body.insertAdjacentHTML )
      {
         curDoc.body.insertAdjacentHTML("beforeEnd",tooltipDiv);
      }
      else if ( curDoc.body.innerHTML )
      {
         curDoc.body.innerHTML += tooltipDiv;
      }

      // necessary for netscape (don`t know why)
      setTimeout( "setupPicklist(" + getQualifiedName(objSel) + ")", 1 );

      return true;
   }

   return false;
}


function showTooltipText(objSel)
{
   if ( !objSel || objSel.Y==UNDEFINED )  // null or not setup
   {
      return false;
   }

   var divPicklistTooltip = getTooltipDiv();
   var s = divPicklistTooltip.innerHTML = "";

   with ( objSel )
   {
      if ( strKeyInBuf=="" && title.length )
      {
         s = '<FONT color="blue">' + title + '</font>';
      }
      else if ( selectedIndex>=0 && strKeyInBuf==options[selectedIndex].text )  // unique match found
      {
         s = '<B>' + strKeyInBuf + '</b>';
      }
      else
      {
         var c = strKeyInBuf.substring(strKeyInBuf.length-1,strKeyInBuf.length);
         c = ( c == ' ' ) ? '&nbsp;' : '<B>' + c + '</b>';
         s = strKeyInBuf.substring(0,strKeyInBuf.length-1) + c;
      }

      divPicklistTooltip.innerHTML = '<TABLE cellpadding=0 cellspacing=0 style="background-color:INFOBACKGROUND;'
        + 'font:8pt ms sans serif;padding:2px 2px 2px 2px;color:INFOTEXT;border:1px solid INFOTEXT;">'
        + '<TR><TD align="left"><NOBR>'+s+'</nobr></td></tr></table>';

      divPicklistTooltip.style.posLeft = divPicklistTooltip.style.left = X;
      divPicklistTooltip.style.posTop  = divPicklistTooltip.style.top  = Y;
      divPicklistTooltip.style.visibility = "";

   } // end with

   return true;
}


function hideTooltipText(objSel)
{
   if (objSel) objSel.strKeyInBuf = "";
   var divPicklistTooltip = getTooltipDiv();
   return divPicklistTooltip.innerHTML = "";
}


function findSelectEntry( objSel, head, tail )  // uses divide-and-conquer search, assumes sorted list
{
   with ( objSel )
   {
      if ( options.length <= 0 )
      {
         strKeyInBuf = ' <FONT color="red">No selections available.</font> ';
         showTooltipText(objSel);
         top.status = strKeyInBuf = "";
         return -1;
      }

      if ( strKeyInBuf == "" )
      {
         showTooltipText(objSel);
         return( selectedIndex = options[selectedIndex=0].text.length ? -1 : 0 );
      }

      if (head==UNDEFINED) head = 0;
      if (tail==UNDEFINED) tail = options.length-1;

      var mid = Math.round( (head+tail)/2 );

      if ( strKeyInBuf.toUpperCase() == options[mid].text.substring(0,strKeyInBuf.length).toUpperCase() )
      {
         while ( (mid>0)  &&  strKeyInBuf.toUpperCase() == options[mid-1].text.substring(0,strKeyInBuf.length).toUpperCase() )
         {
            mid--;  // get the topmost matching item in the list, not just the first found
         }

         selectedIndex = mid;

         top.status = strKeyInBuf = options[mid].text.substring(0,strKeyInBuf.length);

         if ( mid == Math.round( (head+tail)/2 ) )  // if the original mid is an exact match
         {
            if ( (mid==tail) || ( (mid<tail) && strKeyInBuf.toUpperCase() != options[mid+1].text.substring(0,strKeyInBuf.length).toUpperCase() ) )
            {
               top.status = strKeyInBuf = options[mid].text;  // unique match found
            }
         }

         showTooltipText(objSel);

         return selectedIndex;
      }

      if ( head >= tail )  // then since no exact match was found, go back to previous strKeyInBuf (thus the length-1)
      {
         strKeyInBuf = strKeyInBuf.substring(0,strKeyInBuf.length-1)
         return findSelectEntry( objSel );
      }

      if ( strKeyInBuf.toUpperCase() < options[mid].text.substring(0,strKeyInBuf.length).toUpperCase() )
      {
         return findSelectEntry( objSel, head, Math.max(head,mid-1) );
      }

      return findSelectEntry( objSel, Math.min(mid+1,tail), tail );
   }  // end with
}


function picklistFocusHandler(e)
{
    var event = e ? e : curWindow.event;  // to handle both NS and IE events
   var objSel = event.target ? event.target : event.srcElement;
   picklistFocusHandler.objSel = objSel;

   // update data elements
   objSel.X = getX(objSel)+2;
   objSel.Y = getY(objSel)-20;
   objSel.strKeyInBuf = "";

   // display the tooltip help (the title attribute by default)
   showTooltipText(objSel);
}


function picklistBlurHandler(e)
{
    var event = e ? e : curWindow.event;  // to handle both NS and IE events
   var objSel = event.target ? event.target : event.srcElement;
   picklistFocusHandler.objSel = null;

   top.status = (objSel.selectedIndex>-1) ? objSel.options[objSel.selectedIndex].text : "";
   hideTooltipText(objSel);

   return true;
}


function picklistMouseOverHandler(e)
{

   var event = e ? e : curWindow.event;  // to handle both NS and IE events
	 
   var objSel = event.target ? event.target : event.srcElement;

   showTooltipText(objSel);

   return true;
}


function picklistMouseOutHandler(e)
{
   var event = e ? e : curWindow.event;  // to handle both NS and IE events
   var objSel = event.target ? event.target : event.srcElement;

   if ( objSel==picklistFocusHandler.objSel || objSel==curDoc.activeElement )
      return true;

   hideTooltipText();

   return true;
}


function picklistKeyDownHandler(e)
{
    var event = e ? e : curWindow.event;  // to handle both NS and IE events
   var objSel = event.target ? event.target : event.srcElement;
   var divPicklistTooltip = getTooltipDiv();

   with ( objSel )
   {
      // this is to correct the search bug when the list is left open after single-click
      if ( strKeyInBuf=="" && event.keyCode>40 )
      {
         objSel.blur();
         objSel.focus();
      }

      switch(event.keyCode)
      {
        case(8):  // backspace
        {
           if ( selectedIndex>=0 && strKeyInBuf==options[selectedIndex].text )
           {
              top.status = strKeyInBuf = "";
           }
           else
           {
              top.status = strKeyInBuf = strKeyInBuf.substring(0,strKeyInBuf.length-1);
           }

           selectedIndex = findSelectEntry(objSel);

           event.keyCode = 0;
           return false;
        }

        case(9):   // tab
        case(13):  // enter
        {
           event.keyCode = 9;  // convert enter to tab
           return true;
        }

        case(27):  // escape
        {
           top.status = strKeyInBuf = "";
           selectedIndex = options[selectedIndex=0].text.length ? -1 : 0;
           showTooltipText(objSel);

           event.keyCode = 0;
           return false;
        }

        case(32):  // space
        {
           top.status = strKeyInBuf += ' ';
           // this must be fired explicitely for spaces
           return !picklistKeyPressHandler(event);
        }

        // I don't know if these are universal
        case(33):  // page up
        case(34):  // page down
        case(35):  // end
        case(36):  // home
        case(37):  // left arrow
        case(38):  // up arrow
        case(39):  // right arrow
        case(40):  // down arrow
        {
           top.status = hideTooltipText(objSel);
           return true;
        }

      }  // end switch
   }  // end with

   return true;
}


function picklistKeyPressHandler(e)
{
    var event = e ? e : curWindow.event;  // to handle both NS and IE events
   var objSel = event.target ? event.target : event.srcElement;
   var inputChar = String.fromCharCode(event.keyCode ? event.keyCode : event.charCode);

   if ( inputChar=='\n' || inputChar=='\r' )
   {
      top.status = objSel.strKeyInBuf = ( objSel.selectedIndex>-1 ? objSel.options[objSel.selectedIndex].text : "" );
   }

   if ( isvalidchar(inputChar) && event.charCode!=0 )
   {
      objSel.strKeyInBuf += inputChar;

      // must use setTimeout to override the default SELECT keypress event(s)
      setTimeout( "findSelectEntry(" + getQualifiedName(objSel) + ")", 1 );
   }

   return true;
}


function setupPicklist(objSel)
{

   if ( !curDoc.all && !curDoc.getElementById )
      return false;  // browser not supported

   if ( !objSel || (""+objSel.type).substring(0,6).toLowerCase()!="select" )
      return false;  // null or not a select

   createTooltipDiv(objSel);

   // create/init data elements
   objSel.X = getX(objSel)+2;
   objSel.Y = getY(objSel)-20;
   objSel.strKeyInBuf = "";

   // setup event handlers
   objSel.onclick     = function(){top.status=hideTooltipText(this);}
   objSel.onfocus     = picklistFocusHandler;
   objSel.onblur      = picklistBlurHandler;
   objSel.onmouseover = picklistMouseOverHandler;
   objSel.onmouseout  = picklistMouseOutHandler;
   objSel.onkeydown   = picklistKeyDownHandler;
   objSel.onkeypress  = picklistKeyPressHandler;
   objSel.onkeyup     = null;

   return true;
}


/////////////////////////////////// -- End Picklist.js -- ////////////////////////////////////////