var SearchBox = new Class({
	options: {
		formSubmit: false,
		enterSubmit: false,
		selectSubmit: false,
		validation: true,
		typeDelay: 200	
	},
	initialize: function(element, options){
		if(options){
			this.setOptions(options);
		}
		this.element = $(element);
		this.element.setProperty("autocomplete", "off");
		this.lastSearchText = this.element.value;
		this.resultContainer = null;
		this.cover = null;
		this.entryCount = 0;
		this.index = 0;
		this.isEmpty = true;
		this.isClicked = false;
		this.bound = {			
			"keyup": this.onkeyup.bindWithEvent(this),
			"keydown": this.onkeydown.bindWithEvent(this),
			"keypress": this.onkeypress.bindWithEvent(this),
			"blur": this.onblur.bindWithEvent(this),
			"mouseover": this.onmouseover.bindWithEvent(this),
			"mousedown": this.onmousedown.bindWithEvent(this),
			"buttonSubmit": this.buttonSubmit.bindWithEvent(this)
		};
		this.errorPrefix = '<img width="8" height="8" border="0" alt="" src="/page/images/error_bullet.gif"/><b>College Name:</b> ';
		this.emptyErrorMsg = "You must enter a college name to search.";	
		this.errorMsgElement = $('search_suggestion_error');	
		this.schoolId = "searchSuggestionSchoolId";
		this.containerId = "searchsuggestioncontainer";
		this.anchorElement = this.element;
	},
	setTriggerElement: function(triggerElement) {
		this.options.formSubmit = false;
		this.triggerElement = $(triggerElement);
		this.originalEvent = function(){};
		if(this.triggerElement.onclick){
			this.originalEvent =  this.triggerElement.onclick;
		}
		this.triggerElement.onclick = this.bound.buttonSubmit;
	},
	setErrorMsgElement: function(errorMsgElement){
		this.errorMsgElement = $(errorMsgElement);
	},	
	setFormElement: function(formElement){
		this.options.formSubmit = true;
		this.triggerElement = $(formElement);
	},
	
	hasSchoolId: function(){
		return (this.schoolIdElement.getProperty("value") != "");
	},
	
	clearSchoolId: function(){
		if(this.schoolIdElement) this.schoolIdElement.setProperty("value", "");
	},
	
	setSchoolId: function(schoolId){
		this.schoolIdElement.setProperty("value", schoolId);
	},	
	setSchoolName: function(schoolName){
		var maxlength = this.element.getProperty("maxlength");
		if(typeof maxlength != "undefined"){
			schoolName = schoolName.substring(0,maxlength);
		}
		this.element.setProperty("value", schoolName);
	},
	executeHbxTrack: function(){
	},
	submit: function(){			
		this.executeHbxTrack();
		if(this.options.formSubmit){
			this.triggerElement.click();
		}else{
			if(this.originalEvent) {
				this.triggerElement.onclick = this.originalEvent;
			}
			this.triggerElement.onclick();
			this.triggerElement.onclick = this.bound.buttonSubmit;
		}
		this.reboundKeyupEvent();
	},
	buttonSubmit: function(e){
		if(HELP_POPUP) {
			HELP_POPUP.documentClose(e);
		}
		e = new Event(e);
		e.stop();
		if(this.options.validation && !this.valideText(this.element.value)){
			return false;
		}
		this.clear();
		this.empty();
		this.isButtonSubmit = true;			
		if(this.hasSchoolId()){
			this.submit();
		}else{
			if(!this.isClicked){
				this.isClicked = true;			
				this.lightBoxRequest(this.element.value.trim());
			}
			return false;
		}
	},
	setTriggerForm: function(triggerForm){
		this.triggerForm = $(triggerForm);
		var queryString = this.triggerForm.toQueryString();
	},
	
	start: function(){
		this.element.addEvent("change", this.clearSchoolId.bindWithEvent(this));
		this.element.addEvent("keyup", this.bound.keyup);
		this.element.addEvent("keydown", this.bound.keydown);
		this.element.addEvent("blur", this.bound.blur);
		this.element.onkeypress = this.bound.keypress;
		this.schoolIdElement = $(this.schoolId);
		if(!this.schoolIdElement){
			this.schoolIdElement = new Element("input");
			this.schoolIdElement.setProperty("id", this.schoolId);
			this.schoolIdElement.setProperty("type", "hidden");
			this.schoolIdElement.setProperty("value", "");
			this.schoolIdElement.injectInside(document.body);
		}
	},
	onblur: function(){
		this.empty();
	},
	onkeydown: function(e){
		e = new Event(e);		
		switch (e.key) {
			case 'up':
				this.markPrevious();
				e.stop();
				return false;
			case 'down':
				this.markNext();
				e.stop();
				return false;
		}
	},
	onkeyup: function(e){
		e = new Event(e);
		if(e.key != 'enter' && e.key != 'left' && e.key != 'right'){
			this.clearSchoolId();
		}	
		switch (e.key) {
			case 'esc':
				this.empty();
				e.stop();	
				return false;		
			case 'enter':
				this.isButtonSubmit = false;
				this.onenter();
				e.stop();	
				return;			
			case 'left':
	        case 'right':
	         	return false;			
			default:				
				this.onchange();
				return false;
		}
	},
	reboundKeyupEvent: function(){
		this.element.removeEvent("keyup", this.bound.keyup);
		this.element.addEvent("keyup", this.bound.keyup);
	},
	onkeypress: function(e){
		e = new Event(e);
		if(e.key == 'enter'){
			return false;
		}
	},
	onchange: function(){
		this.clear();
		var changeFun = function(){			
			var inputvalue = this.element.value;			
			var currentvalue = inputvalue.trim();
			var orginalvalue = this.lastSearchText.trim();
			if(currentvalue != "" && ((currentvalue != orginalvalue 
								&& (orginalvalue == ""
									|| currentvalue.indexOf(orginalvalue)!=0
									|| this.entryCount == 10
									|| currentvalue.length < orginalvalue.length))
									|| !this.madeRequest)){
				this.empty();
				this.defaultUpdate(currentvalue);
			}else if(this.entryCount>0 
						&& this.entryCount< 10 
						&& currentvalue != orginalvalue 
						&& orginalvalue != "" 
						&& currentvalue.indexOf(orginalvalue)== 0){
				var newArray = [];
				this.resultArray.each(function(ele){
					var collegeName = "";
					if(ele.collegeName){
						collegeName = ele.collegeName.toUpperCase();
					}
					var altCollegeName = "";
					if(ele.altCollegeName){
						altCollegeName = ele.altCollegeName.toUpperCase();
					}
					if(collegeName.indexOf(inputvalue.toUpperCase()) != -1 || (altCollegeName != "&NBSP;" && altCollegeName.indexOf(inputvalue.toUpperCase()) != -1)){
						newArray.push(ele);
					}
				});
				this.resultArray = newArray;
				this.updateContainer();
			}else if((currentvalue == ""  || this.entryCount == 0) && !this.isEmpty){
				this.empty();		
			}
			this.lastSearchText = inputvalue;			
		};
		this.timer = changeFun.delay(this.options.typeDelay, this);		
	},	
	onenter: function(){
		this.executeHbxTrack();
		this.clear();
		var enterFromLi = false;
		if(!this.isEmpty){
			var selectedLi = $$("ul#"+this.containerId+" li.select");
			for(var i=0; i < selectedLi.length; i++){
				var li = selectedLi[i];
				var value = li.getFirst().getText();				
				this.setSchoolName(value);
				var schoolId = li.getElement("div").getText().trim();
				this.setSchoolId(schoolId);	
				enterFromLi = true;
				this.focusElement();
				this.clearErrorMsg();
				break;
			}			
		}
		this.empty();
		if(this.options.validation && !this.valideText(this.element.value)){
			return false;
		}
		if(this.options.enterSubmit && this.options.formSubmit){
			this.submit();
		}else if(this.hasSchoolId()){
			if(this.options.enterSubmit || !enterFromLi){
				this.submit();
			}else{
				this.reboundKeyupEvent();
			}
		}else{
			this.lightBoxRequest(this.element.value.trim());
		}
	},
	lightBoxRequest: function(inputvalue){
		//TODO
	},
	valideText: function(text){
	},
	clearErrorMsg: function(){
	},
	getTopLi: function(e){
		var li = $(e.target);	
		while(li.tagName.toUpperCase() != "LI"){
			li = li.getParent();
		}
		return li;
	},
	onmouseover: function(e){		
		e = new Event(e);
		var li = this.getTopLi(e);
		this.cleanStyle();
		// set the index.
		var children = this.resultContainer.getChildren();
		children.each(function(child, i){
			if(child.getFirst().getText() == li.getFirst().getText()){
		       this.index = i + 1;
		    }
		}, this);
		li.addClass('select');		
	},
	onmousedown: function(e){
		e = new Event(e);
		// clear the schoolId than set school id and name
		this.isButtonSubmit = false;	
		this.clearSchoolId();
		this.clearErrorMsg();
		var li = this.getTopLi(e);
		var value = li.getFirst().getText();
		this.setSchoolName(value);
		var schoolId = li.getElement("div").getText().trim();
		this.setSchoolId(schoolId);		
		
		this.focusElement();
		if(this.options.selectSubmit){			
			this.submit();
		}
	},	
	focusElement: function(){
		this.element.focus();
		this.element.select();
	},
	blurElement: function(){
		this.element.blur();
	},
	prepareParameter: function(schoolObject){
	},
	
	render: function() {
	  	var lis = this.resultContainer.getChildren();
		this.cleanStyle();
		lis[this.index-1].addClass("select");		  
  	},
	markNext: function(){
	 if(!this.isEmpty) {
	 	if (this.index < this.entryCount) {
	 		this.index+=1;
	 	}
	 	else {
	 		this.index = 1;
	 	}
		this.render();
	 }
	},
	markPrevious: function(){
	 if(!this.isEmpty) {
	 	if (this.index > 1){
	 		this.index-=1;
	 	}else{ 
	 		this.index = this.entryCount;
	 	}
		this.render();
	 }
	},
	defaultUpdate: function(inputvalue){
		this.entryCount = 0;
		this.resultArray = this.getUpdatedResult(inputvalue);
		this.updateContainer();
	},
	getUpdatedResult: function(inputvalue){
		//TODO need the subclass implement this method
	},
	updateContainer: function(){
		if (this.resultArray && this.resultArray.length != 0) {
			this.create();			
			this.fill();			
		}
		else if(this.resultArray.length == 0) {
			this.empty();
		}
		this.entryCount = this.resultArray.length;
	},
	create: function(){
		if(this.resultContainer == null){
			this.resultContainer = new Element("UL")
			this.resultContainer.setProperty("id", this.containerId);						
			this.resultContainer.injectAfter(this.element);		
			// create the cover element
			if(window.ie && this.cover == null){	
				this.cover = new Element("IFRAME"); 
				this.cover.addClass("containercover");
				this.cover.setProperty("src", "javascript:''");
				this.cover.setOpacity(0.1);
				this.cover.injectAfter(this.element);
			}
		}else{			
			this.empty();
		}
		// reset the position of the container
		if(this.resultContainer){
			this.resultContainer.setStyle('left', this.anchorElement.getLeft());
			this.resultContainer.setStyle('top', this.anchorElement.getTop() + this.anchorElement.offsetHeight);
			this.resultContainer.setStyle('width', this.anchorElement.offsetWidth);
		}
		if(window.ie && this.cover){
			this.cover.setStyle('left', this.anchorElement.getLeft());
			this.cover.setStyle('top', this.anchorElement.getTop() + this.anchorElement.offsetHeight);
			this.cover.setStyle('width', this.anchorElement.offsetWidth);
		}
	},
	fill: function(){
		if(this.resultContainer){
			this.resultArray.each(function(ele){
				var li = new Element("LI");
				if(window.webkit || window.opera){				
					li.setStyle("width", "96%");
				}
				li.setStyle('display', 'block');
				var inputvalue = this.element.value.trim();
				inputvalue = inputvalue.replace(".", "\\.");
				inputvalue = inputvalue.replace("(", "\\(");
				inputvalue = inputvalue.replace(")", "\\)");
				inputvalue = inputvalue.replace("*", "\\*");
				var html = "<label class='collname'>"+ele.collegeName+"</label><label class='citystate'>"+ele.schoolCity+", "+ele.schoolState+"</label><div style='display:none'>"+ele.schoolId+"</div>";
				li.setHTML(html);
				li.injectInside(this.resultContainer);
				li.addEvent("mouseover", this.bound.mouseover);
				if(window.opera){
					li.onmousedown = this.bound.mousedown;
				}else{
					li.addEvent("mousedown", this.bound.mousedown);
				}
			}, this)			
			this.resultContainer.setStyle('visibility', 'visible');	
			
			// capture the mouse click event of the resultContainer.			
			document.addEvent('click',function(){
										this.empty();
									}.bind(this));			
		}
		if(this.cover){
			this.cover.setStyle('visibility', 'visible');
			this.cover.setStyle('height', this.resultContainer.offsetHeight);
		}		
		this.index = 0;
		this.isEmpty = false;
	},	
	empty: function(){
		if(this.resultContainer){
			this.resultContainer.empty();
			this.resultContainer.setStyle('visibility', 'hidden');
		}
		if(this.cover){
			this.cover.setStyle('visibility', 'hidden');
		}
		this.isEmpty = true;
	},
	cleanStyle: function(){
		//clean the select style	
		$$("ul#"+this.containerId+" li.select").each(function(li){						
			li.removeClass('select');
		});
	},
	getFormParent: function(ele){
		var parent = ele.getParent();
		if(parent){
			if(parent.tagName == 'FORM'){
				return parent;
			}else if(parent.tagName == 'BODY'){
				return null;
			}else{
				return this.getFormParent(parent)
			}
		}
	},
	clear: function(){		
		if(this.timer)$clear(this.timer)
	},
	setErrorMesage: function(msg){
		var errors = $$(".strutserror");
		if(errors){
			for(var i=0; i< errors.length; i++){
				errors[i].setStyle("display", "none");			
			}
		}
		if(this.errorMsgElement){
			this.errorMsgElement.setStyle("display", "block");
			this.errorMsgElement.setHTML(this.errorPrefix + msg);
		}
	}
});

