getTimestamp = function(){			
	var currentTime = new Date();
	var month = currentTime.getMonth() + 1;
	var day = currentTime.getDate();
	var year = currentTime.getFullYear();
	var hours = currentTime.getHours();
	var minutes = currentTime.getMinutes();
	var seconds = currentTime.getSeconds();
	return ''+year+month+day+hours+minutes+seconds;
}

formHelper = {
	init : function(){
		formHelper.el.setFocus();
		formHelper.el.initHighlight();
	},
	el : {
		setFocus : function(){
		errors = Dom.getElementsByClassName("errorFormEle");
			if(isArray(errors)){
				focusEle = errors[0];
				if(focusEle && focusEle.tagName){
					switch(focusEle.tagName){
						case "select" : {
							focusEle.options[focusEle.selectedIndex].focus();
							break;
						}
						default : {
							focusEle.focus();
						}
					}
					formHelper.el.focus(focusEle);
				}
			
			}	
		},
		initHighlight : function(){
			hEls = ["input","textarea","select"];
			for(hEl_i=0;hEl_i<hEls.length;hEl_i++){
				els = document.getElementsByTagName(hEls[hEl_i]);
				for(el_i=0;el_i<els.length;el_i++){
					el = els[el_i];
					if(el.type!="hidden" && el.type!="image"){
						Event.addListener(el,'focus',formHelper.el.focus);
						Event.addListener(el,'blur',formHelper.el.blur);
					}	
				}
			}
		},
		focus : function(el){	
			if(el.type!="focus"){
				Dom.addClass(el,"formHelper-element-focus");
			}else{
				Dom.addClass(this,"formHelper-element-focus");
			}
		},
		blur : function(el){
			if(el.type!="blur"){
				Dom.removeClass(el,"formHelper-element-focus");
			}else{
				Dom.removeClass(this,"formHelper-element-focus");
			}
		}
	},
	error : {
		focusFirstErrorEle : function(){
				
		}
	},
	ajax:	{ 
		filter: {
			triggerGroups: []
			,triggers: {}
			,addTrigger: function(o){
				if(tg = new formHelper.ajax.filter.triggerGroup(o)){
					this.triggerGroups.push(tg);
				}	
			}
			,triggerGroup: function(o){
				//	define methods
				this.doTrigger = function(e,trigger){
					trigger.updateResults();
				}
				this.updateResultSuccess = function(o){
					if(o && (rt = o.responseText) && (rs = eval(rt))){
						var triggerGroup = o.argument.triggerGroup;
						
						//	iterate through resultEls
						for(var rEl_i=0;rEl_i<triggerGroup.resultEls.length;rEl_i++){
							//	get current resultEl
							rEl = triggerGroup.resultEls[rEl_i];
							//	call renderResults method
							rEl.renderResults(rs);
						}
					}
				}
				this.updateResultFailure = function(r){
					//console.info(this,r);
				}
				
				//	****	TRIGGER ELEMENTS bof	*****	//
				
				//	the elements trigger this lookup?
				this.triggers = [];
				var triggerEls = o.triggerEls;
				
				//	only add those triggerEls which are found to the group
				var triggers = formHelper.ajax.filter.triggers;
				for(var tEl_i=0;tEl_i<triggerEls.length;tEl_i++){
					var tElId = triggerEls[tEl_i];
					var	tEl = document.getElementById(tElId.id);
					if(tEl){
						//	create a new trigger and simultaineously store a reference to it
						var tmpTrigger = new formHelper.ajax.filter.triggerCmp(tEl,tElId.v,this.doTrigger,this);
						//console.info(tElId.id);
						triggers[tElId.id] = tmpTrigger;
						this.triggers.push(tmpTrigger);
					}
				}				
				//	****	TRIGGER ELEMENTS eof	*****	//
				
				//	****	RESULT ELEMENTS bof	*****	//
				
				//	the elements receive the result of the lookup?
				var resultEls = o.resultEls;
				this.resultEls = [];
				for(var rEl_i=0;rEl_i<resultEls.length;rEl_i++){
					var rElId = resultEls[rEl_i];
					var	rEl = document.getElementById(rElId.id);
					if(rEl){
						this.resultEls.push(formHelper.ajax.filter.resultCmp(rEl,rElId.v,this));
					}
				}
				//	****	RESULT ELEMENTS eof	*****	//
				
				//	****	TRIGGER DATA URI bof	*****	//
				var loadTriggerUri = o.loadTriggerUri;
				if(typeof loadTriggerUri == 'string' && loadTriggerUri!=""){
					if(loadTriggerUri!=""){
						if(loadTriggerUri.indexOf("?")==-1){
							uriJoin = "?";
						}else{
							uriJoin = "&";
						}
						loadTriggerUri += uriJoin + "json=true&tid=" + getTimestamp();
					}
					this.loadTriggerUri = loadTriggerUri;
				}
				
				//	****	TRIGGER DATA URI eof	*****	//
				
				//	****	RESULT DATA URI bof	*****	//
				var sUri = o.sUri;
				if(typeof sUri == 'string' && sUri!=""){
					this.sUri = sUri;
				}
				//	****	RESULT DATA URI eof	*****	//
				
				
				//	****	INIT	***	//
				//	initiate triggers
				for (var t_i = 0; t_i < this.triggers.length; t_i++) {
					this.triggers[t_i].init();
				}
				
				
				
				
				return this;
			}
			,triggerCmp: function(el,initValue,callback,triggerGroup){
				if(el && (tag=el.tagName)){
					switch(tag){
						case 'select':
							var event = 'change';
						break;
						/*case 'input':
							var event = 'change';
						break;*/
					}
					this.el = el;
					this.triggerGroup = triggerGroup;
					this.updateResults = function(){
						//	connect to remove data source
						Connect.asyncRequest(
							'GET'
							,this.triggerGroup.sUri + this.el.value + "&json=true&tid=" + getTimestamp()
							,{
								success: this.triggerGroup.updateResultSuccess
								,failure: this.triggerGroup.updateResultFailure
								,argument: {
									triggerGroup: this.triggerGroup
									,ev:"init"
								}
							}
						);
					}
					this.initiated = false;
					this.initValue = initValue;
					
					this.init = function(){
						//	make selection if ! initiated
						if(this.initiated==false){
							this.el.value = this.initValue;
							this.initiated = true;
							this.updateResults();
						}
					}
					
					Event.addListener(el,'change',callback,this);
					return this;
				}
				return null;
			}
			,resultCmp: function(el,initValue,triggerGroup){
				var cmp = null;
				if(el && (tag=el.tagName)){	
					switch(tag.toLowerCase()){
						case 'select':
							cmp = new formHelper.ajax.filter.comboResultCmp();
						break;
						case 'input':
							cmp = new formHelper.ajax.filter.inputResultCmp();
						break;
					}
					cmp.el = el;
					cmp.triggerGroup = triggerGroup;
					cmp.initiated = false;
					cmp.initValue = initValue;
					cmp.setValue = function(value,delay){
						if(delay){
							el = this.el;
							setTimeout(
								function(){
									el.value = value;
								}
								,delay
							);
						}else{
							this.el.value = value;
						}
					}
					return cmp;
				}
				return null;
			}
			,comboResultCmp: function(){
				this.renderResults = function(rs,callback){
					var domEl = this.el;
					//	remove all children from the resultEl
					domEl.innerHTML = '';
					/*
					for (var rc_i = 0; rc_i < domEl.childNodes.length; rc_i++) {
						domEl.removeChild(domEl.childNodes[rc_i]);
					}
					*/
					
					//	iterate through data and set the options to be equal
					for(var r_i=0;r_i<rs.length;r_i++){
						var r = rs[r_i];
						
						//	create option DOM
						var opt = document.createElement('option');
						opt.value = r.v;
						opt.innerHTML = r.l;	
						//	append option DOM to the select box
						domEl.appendChild(opt);
					}
					
					//	make selection if ! initiated
					if(this.initiated==false){
						this.setValue.call(this,this.initValue,200);
						this.initiated = true;
					}
					
					//	if this resultEl is also a trigger, call its update method
					if(trigger = formHelper.ajax.filter.triggers[domEl.id]){
						trigger.updateResults();
					}
					
					//	call callback, if exists
					if(callback && (fn = callback.fn) && (typeof fn == 'function')){
						if(scope = callback.scope){}else{scope = this;}
						fn.call(scope,callback.o);
					}
				}
				return this;
			}
			,inputResultCmp: function(){
				this.renderResults = function(rs,callback){
					
				}
				return this;
			}
		}
	}
}
autoCompleteListBox = {
	create : function(label,value,url,resultsContainter,resultLimit,forceSelection){
    oACDS = new YAHOO.widget.DS_XHR(url, ["ResultSet.Result",label]);
    oACDS.queryMatchContains = true;
    oACDS.scriptQueryAppend = "output=json&json=true&callType=autoComplete&resultLimit=" + resultLimit;

    oAutoComp = new YAHOO.widget.AutoComplete(label,resultsContainter, oACDS);
    oAutoComp.useShadow = true;
    oAutoComp.formatResult = function(oResultItem, sQuery) {
        return(oResultItem[1].l);
    };

    oAutoComp.label = label;
    oAutoComp.value = value;
   	oAutoComp.maxResultsDisplayed = resultLimit; 
   	oAutoComp.useIFrame = true; 
   	oAutoComp.forceSelection = forceSelection;
   	oAutoComp.doBeforeExpandContainer = function(oTextbox, oContainer, sQuery, aResults) {
      var pos = YAHOO.util.Dom.getXY(oTextbox);
      pos[1] += YAHOO.util.Dom.get(oTextbox).offsetHeight;
      Dom.setXY(oContainer,pos);
      return true;
    };
  	oAutoComp.itemSelectEvent.subscribe(autoCompleteListBox.itemSelectHandler);
  	oAutoComp.textboxBlurEvent.subscribe(autoCompleteListBox.itemSelectHandler);
  },
  itemSelectHandler : function(sType, aArgs) {
		var oMyAcInstance = aArgs[0]; // your AutoComplete instance
		var elListItem = aArgs[1]; //the <li> element selected in the suggestion	      
		var aData = aArgs[2]; //array of the data for the item as returned by the DataSource
		if(aData){
			$(oMyAcInstance.label).value = aData[1].l;
			$(oMyAcInstance.value).value = aData[1].v;
		}else if($(oMyAcInstance.label).value ==""){
			$(oMyAcInstance.value).value = 0;
		}
		if($(oMyAcInstance.value).isAjaxListBoxTrigger==true){
			formHelper.ajax.filter.processResult(null,{el:$(oMyAcInstance.value),ev:""});
		}
	}
}
Event.addListener(window,'load',formHelper.init);
