var _inputField=null;
var _documentForm=null;
var _submitButton=null;
var _parentElementId=null;
var _completeDiv=null;
var _oldInputFieldValue="";
var _currentInputFieldValue="";
var _eventKeycode=""; 
var _highlightedSuggestionIndex=-1;
var _highlightedSuggestionDiv=null;
var _completeDivRows=-1;
var _completeDivDivList=null;
var _completeDivRows2=5;
var _cursorUpDownPressed=false;
var _resultCache=new Object();
var _lastKeyCode=-1;
var da=false;
var G="";
var q="";
var B=null;

function suggest_main(frm,fld,sb,pid){

  _documentForm=frm;
  _inputField=fld;
  _submitButton=sb;
  _parentElementId=pid;

  _documentForm.onsubmit=Fa;
  _inputField.autocomplete="off";
  _inputField.onblur=onBlurHandler;
  if(_inputField.createTextRange) {
    _inputField.onkeyup=new Function("return okuh(event);")
  }else{
    _inputField.onkeyup=okuh
  }

  _inputField.onsubmit=Fa;
  _currentInputFieldValue=_inputField.value;
  _oldInputFieldValue=_currentInputFieldValue;
  _completeDiv=document.createElement("DIV");
  _completeDiv.id="completeDiv";
  _completeDiv.style.borderRight="black 1px solid";
  _completeDiv.style.borderLeft="black 1px solid";
  _completeDiv.style.borderTop="black 1px solid";
  _completeDiv.style.borderBottom="black 1px solid";
  _completeDiv.style.zIndex="1";
  _completeDiv.style.paddingRight="0";
  _completeDiv.style.paddingLeft="0";
  _completeDiv.style.paddingTop="0";
  _completeDiv.style.paddingBottom="0";

  setCompleteDivSize();
  _completeDiv.style.visibility="hidden";
  _completeDiv.style.position="absolute";
  _completeDiv.style.backgroundColor="white";

  var parentElement = document.getElementById(_parentElementId);
  parentElement.appendChild(_completeDiv);
    
  cacheResults("",new Array(),new Array());
  setStyleForElement(_completeDiv,"mAutoComplete");

  var s=document.createElement("DIV");
  s.style.visibility="hidden";
  s.style.position="absolute";
  s.style.left="-10000";
  s.style.top="-10000";
  s.style.width="0";
  s.style.height="0";
  var M=document.createElement("IFRAME");
  M.completeDiv=_completeDiv;
  M.name="completionFrame";
  M.id="completionFrame";
  M.src="about:blank";
  s.appendChild(M);
  parentElement.appendChild(s);
  if(frames&&(frames["completionFrame"]&&frames["completionFrame"].frameElement)) {
    B=frames["completionFrame"].frameElement
  }else{
    B=document.getElementById("completionFrame")
  }
  window.onresize=setCompleteDivSize;
  document.onkeydown=keyDownHandler;
  if(document.createEventObject) {
    var y=document.createEventObject();
    y.ctrlKey=true;
    y.keyCode=70;
    document.fireEvent("onkeydown",y)
  }

  return true
}

function keyDownHandler(event){
  if(!event&&window.event) {
    event=window.event
  }
  if(event) {
    _lastKeyCode=event.keyCode
  }
  // We are backspacing here...
  if(event&&event.keyCode==8){
    if((_inputField.createTextRange&&(event.srcElement==_inputField&&(bb(_inputField)==0&&lb(_inputField)==0)))){
      cc(_inputField);
      event.cancelBubble=true;
      event.returnValue=false;
      return false
    }
  }
}

function setCompleteDivSize(){
  if(_completeDiv){
    _completeDiv.style.left=calculateOffsetLeft(_inputField)+"px";
    _completeDiv.style.top=calculateOffsetTop(_inputField)+_inputField.offsetHeight-1+"px";
    _completeDiv.style.width=_inputField.offsetWidth+"px"
  }
}