SearchBox.implement(new Options);

var LocalSearchBox = SearchBox.extend({
	valideText: function(text){
		return true;
	},
	initialize: function(element, localArray, options){
		this.parent(element, options);
		this.localArray = localArray;
	},
	getUpdatedResult: function(inputvalue){
		this.resultArray = [];
		this.localArray.each(function(ele){
			if(ele.toUpperCase().indexOf(inputvalue.toUpperCase()) != -1){
				this.resultArray.push(ele);
			}
		});
	}
});

var AjaxSearchBox = SearchBox.extend({
	defaultUpdate: function(inputvalue){
		this.entryCount = 0;
		this.getUpdatedResult(inputvalue);
	},
	getUpdatedResult: function(inputvalue){
		this.madeRequest = true;
	},
	onComplete: function(resultArray){		
		this.resultArray = resultArray;
		this.updateContainer();
	}
});

var CollegeAjaxSearchBox = AjaxSearchBox.extend({	
	// clear the error message for search suggestion
	clearErrorMsg: function(){
		if(this.errorMsgElement)this.errorMsgElement.setStyle("display", "none");	
		var collegeNameLabel = $('collegeNameLabel');
		if(collegeNameLabel){
			collegeNameLabel.removeClass("collegenameerror")
		}
	},	
	
	setErrorMesage: function(msg){
		this.parent(msg);
		var collegeNameLabel = $('collegeNameLabel');
		if(collegeNameLabel){
			collegeNameLabel.addClass("collegenameerror")
		}
	},
	
	valideText: function(text){
		var retval = true;
		if(text.trim() == ""){
			this.setErrorMesage(this.emptyErrorMsg);
			retval = false;
		}
		return retval;
	},	
	lightBoxRequest: function(collegeName){		
		this.clearErrorMsg();
		this.populateVO(collegeName);
		SearchSuggestion.getSchoolList(
			this.vo, dwrCallback(null, {callback: function(text){this.schoolListCallback(text)}.bind(this)}) 
		);
	},	
	
	populateVO: function(collegeName){
		this.vo = {};
		this.vo.collegeName = collegeName;
		this.vo.forwardPath = "/page/inc/search_suggestion_college_list.jsp"
		this.vo.requestAction = "default";
	},
	
	schoolListCallback: function(text){
		this.blurElement();
		this.reboundKeyupEvent();
		this.isClicked = false;
		var searchSuggestionInstance = this;
		LIGHT_BOX.bindbeforedisplay(function(text){
			var retval = true;
			var colleges = this.content.getElements("li");			
			if(colleges.length == 1){
				var schoolObject = searchSuggestionInstance.getSchoolObject(colleges[0].getElements("a")[0]);				
				LIGHT_BOX.empty();
				searchSuggestionInstance.setSchoolId(schoolObject.schoolId);
				searchSuggestionInstance.setSchoolName(schoolObject.schoolName);
				if(searchSuggestionInstance.isButtonSubmit || searchSuggestionInstance.options.enterSubmit){
					searchSuggestionInstance.submit();
				}
				retval = false;
			}else if(colleges.length == 0){
				searchSuggestionInstance.setErrorMesage(text);
				retval = false;
			}
			return retval;
		});
		LIGHT_BOX.showmodal(text);
		//bind click event for the link in the lightbox.
		var links = $$(".lboxcont ul li a");
		if(links){
			for(var i=0; i<links.length; i++){
				var schoolObject = this.getSchoolObject(links[i]);
				links[i].addEvent("click", this.clickLink.bindWithEvent(this, schoolObject));
			}
		}
	},
	
	clickLink: function(e, schoolObject){
		if(e){
			new Event(e).stop();
			if(LOADING_BOX)LOADING_BOX.close();
		}	
		this.setSchoolId(schoolObject.schoolId);
		this.setSchoolName(schoolObject.schoolName);
		
		this.focusElement();
		if(this.isButtonSubmit || this.options.enterSubmit){
			this.submit();
		}
	},
	
	getSchoolObject: function(ele){
		var obj = {};
		obj.href = ele.getProperty("href");
		obj.schoolName = ele.getNext().getText();
		obj.schoolId = ele.getNext().getNext().getText();
		return obj;
	},
		
	getUpdatedResult: function(collegeName){
		this.parent(collegeName);
		SearchSuggestion.getSchoolSearchSuggestion(
			collegeName, dwrCallback(null, {callback: function(resultArray){this.onComplete(resultArray)}.bind(this)})
		);	
	}
});


