// If you use this file, you must also link common/js/dynamic.js to the same

function AjaxSearchManager() {
		this.searches = [];

		var Doc = new Dynamic(document.body);
		Doc.listen("keyup",this.resetAllPos());
}

AjaxSearchManager.prototype.addAjaxSearch = function(inputId,searchBoxId,outputIds,domestic,ignoreWidth,searchFunction,selectFunction) {
		var index = this.searches.length;
		var Search = new AjaxSearch(index,inputId,searchBoxId,outputIds,domestic,ignoreWidth,searchFunction,selectFunction);
		Search.turnOn();

		this.searches.push(Search);

		return Search;
}

AjaxSearchManager.prototype.resetAllPos = function() {
		var obj = this;

		return (function(e) {
						for(var i=0, len=obj.searches.length; i<len; i++) {
								obj.searches[i].resetPos(e);
						}
				});
}

function AjaxSearch(index,inputId,searchBoxId,outputIds,domestic,ignoreWidth,searchFunction,selectFunction) {
	this.index = index;
	this.Input = new Dynamic(inputId);
	this.SearchBox = new Dynamic(searchBoxId,"div",document.body,true);
	this.SearchBox.addClass("searchBox");
	this.outputIds = outputIds;
	this.domestic = !!domestic;
	this.ignoreWidth = !!ignoreWidth;
	this.searchFunction = searchFunction;
	this.selectFunction = selectFunction;

	this.currResults = [];
	this.focusKey = -1;
	this.prevKey = 0;
	this.nextKey = 0;

	this.setBoxPos();
	this.Input.el.setAttribute("autocomplete","off");

	this.searchArpt = this.getSearchArpt();
	this.chooseAndClose = this.getChooseAndClose();
	this.chooseAndCloseKey = this.getChooseAndCloseKey();

}

AjaxSearch.prototype.turnOn = function() {
		this.Input.listen("keyup",this.searchArpt);
		this.Input.listen("blur",this.chooseAndClose);
		this.Input.listen("keydown",this.chooseAndCloseKey);
		this.Input.listen("focus",this.clearEvent());
}		

AjaxSearch.prototype.turnOff = function() {
		this.Input.ignore("keyup",this.searchArpt);
		this.Input.ignore("blur",this.chooseAndClose);
		this.Input.ignore("keydown",this.chooseAndCloseKey);
		this.Input.ignore("focus",this.clearEvent());
}

AjaxSearch.prototype.setBoxPos = function() {
	this.top = this.Input.findY() + this.Input.el.offsetHeight;
	this.bottom = this.top + this.SearchBox.el.offsetHeight;
	this.left = this.Input.findX();
	if(!this.ignoreWidth) {
		this.SearchBox.el.style.width = this.Input.el.offsetWidth + "px";
	}
	this.SearchBox.setPos(this.top + "px",this.left + "px");
}

AjaxSearch.prototype.show = function() {
	if(this.SearchBox.el.style.visibility != "visible") {
		this.SearchBox.show();
		this.focusKey = -1;
		this.prevKey = 0;
		this.nextKey = 0;
		this.toggleSelects();
	}
}

AjaxSearch.prototype.hide = function() {
	if(this.SearchBox.el.style.visibility != "hidden") {
		this.SearchBox.hide();
		this.toggleSelects(true);
	}
}

AjaxSearch.prototype.clearEvent = function() {
	var obj = this;
	return (function() {
					obj.Input.el.value = "";
			});
}

AjaxSearch.prototype.empty = function() {
	this.SearchBox.empty();
}

AjaxSearch.prototype.toggleSelects = function(done) {
	this.SearchBox.toggleSelects(done);
}

AjaxSearch.prototype.handleArrows = function(e) {
	if(e.keyCode == 38) {
		if(this.SearchBox.el.firstChild && this.SearchBox.el.style.visibility == "visible") {
			this.showClickable(e,this.prevKey,true);
		}
	} else if(e.keyCode == 40) {
		if(this.SearchBox.el.firstChild && this.SearchBox.el.style.visibility == "visible") {
			this.showClickable(e,this.nextKey,true);
		}
	} else if(e.keyCode == 32) {
		if(this.focusKey != -1) {
			this.hide();
		}
	} else if(e.keyCode == 13) {
		if(this.focusKey != -1) {
			this.hide();
			this.Input.el.focus();
		}
	}
}

AjaxSearch.prototype.makeResult = function(newResults) {
	this.resultRows = [];
	var docFrag = document.createDocumentFragment();
	var resultsTable = new Dynamic("","table",docFrag);
	var resultsTBody = new Dynamic("","tbody",resultsTable.el);
	if(newResults.length > 0) {
		for(var d=0, len=newResults.length; d<len; d++) {
			var row = newResults[d];
			var newRow = new Dynamic("","tr",resultsTBody.el);
			var cells = [];
			for(var resultKey in row) {
					var Cell = new Dynamic("","td",newRow.el);
					Cell.appendChildren(row[resultKey]);
					Cell.addClass(resultKey);
					cells.push(Cell);
			}

			this.makeClickable(newRow,this.resultRows.length);
			this.resultRows.push(newRow);
		}
		this.SearchBox.el.appendChild(docFrag);
		this.show();
		this.resetFocus();
		this.currResults = newResults;
	} else {
		this.hide();
	}
}


AjaxSearch.prototype.resetFocus = function() {
		this.focusKey = -1;
		this.nextKey = 0;
		this.prevKey = 0;
		this.handleArrows({"keyCode": 40});
}


AjaxSearch.prototype.makeClickable = function(obj,key) {
	var hostObj = this;
	obj.listen("mouseover",function(e){hostObj.showClickable(e,key,true);});
	obj.listen("mouseout",function(e){hostObj.showClickable(e,key,false);});
}


AjaxSearch.prototype.chooseOption = function() {
		this.selectFunction();
		this.hide();
}


AjaxSearch.prototype.showClickable = function(e,key,clear) {
	if(!clear) {
		this.resultRows[key].removeClass("clickable");
		this.focusKey = -1;
		this.nextKey = 0;
		this.prevKey = 0;
	} else {
		if(this.focusKey != -1) {
			this.resultRows[this.focusKey].removeClass("clickable");
		}
		this.focusKey = key;
		this.prevKey = (this.focusKey == 0 ? 0 : this.focusKey - 1);
		this.nextKey = (this.focusKey == this.resultRows.length - 1 ? this.resultRows.length - 1 : this.focusKey + 1);
		this.resultRows[key].addClass("clickable");
	}
}

AjaxSearch.prototype.resetPos = function(e) {
	if(e.ctrlKey && (e.keyCode == 61 || e.keyCode == 109)) {
		this.setBoxPos();
	}
}

AjaxSearch.prototype.getSearchArpt = function() {
		var obj = this;
		return (function(e) {
						var e = e || window.event;
						var re = /^[\s ]+$/;
						if(!re.test(obj.Input.el.value) && e.keyCode != 38 && e.keyCode != 40 && e.keyCode != 32 && e.keyCode != 13) {
								domestic = obj.domestic ? 1 : 0;
								obj.searchFunction(obj.Input.el.value, obj.index, domestic);
						} else {
								obj.handleArrows(e);
						}
				});
}

AjaxSearch.prototype.getChooseAndClose = function() {
		var obj = this;

		return (function() {
						obj.chooseOption();
						obj.empty();
				});
}

AjaxSearch.prototype.getChooseAndCloseKey = function() {
		var obj = this;

		return (function(e) {
						if(e.keyCode == 13) {
								obj.chooseOption();
								obj.empty();
						}
				});
}