function onBlurHandler(event){
  if(!event&&window.event) {
    event=window.event
  }
  if(!_cursorUpDownPressed){
    hideCompleteDiv();
    // check if tab pressed...
    if(_lastKeyCode==9){
      _submitButton.focus();
      _lastKeyCode=-1
    }
  }
  _cursorUpDownPressed=false
}

okuh=function(e){
  _eventKeycode=e.keyCode;
  // 38 is up cursor key, 40 is down cursor key...
  if(_eventKeycode==40||_eventKeycode==38) {
    _cursorUpDownPressed=true;
    _inputField.blur();
    setTimeout("_inputField.focus();",10)
  }
  var N=lb(_inputField);
  var v=bb(_inputField);
  var V=_inputField.value;
  if(_eventKeycode!=0){
    if(N>0&&v!=-1) {
      V=V.substring(0,v)
    }
    if(_eventKeycode==13||_eventKeycode==3){
      var d=_inputField;
      if(d.createTextRange){
        var t=d.createTextRange();
        t.moveStart("character",d.value.length);
        t.select()
      }else if(d.setSelectionRange){
        d.setSelectionRange(d.value.length,d.value.length)
      }
    }else{
      if(_inputField.value!=V) {
        _inputField.value=V
      }
    }
  }
  _currentInputFieldValue=V;
  if(handleCursorUpDownEnter(_eventKeycode)&&_eventKeycode!=0) {
    Pa(_completeDiv,valueOfCAutoComplete)
  }
};

// strip CR from string...
function stripCRFromString(va){
  for(var f=0,oa="",zb="\n\r"; f<va.length; f++) {
    if (zb.indexOf(va.charAt(f))==-1) {
      oa+=va.charAt(f)
    }else{
      oa+=" "
    }
  }
  return oa
}

// Find span value with className
function findSpanValueForClass(i,dc){
  var ga=i.getElementsByTagName("span");
  if(ga){
    for(var f=0; f<ga.length; ++f){
      if(ga[f].className==dc){
        var value=ga[f].innerHTML;
        if(value=="&nbsp;") {
          return""
        }else{
          var z=stripCRFromString(value);
          return z
        }
      }
    }
  }else{
    return""
  }
}

function valueOfCAutoComplete(i){
  if(!i) {
    return null
  }
  return findSpanValueForClass(i,"cAutoComplete")
}

function valueOfDAutoComplete(i){
  if(!i) {
    return null
  }
  return findSpanValueForClass(i,"dAutoComplete")
}

function hideCompleteDiv(){
  document.getElementById("completeDiv").style.visibility="hidden"
}

function showCompleteDiv(){
  document.getElementById("completeDiv").style.visibility="visible";
  setCompleteDivSize()
}

// This is a result caching mechanism...
function cacheResults(is,cs,ds){
  _resultCache[is]=new Array(cs,ds)
}

sendRPCDone=function(fr,is,cs,ds){
  if(!fr) {
    fr=B
  }
  cacheResults(is,cs,ds);
  var b=fr.completeDiv;
  b.completeStrings=cs;
  b.displayStrings=ds;

  while(b.childNodes.length>0) {
    b.removeChild(b.childNodes[0])
  }
  // For each element in our list, we create:
  // <DIV (u) - mousedown/mouseover/mouseout aAutoComplete>
  //   <SPAN (ka) lAutoComplete>
  //     <SPAN (ua) cAutoComplete>
  //        bug tracking
  //     </SPAN (ua)>
  //     <SPAN (ea) dAutoComplete>
  //        500,000 results
  //     </SPAN (ea)>
  //   </SPAN>
  // </DIV (u)>
  for(var f=0; f<b.completeStrings.length; ++f){
    var u=document.createElement("DIV");
    setStyleForElement(u,"aAutoComplete");
    u.onmousedown=Cb;
    u.onmouseover=pb;
    u.onmouseout=ec;
    var ka=document.createElement("SPAN");
    setStyleForElement(ka,"lAutoComplete");
    var ua=document.createElement("SPAN");
    ua.innerHTML=b.completeStrings[f];
    var ea=document.createElement("SPAN");
    setStyleForElement(ea,"dAutoComplete");
    setStyleForElement(ua,"cAutoComplete");
    u.displaySpan=ea;
    ea.innerHTML=b.displayStrings[f];
    ka.appendChild(ua);
    ka.appendChild(ea);
    u.appendChild(ka);
    b.appendChild(u)
  }

  Pa(b,valueOfCAutoComplete);
  if(_completeDivRows2>0) {
    b.height=16*_completeDivRows2+4
  }else{
    hideCompleteDiv()
  }
}