var AdmissionsResultSearchBox = CollegeAjaxSearchBox.extend({
	initialize: function(element, options){
		this.parent(element, options);		
		this.emptyErrorMsg = "You must enter a college name to view admissions profiles.";
		this.errorPrefix = "";
		this.schoolId = "resultSchoolId";
	},
	populateVO: function(collegeName){
		this.parent(collegeName);
		var classYear = DWRUtil.getValue("classYear");
		this.vo.classYear = classYear;
		this.vo.requestAction = "admissionsTrackerResult";
	},
	executeHbxTrack: function(){
		//_hbPageView('Track+Another','/tracker/results');
	}
});


var CollegeChanceSearchBox = CollegeAjaxSearchBox.extend({
	initialize: function(element, options){
		this.parent(element, options);		
		this.emptyErrorMsg = 'You must enter a college name to calculate your College Chances.';		
		this.schoolId = "schoolId";
	},
			
	populateVO: function(collegeName){
		this.parent(collegeName);
		this.vo.requestAction = "collegeChance";
	},
	
	valideText: function(text){
		var retval = true;
		if(text.trim() == ""){
			this.setErrorMesage(this.emptyErrorMsg);
			if($$('.chanceresult')[0]) $$('.chanceresult')[0].remove();
			if($$('.college_chance_cal_intro')[0]) $$('.college_chance_cal_intro')[0].setStyle('display', '');
			retval = false;
		}
		return retval;
	},
	
	setErrorMesage: function(msg){
		var imgs = document.forms[0].getElementsByTagName("img");
		for(var i = 0; i < imgs.length; i++)
		{
			if(imgs[i].src.indexOf("/page/images/error_arrow.gif")>=0)
			{
				imgs[i].style.display="none";
			}
		}
		var spans = document.forms[0].getElementsByTagName("span");
		for(var i = 0; i < spans.length; i++)
		{
			if(spans[i].className && spans[i].className.indexOf("error") != -1)
			{
				var classNames = spans[i].className.split(' ');
				var targetClassName = '';
				var first = true;
				for(var k = 0; k < classNames.length; k ++) {
					var className = classNames[k];
					if(className != 'error') {
						if(first) targetClassName += className;
						else targetClassName += ' ' + className;					
					}
				}
				spans[i].className = targetClassName;
			}
		}
		this.parent(msg);
	}

});	

