function acFields(){this.fields={};this.register=function(name,data){this.fields[name]={json:data.jsonProvider,limit:data.limit};if(data.affected)this.fields[name]["affected"]=data.affected;if(data.consider)this.fields[name]["consider"]=data.consider;if(data.additionalData)this.fields[name]["additionalData"]=data.additionalData};this.getJsonProvider=function(name){if(this.fields[name]["json"]!=undefined)return this.fields[name]["json"];else return false};this.getConsiderFields=function(name){if(this.fields[name]["consider"]!=
undefined)return this.fields[name]["consider"];else return false};this.getAffectedFields=function(name){if(this.fields[name]["affected"]!=undefined)return this.fields[name]["affected"];else return false};this.getAdditionalData=function(name){if(typeof this.fields[name]["additionalData"]!="undefined")return this.fields[name]["additionalData"];else return false};this.getLimit=function(name){if(this.fields[name]["limit"]!=undefined)return this.fields[name]["limit"];else return false};this.getValue=function(name){return $("#"+
name).attr("value")};this.bindEvents=function(fieldId){field=$("#"+fieldId).bind("keydown",acEvents.keydown).bind("keyup",acEvents.keyup).bind("keypress",acEvents.keypress).bind("blur",acEvents.blur)}}
function acAjax(){this.data={};this.processed={};this.fieldsConsiderValues={};this.cacheAdd=function(name,value,data){this.refreshConsiderValues(name);try{this.data[name][value+this.fieldsConsiderValues[name]["idkey"]]=data}catch(e){this.data[name]={};this.cacheAdd(name,value,data)}if(data==null)this.data[name][value+this.fieldsConsiderValues[name]["idkey"]]=data};this.cacheGet=function(name,value){if(this.inCache(name,value))return this.data[name][value+this.fieldsConsiderValues[name]["idkey"]];
else return false};this.inCache=function(name,value){try{if(this.data[name][value+this.fieldsConsiderValues[name]["idkey"]]!=undefined)return true;else return false}catch(e){return false}};this.generateConsiderValuesIdkey=function(considerValues){var str="";for(field in considerValues)str=str+field+considerValues[field];return str};this.refreshConsiderValues=function(name){try{var consider=acFields.getConsiderFields(name);var values=this.collectConsiderValues(consider);this.fieldsConsiderValues[name]["values"]=
values;this.fieldsConsiderValues[name]["idkey"]=this.generateConsiderValuesIdkey(values)}catch(e){this.fieldsConsiderValues[name]={values:"",idkey:""};this.refreshConsiderValues(name)}};this.loadData=function(name,value){var value=acFields.getValue(name);var limit=acFields.getLimit(name);var affected=acFields.getAffectedFields(name);var consider=acFields.getConsiderFields(name);var additionalData=acFields.getAdditionalData(name);var jsonUrl=acFields.getJsonProvider(name);this.refreshConsiderValues(name);
var considerValues=this.collectConsiderValues(consider);var idkey=this.generateConsiderValuesIdkey(considerValues);if(value!="")if(!this.inCache(name,value)&&!this.processed[name+value+idkey]){this.processed[name+value+idkey]=true;var toAjax={};toAjax[name]=value;toAjax["field"]=name;toAjax["limit"]=limit;if(affected)toAjax["affected"]=acArrayEncoder.encode(affected);if(consider)toAjax["consider"]=acArrayEncoder.encode(considerValues);if(additionalData)toAjax["additionalData"]=acArrayEncoder.encode(additionalData);
$.getJSON(jsonUrl,toAjax,function(data){acAjax.cacheData(data,name,value)})}else this.goToView(name,value);else acView.hideMenu()};this.collectConsiderValues=function(considerFields){var out=new Array;for(index in considerFields){var fieldName=considerFields[index];out[fieldName]=$("#"+fieldName).attr("value")}return out};this.cacheData=function(data,name,value){this.cacheAdd(name,value,data);this.goToView(name)};this.goToView=function(name){acView.process(name)}}
function acEvents(){this.handleFlag=true;this.keydown=function(event){switch(event.which){case 38:this.handleFlag=false;acView.menuNavigate(event.target.id,"up");break;case 40:this.handleFlag=false;acView.menuNavigate(event.target.id,"down");break;case 13:this.handleFlag=false;break;case 27:acView.hideMenu(true);break;default:this.handleFlag=true;break}};this.keyup=function(event){if(this.handleFlag!=false)acAjax.loadData(event.target.id)};this.keypress=function(event){if(event.which==13)if(acView.hideMenu()){event.preventDefault();
return false}};this.blur=function(event){acView.hideMenu()}}
function acView(){this.currentMenu=null;this.selectedElement=null;this.selectedRowClass="autocompleteSelectedRow";this.resultListClass="autocompleteResult";this.process=function(name){this.renderMenu(name)};this.renderMenu=function(name){if(this.currentMenu!=null)this.hideMenu();var field=$("#"+name);var value=field.attr("value");var off=field.offset();acAjax.refreshConsiderValues(name);var fullData=acAjax.cacheGet(name,value);var data=fullData[name];var length=0;var firstElement=null;for(t in data){if(firstElement===
null)firstElement=t;length++}if(data&&length>0){if(length==1&&firstElement==value)return;var menu=$("<ul/>").addClass(this.resultListClass).css("position","absolute").css("zIndex","1005").css("top",off.top+field.outerHeight()).css("left",off.left).css("width",field.innerWidth()).bind("mouseout",this.menuMouseOut).appendTo(document.body);for(suggest in data)$("<li/>").text(suggest).appendTo(menu).bind("mouseover",this.itemMouseOver).bind("mousedown",{name:name},this.itemMouseDown);this.currentMenu=
{value:value,fieldId:name,affectedValuesRollback:{}};var affected=acFields.getAffectedFields(name);for(key in affected){field=affected[key];jField=$("#"+field);this.currentMenu["affectedValuesRollback"][field]=jField.attr("value")}acBrowserFixes.showAction()}};this.hideMenu=function(rollback){if(this.currentMenu!=null){if(rollback){$("#"+this.currentMenu["fieldId"]).attr("value",this.currentMenu["value"]);for(field in this.currentMenu["affectedValuesRollback"]){var value=this.currentMenu["affectedValuesRollback"][field];
jField=$("#"+field);if(jQuery.nodeName(jField,"select"))jField.selectOptions(fieldValue);else{jField.attr("value",value);jField.change()}}}$("."+this.resultListClass).remove();this.currentMenu=null;this.selectedElement=null;acBrowserFixes.hideAction();return true}else return false};this.fillAffected=function(name,userEntry,suggest){var affected=acFields.getAffectedFields(name);var data=acAjax.cacheGet(name,userEntry);for(key in affected){field=affected[key];jField=$("#"+field);var fieldValue=data[name][suggest][field];
if(jQuery.nodeName(jField,"select"))jField.selectOptions(fieldValue);else{jField.attr("value",fieldValue);jField.change()}}var pref=["","addCouple_"];for(i in pref)if(name==pref[i]+"zip"){var city=$("#"+pref[i]+"city").val();var val=$("#"+pref[i]+"zip").val();$("#"+pref[i]+"zip").val(val.substring(0,val.lastIndexOf(city)-1));if(window.handleIdRelatedField)handleIdRelatedField()}};this.menuNavigate=function(name,direction){var field=$("#"+name);if(this.currentMenu==null){acAjax.loadData(name);return}$("li."+
this.selectedRowClass).removeClass(this.selectedRowClass);menu=$("."+this.resultListClass);var items=$("li",menu).get();if(items.length>0){if(direction==="down")if(this.selectedElement==items.length-1||this.selectedElement==null)this.selectedElement=0;else this.selectedElement=this.selectedElement+1;else if(direction==="up")if(this.selectedElement==0||this.selectedElement==null)this.selectedElement=items.length-1;else this.selectedElement=this.selectedElement-1;items[this.selectedElement].className=
this.selectedRowClass;var value=items[this.selectedElement].innerHTML;$(field).attr("value",value);$(field).change();this.fillAffected(name,this.currentMenu["value"],value)}};this.menuMouseOut=function(){$("li."+acView.selectedRowClass).removeClass(acView.selectedRowClass)};this.itemMouseOver=function(){$("li."+acView.selectedRowClass).removeClass(acView.selectedRowClass);$(this).toggleClass(acView.selectedRowClass)};this.itemMouseDown=function(event){var field=$("#"+event.data.name);var newValue=
$(this).text();var oldValue=field.attr("value");field.attr("value",newValue);field.change();acView.fillAffected(event.data.name,oldValue,newValue)}}
function acArrayEncoder(){this.encode=function(array){var serializedString="";var arrayLength=0;for(var aKey in array){if(aKey*1==aKey)serializedString+="i:"+aKey+";";else serializedString+="s:"+aKey.length+':"'+aKey+'";';if(array[aKey]*1==array[aKey])serializedString+="i:"+array[aKey]+";";else if(typeof array[aKey]=="string")serializedString+="s:"+array[aKey].length+':"'+array[aKey]+'";';else if(array[aKey]instanceof Array)serializedString+=serializeArray(array[aKey]);arrayLength++}serializedString=
"a:"+arrayLength+":{"+serializedString+"}";return serializedString}}
function acBrowserFixes(){this.hiddenFromExplorer=new Array;this.showAction=function(){if($.browser.msie)this.explorerDropDownListsFixHide()};this.hideAction=function(){if($.browser.msie)this.explorerDropDownListsFixShow()};this.explorerDropDownListsFixHide=function(){var menu=$("."+acView.resultListClass);var offset=menu.offset();var oh=menu.outerHeight();var ow=menu.outerWidth();var l=offset.left;var r=offset.left+ow;var t=offset.top;var b=offset.top+oh;var key=0;$("select").each(function(){var off=
$(this).offset();sl=off.left;sr=off.left+$(this).outerWidth();st=off.top;sb=off.top+$(this).outerHeight();if((st>=t&&sb<=b||st>=t&&st<=b)&&(sl>=l&&sl<=r||sr<=r&&sr>=l)){var select=$(this);select.css("visibility","hidden");var arr=acBrowserFixes.hiddenFromExplorer;arr.push(select)}})};this.explorerDropDownListsFixShow=function(){for(select in this.hiddenFromExplorer)this.hiddenFromExplorer[select].css("visibility","visible");this.hiddenFromExplorer=new Array}}var acFields=new acFields;var acAjax=new acAjax;
var acEvents=new acEvents;var acArrayEncoder=new acArrayEncoder;var acView=new acView;var acBrowserFixes=new acBrowserFixes;$(document).ready(function(){$("body").mousedown(function(){acView.hideMenu()});for(fieldId in acFields.fields)acFields.bindEvents(fieldId)});

