function autosug(el, vel, type, minChar, maxSug, loc){

  //variables
  this.el = el;
  this.vel = vel;
  this.type = type;
  this.resPos = -1;
  this.minChar = minChar;
  this.ro = createRO();
  this.maxSug = maxSug;
  this.loc = loc;
  this.to;

  var self = this;
  
  //functions
  this.init = function(){
    this.initSug();
    addEvent(el,'keyup',this.procKeyUp);
    addEvent(el,'keydown',this.procKeyDown);
    addEvent(el,'blur',this.procBlur);
  };

  this.procKeyUp = function(e){
    
    if(self.el.value.length >= self.minChar){
      oEvent=window.event || e;
      var iKeyCode=oEvent.keyCode;
      
      if(iKeyCode==8 || iKeyCode==46){
        clearTimeout(self.to);        
        self.to = setTimeout(self.sendReq(), 300);
      }
      else if (iKeyCode < 32 || (iKeyCode >= 33 && iKeyCode <= 46) || (iKeyCode >= 112 && iKeyCode <= 123)) {
        //ignore
      } 
      else{
        clearTimeout(self.to);
        self.to = setTimeout(self.sendReq(), 300);
      }
    }
  };

  //Initialize the suggestion div
  this.initSug = function(){
    if(document.getElementById("autoSugDiv") != null){
      this.sugBox = document.getElementById("autoSugDiv");
    }
    else{
      this.sugBox = document.createElement("div");
      this.sugBox.id = "autoSugDiv";
      this.sugBox.className = "suggestions";
      this.sugBox.style.position = "absolute";
      this.sugBox.style.overflowY = "auto";
      this.sugBox.style.border = "1px solid black";
      this.sugBox.style.visibility = "hidden";
      this.sugBox.style.backgroundColor = "#FFFFFF";
      this.sugBox.style.cursor = "hand";
      document.body.appendChild(this.sugBox);
    }
  }

  this.sendReq = function(){
      self.hideSug();
      this.ro.open('get', '/results_me.php?limit=' + this.maxSug + '&type=' + this.type + '&val=' + this.el.value, true);
      this.ro.onreadystatechange = self.getRes;
      this.ro.send(null);
    
  };
  
  this.disRes = function(){
    
    var res = self.ro.responseXML.getElementsByTagName('result');

    for (var i=0, j = res.length;i<j;i++){
      var tDiv = document.createElement('div');
      var regEx = new RegExp(self.el.value, 'gi');
      tDiv.id = getNodeValue(res[i],'id');
      tDiv.innerHTML = getNodeValue(res[i],'sug').replace(regEx, self.el.value.bold().toUpperCase());
      addEvent(tDiv,'mouseover',function(){ self.procMouseOver(this)});
      addEvent(tDiv,'mouseout',function(){ self.procMouseOut(this)});
      addEvent(tDiv,'mousedown',function(){ self.procMouseDown(this)});
      tDiv.style.padding = "3px 0px 0px 3px";
      tDiv.className = "notSel";
      self.sugBox.appendChild(tDiv);
    }
    if(res.length > 6){
      self.sugBox.style.height = (self.sugBox.childNodes[2].offsetHeight * 5) + "px";
      self.sugBox.style.paddingRight = "";
    }
    else{
      self.sugBox.style.height = "";
      self.sugBox.style.paddingRight = "";
    }
    if(res.length > 0){
      self.showSug();
    }
  };

  this.getRes = function(){
    if(self.ro.readyState == 4){
      self.disRes();  
    }
  };

  this.showSug = function(){
    self.sugBox.style.visibility = "visible";
    self.sugBox.style.top = getTop(self.el) + self.el.offsetHeight + "px";

    //Switch to determine where to align the suggestion box
    //Default is "left" if "center" or "right" isn't specified
    switch(self.loc){
      case "center":
        self.sugBox.style.left = (getLeft(self.el) + (self.el.offsetWidth / 2) - (self.sugBox.offsetWidth / 2)) + "px";  
        break;
      case "right":
        self.sugBox.style.left = (getLeft(self.el) + self.el.offsetWidth - self.sugBox.offsetWidth) + "px";  
        break;
      default:
        self.sugBox.style.left = getLeft(self.el) + "px";        
        break;
    }
  };
  
  this.hideSug = function(){
    self.resPos = -1;
    self.sugBox.style.visibility = "hidden";
    self.sugBox.innerHTML = ""; 
  };

  this.procMouseOver = function(el){
    for(var i=0, j = self.sugBox.childNodes.length;i < j;i++){
      if(el.id == self.sugBox.childNodes[i].id){
        self.resPos = i;
        el.className = "selected";
      }
      else{
        self.sugBox.childNodes[i].className = "notSel";
      }
    }
  }
  
  this.procMouseOut = function(el){
    el.className = "notSel";
  }

  this.procMouseDown = function(el){
    self.el.value = el.innerHTML.replace(/(<([^>]+)>)/ig,"").toLowerCase();
    self.vel.value = el.id;
    self.hideSug();
  }

  this.procKeyDown = function(e){
        oEvent=window.event || e;
        var iKeyCode=oEvent.keyCode;
     
        switch(iKeyCode)
        {
           case 27: //ESC
             self.hideSug();
             return false;
             break;
           case 38: //up arrow
             self.procUpArrow();
             break;
           case 40: //down arrow
             self.procDownArrow();
             break;
           case  9: //tab key
             if(self.resPos >= 0){
               self.el.value=self.sugBox.childNodes[self.resPos].innerHTML.replace(/(<([^>]+)>)/ig,"").toLowerCase();
               self.vel.value = self.sugBox.childNodes[self.resPos].id;
             }
             self.hideSug();
             break;           
           case 13: //return key
             if(self.sugBox.style.visibility == 'hidden'){
               return true;
             }
             if(self.resPos >= 0){
               self.el.value=self.sugBox.childNodes[self.resPos].innerHTML.replace(/(<([^>]+)>)/ig,"").toLowerCase();
               self.vel.value=self.sugBox.childNodes[self.resPos].id;
             }
             self.hideSug();
             return false;
             break;
    }
  };
  
  this.procUpArrow = function(){

    if(self.sugBox.childNodes.length > 0 && self.resPos > 0){
      --self.resPos;
      
      if(self.resPos < (self.sugBox.childNodes.length - 3)){
        self.sugBox.scrollTop = self.sugBox.scrollTop - self.sugBox.childNodes[self.resPos].offsetHeight;
      }      
      
      for(var i=0, j = self.sugBox.childNodes.length;i < j;i++){
         if(i == self.resPos){
              self.sugBox.childNodes[i].className = "selected";
            }
            else{
               self.sugBox.childNodes[i].className = "notSel";
            }
      }
    }
  };
  
  this.procDownArrow = function(){

    if(self.sugBox.childNodes.length > 0 && self.resPos < (self.sugBox.childNodes.length - 1)){
      ++self.resPos;
      
      if(self.resPos > 2){
        self.sugBox.scrollTop = self.sugBox.scrollTop + self.sugBox.childNodes[self.resPos].offsetHeight;
      }
      
      for(var i=0, j = self.sugBox.childNodes.length;i < j;i++){
         if(i == self.resPos){
              self.sugBox.childNodes[i].className = "selected";
            }
            else{
               self.sugBox.childNodes[i].className = "notSel";
            }
      }
    }
  };

  this.procBlur = function(){
    
    if(document.activeElement != self.sugBox && document.activeElement != self.el){
      self.hideSug();
    }
    
  };

  //make sure to initialize the object
  this.init();
}