var NetCostSearchBox = CollegeAjaxSearchBox.extend({
	initialize: function(element, options){
		this.parent(element, options);		
		this.emptyErrorMsg = 'You must enter a college name to calculate your College Net Cost.';		
		this.schoolId = "college_id";
	},
	populateVO: function(collegeName){
		this.parent(collegeName);
		this.vo.requestAction = "netCost";
	}
});	

var YourCollegeSearchBox = CollegeAjaxSearchBox.extend({
	initialize: function(element, options){
		this.parent(element, options);		
		this.emptyErrorMsg = 'You must enter a college name to view admissions profiles.';		
		this.schoolId = "yourSchoolId";
	},
	populateVO: function(collegeName){
		this.parent(collegeName);
		this.vo.requestAction = "yourCollegeList";
	},
	valideText: function(text){
		var retval = this.parent(text);
		if(retval){
			if(text == "Enter College Name to Add"){
				this.setErrorMesage(this.emptyErrorMsg);
				retval = false;
			}
		}
		return retval;
	}
});	

var AdmissionsHomeSearchBox = CollegeAjaxSearchBox.extend({
	initialize: function(element, options){
		this.parent(element, options);		
		this.emptyErrorMsg = "You must enter a college name to view admissions profiles.";		
		this.schoolId = "trackCollegeId";
	},
	populateVO: function(collegeName){
		this.parent(collegeName);
		var classYear = DWRUtil.getValue("classYear");
		this.vo.classYear = classYear;
		this.vo.requestAction = "admissionsTrackerHome";
	}
});	