// Global Killswitch
if (isJsEnabled()) {
  addLoadEvent(autocompleteAutoAttach);
}

/**
 * trim()
 */
function trim(value) {
   var temp = value;
   var obj = /^(\s*)([\W\w]*)(\b\s*$)/;
   if (obj.test(temp)) { temp = temp.replace(obj, '$2'); }
   var obj = /  /g;
   while (temp.match(obj)) { temp = temp.replace(obj, " "); }
   return temp;
};

function getInputValue(fieldValue, isMulti) {
	if (isMulti) {
		debug("full value:"+fieldValue);
		fieldValueArray = fieldValue.split(',');
		if (fieldValueArray.length == 0) return "";
		lastInput = fieldValueArray[fieldValueArray.length-1];
		lastInput = trim(lastInput);
		debug("last value:*"+lastInput+"*");
		return lastInput;
	} else {
		return fieldValue;
	}
};

function setSelectValue(fieldValue, value, isMulti) {
	if(isMulti) {
		debug("field value:"+fieldValue);
		debug("value:"+value);	
		fieldValueArray = fieldValue.split(',');
		if (fieldValueArray.length == 0) return "";
		fieldValueArray[fieldValueArray.length-1] = value;
		retValue = fieldValueArray.join(",");
		debug("retValue:*"+retValue+"*");
		return retValue+",";	
	} else {	
		return value;
	}
};


/**
 * Attaches the autocomplete behaviour to all required fields
 */
function autocompleteAutoAttach() {
  var acdb = [];
  var inputs = document.getElementsByTagName('input');
  for (i = 0; input = inputs[i]; i++) {  	
    if (input && hasClass(input, 'autocomplete')) {
	
      uri = input.value;
      if (!acdb[uri]) {
        acdb[uri] = new ACDB(uri);
      }
      id = input.id.substr(0, input.id.length - 13);

      input = document.getElementById(id);
      input.setAttribute('autocomplete', 'OFF');
      input.form.onsubmit = autocompleteSubmit;
      var obj = new jsAC(input, acdb[uri]);
    }
  }
};

/**
 * Prevents the form from submitting if the suggestions popup is open
 */
function autocompleteSubmit() {
	debug("autocompleteSubmit");
  var popup = document.getElementById('autocomplete');
  if (popup) {
    popup.owner.hidePopup();
    return false;
  }
  return true;
};


/**
 * An AutoComplete object
 */
function jsAC(input, db) {
  var ac = this;
  this.input = input;
  this.db = db;  
  this.input.onkeydown = function (event) { return ac.onkeydown(this, event); };
  this.input.onkeyup = function (event) { ac.onkeyup(this, event) };
  this.input.onblur = function () { ac.hidePopup() };
  this.popup = document.createElement('div');
  this.popup.id = 'autocomplete';
  this.popup.owner = this;
  this.isMulti = hasClass(input, 'multi');
//  document.getElementsByTagName('body')[0].appendChild(this.popup);  
//  this.hidePopup()
};

/**
 * Hides the autocomplete suggestions
 */
jsAC.prototype.hidePopup = function (keycode) {
	toggleSelects(this.input.id, false);
  if (this.selected && ((keycode && keycode != 46 && keycode != 8 && keycode != 27) || !keycode)) {
  	debug("ENTER");
    try {  
 	   this.input.value = setSelectValue(this.input.value, this.selected.autocompleteValue, this.isMulti);
	  	debug("ENTER1"); 	   
 	   this.input.focus();
	  	debug("ENTER2"); 	    	   
 	   // move the cursor
 	   if (this.input.setSelectionRange) {
	 	   try {		 	   	
			this.input.setSelectionRange(this.input.value.length, this.input.value.length);
		  	debug("ENTER3"); 	    	   			
	   	    this.input.focus();		  	
		  	debug("ENTER3Focus"); 	
			} catch (f) {					  	    	   			
			  	debug("ErrFFf"); 	    	   					    					 	   
			}
		} 
		if (this.input.createTextRange) {
	 	   try {		
		  	debug("ENTER4"); 	    	   					
			tr = this.input.createTextRange();
			tr.collapse(false);
			tr.select();
			} catch (g) {			
			  	debug("ErrGG"); 	    	   					    
			     debug(g.message);			
			}
		} 	   
    } catch(e) {
  	debug("Err"); 	    	   					    
     debug(e.message);
    }
  }
  if (this.popup.parentNode && this.popup.parentNode.tagName) {
    removeNode(this.popup);
  }
  this.selected = false;
};


/**
 * Handler for the "keydown" event
 */
jsAC.prototype.onkeydown = function (input, e) {

  var popup = document.getElementById('autocomplete');
		
  if (!e) {
    e = window.event;
  }
  switch (e.keyCode) {
  
    case 40: // down arrow    	
    if (popup) {
      this.selectDown();
      return false;
    } else {
    	return true;
    }
    case 38: // up arrow
    if (popup) {    
      this.selectUp();
      return false;
    } else {
    	return true;
    }      
    default: // all other keys
      return true;
  }
};

/**
 * Handler for the "keyup" event
 */