function Fa(){
  da=true;
  hideCompleteDiv();
  _documentForm.submit();
  return true
}

// This function sets itself up and gets called over and over (timeout driven)
mainLoop=function(){
  if(_oldInputFieldValue!=_currentInputFieldValue){
    if(!da){
      var ma=_resultCache[_currentInputFieldValue];
      if(ma){
        // Found in our cache...
        sendRPCDone(B,_currentInputFieldValue,ma[0],ma[1])
      }else{
        _currentInputFieldValue = _currentInputFieldValue.replace("\\","\\\\");
        Re = new RegExp("^"+_currentInputFieldValue);
        var good_words = new Array();
        var good_amount = new Array();
        var j=0;
        for(var i=0; i<words.length; i++){
          if(Re.test(words[i][0])) {
            good_words[j] = words[i][0];
            good_amount[j] = words[i][1];
            j++
          }
        }
        sendRPCDone(frameElement, _currentInputFieldValue, good_words, good_amount)
      }
      _inputField.focus()
    }
    da=false
  }
  _oldInputFieldValue=_currentInputFieldValue;
  setTimeout("mainLoop()", 150);
  return true
};

// Call mainLoop() after 10 milliseconds...
setTimeout("mainLoop()",10);

// This is onMouseDown function...
var Cb=function(){
  _inputField.value=valueOfCAutoComplete(this);
  q=valueOfDAutoComplete(this);
  da=true;
  Fa()
};

// on mouseover...
var pb=function(){
  if(_highlightedSuggestionDiv) {
    setStyleForElement(_highlightedSuggestionDiv,"aAutoComplete")
  }
  setStyleForElement(this,"bAutoComplete")
};

// On Mouse out...
var ec=function(){
  setStyleForElement(this,"aAutoComplete")
};

// Called when cursor up/down pressed. selects new entry in completeDiv
function highlightNewValue(C){
  _currentInputFieldValue=G;
  _inputField.value=G;
  q=G;
  if(!_completeDivDivList||_completeDivRows<=0) {
    return
  }
  showCompleteDiv();
  if(C>=_completeDivRows){
    C=_completeDivRows-1
  }
  if(_highlightedSuggestionIndex!=-1&&C!=_highlightedSuggestionIndex){
    setStyleForElement(_highlightedSuggestionDiv,"aAutoComplete");
    _highlightedSuggestionIndex=-1
  }
  if(C<0){
    _highlightedSuggestionIndex=-1;
    _inputField.focus();
    return
  }
  _highlightedSuggestionIndex=C;
  _highlightedSuggestionDiv=_completeDivDivList.item(C);
  setStyleForElement(_highlightedSuggestionDiv,"bAutoComplete");
  _currentInputFieldValue=G;
  q=valueOfDAutoComplete(_highlightedSuggestionDiv);
  _inputField.value=valueOfCAutoComplete(_highlightedSuggestionDiv)
}

// returns false if cursor up / cursor down or enter pressed...
function handleCursorUpDownEnter(eventCode){
  if(eventCode==40){
    highlightNewValue(_highlightedSuggestionIndex+1);
    return false
  }else if(eventCode==38){
    highlightNewValue(_highlightedSuggestionIndex-1);
    return false
  }else if(eventCode==13||eventCode==3){
    return false
  }
  return true
}

