/* FILE INFORMATION
-----------------------------------------------------------------------------
Author:				Dan Rouw
Created:			2/10/2011 By Dan Rouw
Purpose:			To provide a class for AJAX search functionality using jQuery
Update History:		
Methods:			
					initialize		Initializes the properties of the class
						args:		obj		A JSON object that contains the ids of the controls, or the control objects themselves
			
					registerEvents	Creates all necessary events on the controls
					
					executeSearch	Uses an AJAX request to pass the current filters to a web service, which returns a JSON object to update the controls.
					
					status			Used for debugging. Alerts the values of the controls.

-----------------------------------------------------------------------------
*/
MiniSearch = function(obj){
	this.formControlIDs = obj.formControlIDs;
	this.numFormControls = this.formControlIDs.length;
	this.controls = [];
	
	this.activeFilterControl = jQuery('#'+obj.activeFilterControl);
	this.recordCountControl = jQuery('#'+obj.recordCountControl);
	this.searchButtonControl = jQuery('#'+obj.searchButtonControl);
	this.spinnerControl = jQuery('#'+obj.spinnerControl);
	
	this.activeFilters = [];
	
	if( navigator.userAgent.toLowerCase().indexOf("msie 6") != -1 ){
		this.isIE6 = true;
	} else {
		this.isIE6 = false;
	}
	
	this.init();
}

MiniSearch.prototype.init = function(){
	for(var i=0; i<this.numFormControls; i++){
		// USE THE FORM CONTROL ID TO GET THE CONTROLS. THEIR NAME SHOULD CORRESPOND TO THE APPROPRIATE SEARCH/URL VARIABLE
		this.controls[i] = {
			field: jQuery('#'+this.formControlIDs[i])
			,urlVar: jQuery('#'+this.formControlIDs[i]).attr('name')
		};
	}
	
	this.ActiveFilterControlPs = jQuery(this.activeFilterControl).find('p');
	
	// INITIALIZE, OR RESET, THE FORM. THIS HAS TO BE CALLED FOR BROWSERS LIKE FIREFOX THAT REMEMBER YOUR SELECTIONS WHEN YOU USE THE BACK BUTTON
	this.resetForm();
	  
	//INITIALIZE THE EVENTS FOR THE CONTROLS
	this.registerEvents();
}

MiniSearch.prototype.request = function(data){
	// RUN THE AJAX SEARCH
	jQuery.ajax({
		url: '/webservices/search/mini_search.cfc'
		,data: data
		,cache: false
		,dataType: 'json'
		,context: this
		,timeout: 60000
		,beforeSend: function(){
			//alert('beforeSend');
			// IE6 HAS ISSUES WITH SELECT BOXES BEING ON TOP OF OVERLAYS, SO WE'LL HIDE THE CONTROLS FOR IE6 TO FORCE PEOPLE INTO SELECTING 1 OPTION AT A TIME
			if( this.isIE6 ) {
				this.hideControls();
			}
			
			// HIDE THE SPINNER UPON COMPLETION OF THE REQUEST
			this.spinnerControl.fadeIn();
		}
		,complete: function(){
			//alert('complete');
			// HIDE THE SPINNER UPON COMPLETION OF THE REQUEST
			this.spinnerControl.fadeOut();
			
			// SHOW THE CONTROLS AGAIN IN IE6
			if( this.isIE6 ) {
				this.showControls();
			}
		}
		,success: function(data, textStatus, jqXHR){
			//alert('success');
			//alert(data);
			this.updateControls(data);
		}
		,error: function(jqXHR, textStatus, errorThrown){
			alert('error: ' + textStatus);
			// HIDE THE SPINNER UPON COMPLETION OF THE REQUEST
			this.spinnerControl.fadeOut();
			
			// SHOW THE CONTROLS AGAIN IN IE6
			if( this.isIE6 ) {
				this.showControls();
			}
		}
	});
}

