function AutoSuggest(elem, suggestions, location_id)
{
  var hideDivFlag = "1";
  var me = this;
  
  this.elem = elem;
  this.suggestions = suggestions;
  this.eligible = new Array();
  this.inputText = null;
  this.highlighted = -1;
  this.div = document.getElementById("autosuggest");
  
  var div_flag;
  var ua = navigator.userAgent;
  if (ua.indexOf("MSIE 5.5")>=0||ua.indexOf("MSIE 6")>=0) {
    var SEMICOLON = 186;
  } else {
    var SEMICOLON = 59;
  }
  if (ua.indexOf("MSIE 5.5")>=0||ua.indexOf("MSIE 6")>=0) {
    var COMMA = 27;
  } else {
    var COMMA = 188;
  }
  
  var TAB = 9;
  var ESC = 27;
  var KEYUP = 38;
  var KEYDN = 40;
  var ENTER = 13;
  var SPACE = 32;
  var BACKSPACE = 8;
  var tempVal = "";
  var lastKey = "";
  elem.setAttribute("autocomplete","off");
  if(!elem.id) {
    var id = "autosuggest" + idCounter;idCounter++;elem.id = id;
  }
  
  elem.onkeydown = function(ev)
  {
    var key = me.getKeyCode(ev);
    switch(key) {
      
      case TAB:
        me.useSuggestion();
	me.hideDiv();
	break;
      
      case ESC:
        me.hideDiv();
	break;
      
      case KEYUP:
        if (me.highlighted > 0) {
	  me.highlighted--;
	}
	me.changeHighlight(key);
	me.useSuggestion();
	break;
	
      case KEYDN:
        if (me.highlighted < (me.eligible.length - 1)) { 
	  me.highlighted++;
	}
	me.changeHighlight(key);
	me.useSuggestion();
	break;
	
      case ENTER:
        me.useSuggestion();
	me.hideDiv();
	document.getElementById(location_id).focus();
	if (div_flag) {
	  div_flag=0;return false;
	}
	break;
	
      case COMMA:
        me.useSuggestion();
	me.hideDiv();
	break;
    }
  };
  elem.onkeyup = function(ev) {
    var key = me.getKeyCode(ev);
    switch(key){
      
      case TAB:
      case ESC:
      case KEYUP:
      case KEYDN:
      case ENTER:
        return;
      
      case COMMA:
         break;
     
      case SEMICOLON:
         alert("Use Comma (,) to separate multiple locations");
	 document.getElementById(location_id).focus();
	 tempVal = this.value;
	 this.value = tempVal.substring(0, tempVal.length-1);
	 return false;

      case SPACE:
         if (lastKey == COMMA) {
	   document.getElementById(location_id).focus();
	   tempVal = this.value;
	   this.value = tempVal.substring(0, tempVal.length-1);
	 }
  
      default:
        tempVal = this.value;
	if (tempVal.lastIndexOf(',') > -1) {
	  tempVal = tempVal.substring(tempVal.lastIndexOf(',')+1,tempVal.length);
	  me.inputText = tempVal;
	  me.getEligible();
	  me.createDiv();
	  me.positionDiv();
	  me.showDiv();
	  if(hideDivFlag=="1")  {
	    me.hideDiv();
	    return;
	  }
        } else  {
	  if (this.value != me.inputText && this.value.length > 0) {
	    me.inputText = this.value;
	    me.getEligible();
	    me.createDiv();
	    me.positionDiv();
	    me.showDiv();
	    if(hideDivFlag=="1") {
	      me.hideDiv();
	      return;
	    }
	  } else {
	    me.hideDiv();
	    }
	  }
    }
    if (key == COMMA || (lastKey == COMMA && key == SPACE)  || ((lastKey == COMMA) && (key == BACKSPACE))) {
      lastKey = COMMA;
    } else {
    lastKey = 0;
    }
  };
  
  this.useSuggestion = function() {
    if (this.highlighted > -1) {
      this.elem.value = this.elem.value.substring(0,this.elem.value.lastIndexOf(',')+1) + this.eligible[this.highlighted];
      setTimeout("document.getElementById('" + this.elem.id + "').focus()",100);
    }
  };
  
  this.showDiv = function() {
    this.div.style.display = 'block';
    div_flag = 1;
  };
  
  this.hideDiv = function() {
    this.div.style.display ='none';
    this.highlighted = -1;
  };
  
  this.changeHighlight = function() {
    var lis = this.div.getElementsByTagName('LI');
    for (i in lis) {
      var li = lis[i];
      if (this.highlighted == i) {
        li.className = "selected";
      }else {
        li.className = "";
      }
    }
  };
  
  this.positionDiv = function() {
    var el = this.elem;
    var x = 0;
    var y = el.offsetHeight;
    while (el.offsetParent && el.tagName.toUpperCase() != 'BODY') {
      x += el.offsetLeft;
      y += el.offsetTop;
      el = el.offsetParent;
    }
    x += el.offsetLeft;
    y += el.offsetTop;
    this.div.style.left = x + 'px';
    this.div.style.top = y + 'px';
  };
  
  this.createDiv = function() {
    var ul = document.createElement('ul');hideDivFlag = "1";
    for (i in this.eligible) {
      var word = this.eligible[i];
      var li = document.createElement('li');
      var a = document.createElement('a');
      a.href="javascript:false";
      a.innerHTML = word;
      li.appendChild(a);
      if (me.highlighted == i) {
        li.className = "selected";
      }
      ul.appendChild(li);
      hideDivFlag="0";
    }
    this.div.replaceChild(ul,this.div.childNodes[0]);
    ul.onmouseover = function(ev) {
      var target = me.getEventSource(ev);
      while (target.parentNode && target.tagName.toUpperCase() != 'LI') {
        target = target.parentNode;
      }
      var lis = me.div.getElementsByTagName('LI');
      for (i in lis) {
        var li = lis[i];
	if(li == target) {
	  me.highlighted = i;
	  break;
	}
      }
      me.changeHighlight();
      me.useSuggestion();
    };

    ul.onclick = function(ev) {
      me.useSuggestion();
      me.hideDiv();
      me.cancelEvent(ev);
      return false;
    };
    
    this.div.className="suggestion_list";
    this.div.style.position = 'absolute';
  };
  
  this.getEligible = function() {
    this.eligible = new Array();
    for (i in this.suggestions) {
      var suggestion = this.suggestions[i];
      if(suggestion.toLowerCase().indexOf(this.inputText.toLowerCase()) == "0") {
        this.eligible[this.eligible.length]=suggestion;
      }
    }
  };
  
  this.getKeyCode = function(ev) {
    if(ev) {
      return ev.keyCode;
    }
    if(window.event) {
      return window.event.keyCode;
    }
  };
  
  this.getEventSource = function(ev) {
    if(ev) {
      return ev.target;
    }
    if(window.event) {
      return window.event.srcElement;
    }
  };
  
  this.cancelEvent = function(ev) {
    if(ev) {
      ev.preventDefault();
      ev.stopPropagation();
    }
    if(window.event) {
      window.event.returnValue = false;
    }
  } 
}
var idCounter = 0;