// This function gets called for every keypress I make...
function Pa(localCompleteDiv,ib){
  var localInputField=_inputField;
  _highlightedSuggestionIndex=-1;
  // This becomes the rows in our suggestion list...
  var J=localCompleteDiv.getElementsByTagName("div");
  // # of rows in list...
  var O=J.length;
  _completeDivRows=O;
  _completeDivDivList=J;
  _completeDivRows2=O;
  G=_currentInputFieldValue;
  if(_currentInputFieldValue==""||O==0){
    hideCompleteDiv()
  }else{
    showCompleteDiv()
  }
  for(var f=0; f<O; f++) {
    setStyleForElement(J.item(f),"aAutoComplete")
  }

  q=_currentInputFieldValue;
  _highlightedSuggestionIndex=-1;
  _highlightedSuggestionDiv=null

  var ab=false;
  switch(_eventKeycode){
    // cursor left, cursor right, others??
    case 8:
    case 33:
    case 34:
    case 35:
    case 35:
    case 36:
    case 37:
    case 39:
    case 45:
    case 46:
      ab=true;
      break;
    default:
      // regular keypress ...
      break
  }
  if(!ab&&_highlightedSuggestionDiv){
    var Da=_currentInputFieldValue;
    setStyleForElement(_highlightedSuggestionDiv,"bAutoComplete");
    var z;
    z=Da;
    if(z!=localInputField.value){
      if(localInputField.value!=_currentInputFieldValue) {
        return
      }
      if(localInputField.createTextRange||localInputField.setSelectionRange) {
        _inputField.value=z
      }
      if(localInputField.createTextRange){
        var t=localInputField.createTextRange();
        t.moveStart("character",Da.length);
        t.select()
      }else if(localInputField.setSelectionRange){
        localInputField.setSelectionRange(Da.length,localInputField.value.length)
      }
    }
  }else{
    _highlightedSuggestionIndex=-1;
    q=_currentInputFieldValue
  }
}

function calculateOffsetLeft(r){
  return Ya(r,"offsetLeft")
}

function calculateOffsetTop(r){
  return Ya(r,"offsetTop")
}

function Ya(r,attr){
  var kb=0;
  while(r){
    kb+=r[attr];
    r=r.offsetParent
  }
  return kb
}

function lb(n){
  var N=-1;
  if(n.createTextRange){
    var fa=document.selection.createRange().duplicate();
    N=fa.text.length
  }else if(n.setSelectionRange){
    N=n.selectionEnd-n.selectionStart
  }
  return N
}

function bb(n){
  var v=0;
  if(n.createTextRange){
    var fa=document.selection.createRange().duplicate();
    fa.moveEnd("textedit",1);
    v=n.value.length-fa.text.length
  }else if(n.setSelectionRange){
    v=n.selectionStart
  }else{
    v=-1
  }
  return v
}

function cc(d){
  if(d.createTextRange){
    var t=d.createTextRange();
    t.moveStart("character",d.value.length);
    t.select()
  }else if(d.setSelectionRange) {
    d.setSelectionRange(d.value.length,d.value.length)
  }
}

function setStyleForElement(c,name){
  c.className=name;
  switch(name.charAt(0)){
    case "m":
      c.style.fontSize="13px";
      c.style.fontFamily="arial,sans-serif";
      c.style.wordWrap="break-word";
      break;
    case "l":
      c.style.display="block";
      c.style.paddingLeft="3";
      c.style.paddingRight="3";
      c.style.height="16px";
      c.style.overflow="hidden";
      break;
    case "a":
      c.style.backgroundColor="white";
      c.style.color="black";
      if(c.displaySpan){
        c.displaySpan.style.color="green"
      }
      break;
    case "b":
      c.style.backgroundColor="#3366cc";
      c.style.color="white";
      if(c.displaySpan){
        c.displaySpan.style.color="white"
      }
      break;
    case "c":
      c.style.width="65%";
      c.style.cssFloat="left";
      break;
    case "d":
      c.style.cssFloat="right";
      c.style.width="35%";
      c.style.fontSize="10px";
      c.style.textAlign="right";
      c.style.color="green";
      c.style.paddingTop="3px"
      break
  }
}