MiniSearch.prototype.registerEvents = function() {
	//IN ORDER TO CALL A METHOD WITIN THIS CLASS, WE MUST BIND THE THIS OBJECT TO THE EVENT. OTHERWISE THE
	//THIS OBJECT IN THE ONCHANGE FUNCTION WILL BE THE CONTROL OBJECT ITSELF INSTEAD OF THE CLASS OBJECT.
	for(var i=0; i<this.numFormControls; i++){
		this.controls[i].field.bind('change',{that: this, i: i},function(evt){
			evt.data.that.activeFilters[evt.data.i].value = jQuery(this).val();
			evt.data.that.activeFilters[evt.data.i].description = jQuery(this).find('option:selected').text();
			
			// EXECUTE THE SEARCH
			evt.data.that.executeSearch();
		});
	}
	
	this.searchButtonControl.bind('click',{that: this}, function(evt){
		var gotoUrl = evt.data.that.generateSearchURL();								 
		// AT THIS TIME WE DON'T HAVE GA TRACKING ON THE EXTREME HOME PAGE FOR THE MINI SEARCH
		//pageTracker._trackEvent('Homepage Promo', 'Mini-Search', goto_url);
		window.location.href = gotoUrl;
	});
}

MiniSearch.prototype.executeSearch = function() {
	var requestData = 'method=execute_search';
	// ADD THE FILTERS
	for(var i=0; i<this.numFormControls; i++){
		requestData = requestData + '&' + this.controls[i].urlVar + '=' + this.activeFilters[i].value;
	}
	//alert(requestData);
	this.request(requestData);
}

MiniSearch.prototype.updateControls = function(data) {
	// CLEAR OUT THE FILTERS. THE UPDATESELECTOPTIONS METHOD WILL ADD THE FILTERS AS NECESSARY
	for(var i=0; i<this.numFormControls; i++){
		// THE LINE BELOW WORKS WITHOUT JQUERY() IN FF, BUT NOT IN IE
		jQuery(this.ActiveFilterControlPs[i]).empty();
		this.updateSelectOptions(i,data[this.controls[i].field.attr('id')]);
	}
	
	// UPDATE THE RECORD COUNT CONTROL
	this.recordCountControl.html(data.record_count + ' trips');
}

MiniSearch.prototype.updateSelectOptions = function(index,data) {
	var optionCount = 0;
	var option = '';
	var i = 0;
	
	// REMOVE ALL OF THE OPTIONS
	this.controls[index].field.empty();
	
	// GET THE NUMBER OF OPTIONS TO ADD
	optionCount = data.value.length;
	
	for(i = 0; i < optionCount; i++) {
		// CREATE A NEW OPTION ELEMENT
		option = jQuery(document.createElement('option'));
		option.attr('value',data.value[i]);
		option.html(data.description[i]);
		
		// IF THERE IS AN ACTIVE FILTER FOR THIS CONTROL, CHECK THE OPTIONS TO FIND A MATCH
		if( this.activeFilters[index].value != 0 && this.activeFilters[index].value != '') {
			if( data.value[i] == this.activeFilters[index].value ) {
				// IF THE OPTION VALUE MATCHES THE ACTIVE FILTER VALUE, SELECT THE OPTION
				option.attr('selected',true);
				
				// DISABLE THE DROPDOWN AND FORCE THEM TO REMOVE THE FILTER BY USING THE LINK BELOW THE FILTERS
				this.controls[index].field.attr('disabled',true);
			}
		} else {
			// IF THERE IS NO ACTIVE FILTER FOR THIS CONTROL, MAKE SURE IT IS ENABLED
			this.controls[index].field.attr('disabled',false);
		}
		
		// ADD THE OPTION TO THE SELECT CONTROL
		this.controls[index].field.append(option);
		
		// CLEAR THE OPTION
		option = '';
	}
	
	// ADD THE FILTER TO THE FILTER BOX
	this.addFilter(index);
	
}

MiniSearch.prototype.addFilter = function(index) {
	var a = '';
	var p = this.ActiveFilterControlPs[index];
	
	// IF THERE IS A REAL VALUE, ADD THE LI AND AN A TAG
	if( this.activeFilters[index].value != 0 && this.activeFilters[index].value != '') {
		a = jQuery(document.createElement('a'));
		a.text(this.activeFilters[index].description);
		a.attr('href','javascript:void(0);');
		a.attr('title',a.text());
		a.addClass('icon remove_white');
		a.bind('click',{that: this},function(evt){
			evt.data.that.removeFilter(index);
		});
		
		jQuery(p).append(a);
	} else {
		jQuery(p).html(this.activeFilters[index].defaultFilterText);
	}
}