jsAC.prototype.onkeyup = function (input, e) {
  if (!e) {
    e = window.event;
  }
  switch (e.keyCode) {
    case 16: // shift
    case 17: // ctrl
    case 18: // alt
    case 20: // caps lock
    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
      return true;

    case 9:  // tab
    case 13: // enter
    case 27: // esc
      this.hidePopup(e.keyCode);
      return true;

    default: // all other keys
      if (input.value.length > 0)
        this.populatePopup();
      else
        this.hidePopup(e.keyCode);
      return true;
  }
};

/**
 * Puts the currently highlighted suggestion into the autocomplete field
 */
jsAC.prototype.select = function (node) {
  debug("SELECTION DONE");
//  this.input.value = setSelectValue(this.input.value, node.autocompleteValue);
};

/**
 * Highlights the next suggestion
 */
jsAC.prototype.selectDown = function () {
  if (this.selected && this.selected.nextSibling) {
    this.highlight(this.selected.nextSibling);
  }
  else {
    var lis = this.popup.getElementsByTagName('li');
    if (lis.length > 0) {
      this.highlight(lis[0]);
    }
  }
};

/**
 * Highlights the previous suggestion
 */
jsAC.prototype.selectUp = function () {
  if (this.selected && this.selected.previousSibling) {
    this.highlight(this.selected.previousSibling);
  }
};

/**
 * Highlights a suggestion
 */
jsAC.prototype.highlight = function (node) {
  removeClass(this.selected, 'selected');
  addClass(node, 'selected');
  this.selected = node;
};

/**
 * Unhighlights a suggestion
 */
jsAC.prototype.unhighlight = function (node) {
  removeClass(node, 'selected');
  this.selected = false;
};

/**
 * Positions the suggestions popup and starts a search
 */
jsAC.prototype.populatePopup = function () {

  var ac = this;
  var pos = absolutePosition(this.input);
  this.selected = false;
  this.popup.style.top   = (pos.y + this.input.offsetHeight) +'px';
  this.popup.style.left  = pos.x +'px';
//  this.popup.style.width = (this.input.offsetWidth - 4) +'px';
  this.db.owner = this;
  var value = 
  this.db.search(getInputValue(this.input.value, this.isMulti));
  
};

/**
 * Fills the suggestion popup with any matches received
 */
jsAC.prototype.found = function (matches) {
  toggleSelects(this.input.id, true);
  while (this.popup.hasChildNodes()) {
    this.popup.removeChild(this.popup.childNodes[0]);
  }
  if (!this.popup.parentNode || !this.popup.parentNode.tagName) {
    document.getElementsByTagName('body')[0].appendChild(this.popup);
  }
  
  var ul = document.createElement('ul');
  var ac = this;
  var matchRegExp = new RegExp('('+getInputValue(this.input.value, this.isMulti)+ ')', 'gi');
  if (matches.length > 0 ) {
    for (i in matches) {
      li = document.createElement('li');
      div = document.createElement('div');
      div.innerHTML = matches[i][1];
      
      div.innerHTML = div.innerHTML.replace(matchRegExp, "<span class=\"match\">$1</span>");
      li.appendChild(div);
      li.autocompleteValue = matches[i][0];
      li.onmousedown = function() { ac.select(this); };
      li.onmouseover = function() { ac.highlight(this); };
      li.onmouseout  = function() { ac.unhighlight(this); };
      ul.appendChild(li);
    }
    this.popup.appendChild(ul);
    this.input.focus();
  }
  else {
    this.hidePopup();
  }

};

/**
 * An AutoComplete DataBase object
 */
function ACDB(uri) {
  this.uri = uri;
  this.max = 15;
  this.delay = 300;
  this.cache = {};
};

/**
 * Performs a cached and delayed search
 */
ACDB.prototype.search = function(searchString) {
  if (this.docache) {
    this.searchString = searchString;
    if (this.cache[searchString]) {
      return this.match(this.cache[searchString]);
    }
  }
 if (this.timer) {
    clearTimeout(this.timer);
  }
   var db = this;
   this.timer = setTimeout(function() {
	
    HTTPPost(db.uri,'q='+ searchString, db.receive, db);
  }, this.delay); 
};

/**
 * HTTP callback function. Passes suggestions to the autocomplete object
 */
ACDB.prototype.receive = function(string, xmlhttp, acdb) {

  if (xmlhttp.status != 200) {
//    return alert('An HTTP error '+ xmlhttp.status +' occured.\n'+ acdb.uri);
  }
  // Split into array of key->value pairs
  var matches = string.length > 0 ? string.split('||') : [];
  for (i in matches) {
//      alert('>'+matches[i]+'<');
    matches[i] = matches[i].length > 0 ? matches[i].split('|') : [];
    // Decode textfield pipes back to plain-text
    //    matches[i][0] = eregReplace('&#124;', '|', matches[i][0]);
  }
  acdb.cache[acdb.searchString] = matches;
  acdb.owner.found(matches);
};

var d="";
function debug(text) {
//d = d+"<br>"+text;
//document.getElementById('debug').innerHTML=d;
};

function toggleSelects(id, bool){
	var fields = document.getElementById(id+"-autocomplete").fields;
	if(fields != null){
		var splitFields = fields.split("|");
	
		for(i = 0; i < splitFields.length; i++){
			if(document.getElementsByName(splitFields[i])[0] != null){
				if(bool){
					document.getElementsByName(splitFields[i])[0].style.visibility = "hidden";
				} else {
					document.getElementsByName(splitFields[i])[0].style.visibility = "";
				}
			}
		}
	}

	
}