MiniSearch.prototype.removeFilter = function(index) {
	this.activeFilters[index].value = 0;
	this.activeFilters[index].description = '';
	
	// EXECUTE THE SEARCH
	this.executeSearch();
}

MiniSearch.prototype.hideControls = function(){
	for(var i=0; i<this.numFormControls; i++){
		// THIS FUNCTION IS USED FOR IE6 TO HIDE THE CONTROLS JUST BEFORE THE AJAX REQUEST STARTS
		this.controls[i].field.css('visibility','hidden');
	}
}

MiniSearch.prototype.showControls = function(){
	for(var i=0; i<this.numFormControls; i++){
		// THIS FUNCTION IS USED FOR IE6 TO SHOW THE CONTROLS AFTER THE AJAX REQUEST ENDS
		this.controls[i].field.css('visibility','visible');
	}
}

MiniSearch.prototype.generateSearchURL = function(){
	
	// INITIALIZE THE URL TO START A NEW SEARCH
	var url = '/adventure-travel/search/';
	var firstFilterFound = false;
	
	// ADD FILTERS AS NEEDED
	for(var i=0; i<this.numFormControls; i++){
		if (this.activeFilters[i].value != 0 && this.activeFilters[i].value != ''){
			// IF WE HAVE FOUND AT LEAST 1 FILTER, ADD AN & BEFORE THE URL VAR
			if(firstFilterFound){
				url = url + '&';
			} else {
				// THE FIRST URL VAR WILL HAVE A ? BEFORE IT
				url = url + '?';
				// MARK THE FIRST FILTER AS FOUND
				firstFilterFound = true;
			}
			// THE DEPARTURE DATE FILTER IS A YEAR AND MONTH COMBINED. THE VALUES ARE DELIMITED BY AN _ CHARACTER.
			if(this.controls[i].urlVar.toLowerCase().indexOf('_') >= 0){
				var urlVars = this.controls[i].urlVar.split('_');
				var urlValues = this.activeFilters[i].value.split('_');
				if(urlVars.length != urlValues.length){
					// IF THE 2 ARRAYS ARE NOT THE SAME LENGTH, RETURN AS 1 PARAMETER
					url = url + this.controls[i].urlVar + '=' + this.activeFilters[i].value;
				} else {
					// IF THE LENGTHS MATCH, LOOP THROUGH THEM AND ADD THEM.
					for(var j=0; j<urlVars.length; j++){
						// SINCE WE KNOW THERE IS ALREADY EITHER A ? OR & WE DON'T NEED TO ADD THAT FOR THE FIRST ONE.
						if (j != 0){
							url = url + '&';
						}
						url = url + urlVars[j] + '=' + urlValues[j];
					}
				}
			} else {
				// THE URL VAR DOES NOT HAVE A DELIMITER
				url = url + this.controls[i].urlVar + '=' + this.activeFilters[i].value;
			}
		}
	}
	return url;
	
}

MiniSearch.prototype.resetForm = function() {
	for(var i=0; i<this.numFormControls; i++){
		// MAKE SURE ALL OF THE CONTROLS ARE ENABLED AND VISIBLE
		this.controls[i].field.removeAttr('disabled');
		
		// RESET THE SELECTED INDEX FOR THE CONTROLS
		this.controls[i].field.attr('selectedIndex',0);
		
		// CLEAR THE ACTIVE FILTERS OBJECT
		
		this.activeFilters[i] = {
			value: 0
			,description: ''
			,defaultFilterText: jQuery(this.ActiveFilterControlPs[i]).html()
		}
		
		// FOR IE6, MAKE SURE ALL CONTROLS ARE VISIBLE
		if( this.isIE6 ){
			this.controls[i].field.css('visibility','visible');
		}
	}
	
	// RUN THE SEARCH TO GET VALID OPTIONS
	//this.executeSearch();
}

MiniSearch.prototype.status = function() {
	var msg = '';
	
	for(var i=0; i<this.numFormControls; i++){
		msg = msg + this.controls[i].urlVar + ': ' + this.controls[i].field.val() + '\n';
	}
	msg = msg + 'filter set: ' + this.activeFilterControl.html() + '\n';
	msg = msg + 'record count: ' + this.recordCountControl.html() + '\n';
	alert(msg);
}

