/* FILE INFORMATION
-----------------------------------------------------------------------------
Author:				Dan Rouw
Created:			1/19/2010 By Dan Rouw
Purpose:			To provide a class for AJAX search functionality
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.

-----------------------------------------------------------------------------
*/

var MiniSearch = new Class({
	initialize: function(obj) {
		this.travel_destination_control = $(obj.travel_destination_control);
		this.travel_interest_control = $(obj.travel_interest_control);
		this.departure_date_control = $(obj.departure_date_control);
		this.price_range_control = $(obj.price_range_control);
		this.active_filter_control = $(obj.active_filter_control);
		this.record_count_control = $(obj.record_count_control);
		this.search_button_control = $(obj.search_button_control);
		this.active_filters = {};
		// CREATE A SPINNER OBJECT. WE COULD USE THE BUILT-IN REQUEST SPINNER, BUT IT DOESN'T WANT TO FADE OUT NICELY
		this.spinner = new Spinner($(this.travel_destination_control).getParent('div'),{
			message: 'Please Wait'
			,fxOptions: { duration: 500 }
		})
		
		// 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();
		
		// WE HAVE TO CREATE THE REQUEST OBJECT HERE BECAUSE WE WANT TO BE ABLE TO CANCEL A
		// REQUEST IF THE USER CHANGES ANY OF THE CONTROLS WHILE WAITING FOR THE CURRENT REQUEST
		// THE DATA WILL BE SPECIFIED IN THE EXECUTESEARCH METHOD
		this.request = new Request.JSON({
			url: '/webservices/search/mini_search.cfc'
			,method: 'get'
			,link: 'cancel'
			,noCache: true
			// JUST AS BEFORE WE HAVE TO BIND THE THIS OBJECT SO THAT WE CAN CALL THE UPDATECONTROLS METHOD IN THIS CLASS IN THE ONSUCCESS METHOD OF THE REQUEST
			,onRequest: function() {
				// 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( navigator.userAgent.indexOf("MSIE 6") != -1 ){
					this.hideControls();
				}
				// SHOW THE SPINNER AT THE BEGINNING OF THE REQUEST
				this.spinner.show();
			}.bind(this)
			,onComplete: function() {
				// SHOW THE CONTROLS AGAIN IN IE6
				if( navigator.userAgent.indexOf("MSIE 6") != -1 ){
					this.showControls();
				}
				// HIDE THE SPINNER UPON COMPLETION OF THE REQUEST
				this.spinner.hide();
			}.bind(this)
			,onSuccess: function(obj,txt) {
				//alert(txt);
				this.updateControls(obj);
			}.bind(this)
			,onFailure: function(e) {
				alert('Error: ' + e.status + '\nPlease try again');
				// SHOW THE CONTROLS AGAIN IN IE6
				if( navigator.userAgent.indexOf("MSIE 6") != -1 ){
					this.showControls();
				}
				// HIDE THE SPINNER IF AN ERROR OCCURS
				this.spinner.hide();
			}.bind(this)
		});
			  
		//INITIALIZE THE EVENTS FOR THE CONTROLS
		this.registerEvents(this.active_filter_control);
	},
	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.
		this.travel_destination_control.addEvent('change',function() {
			// UPDATE THE ACTIVE FILTER STRUCTURE
			this.active_filters["travel_destination_filter"].value = this.travel_destination_control.getSelected()[0].get('value');
			this.active_filters["travel_destination_filter"].description = this.travel_destination_control.getSelected()[0].get('html');
			// EXECUTE THE SEARCH
			this.executeSearch();
		}.bind(this));
		
		this.travel_interest_control.addEvent('change',function() {
			// UPDATE THE ACTIVE FILTER STRUCTURE
			this.active_filters["travel_interest_filter"].value = this.travel_interest_control.getSelected()[0].get('value');
			this.active_filters["travel_interest_filter"].description = this.travel_interest_control.getSelected()[0].get('html');
			// EXECUTE THE SEARCH
			this.executeSearch();
		}.bind(this));
		
		this.departure_date_control.addEvent('change',function() {
			// UPDATE THE ACTIVE FILTER STRUCTURE
			this.active_filters["departure_date_filter"].value = this.departure_date_control.getSelected()[0].get('value');
			this.active_filters["departure_date_filter"].description = this.departure_date_control.getSelected()[0].get('html');
			// EXECUTE THE SEARCH
			this.executeSearch();
		}.bind(this));
		
		this.price_range_control.addEvent('change',function() {
			// UPDATE THE ACTIVE FILTER STRUCTURE
			this.active_filters["price_range_filter"].value = this.price_range_control.getSelected()[0].get('value');
			this.active_filters["price_range_filter"].description = this.price_range_control.getSelected()[0].get('html');
			// EXECUTE THE SEARCH
			this.executeSearch();
		}.bind(this));
		
		this.search_button_control.addEvent('click',function() {
			var goto_url = this.generateSearchURL();								 
			pageTracker._trackEvent('Homepage Promo', 'Mini-Search', goto_url);
			window.location.href = goto_url;
			//this.resetForm();
		}.bind(this));
	},
	executeSearch: function() {
		
		var requestData = 'method=execute_search' +
					'&tdgf=' + this.active_filters["travel_destination_filter"].value +
					'&tif=' + this.active_filters["travel_interest_filter"].value +
					'&drf=' + this.active_filters["departure_date_filter"].value + 
					'&prf=' + this.active_filters["price_range_filter"].value;
		//alert(requestData);
		this.request.send(requestData);
	},
	updateControls: function(obj) {		
		// CLEAR OUT THE FILTERS. THE UPDATESELECTOPTIONS METHOD WILL ADD THE FILTERS AS NECESSARY
		this.active_filter_control.empty();
		
		// UPDATE THE TRAVEL DESTINATION CONTROL
		this.updateSelectOptions(this.travel_destination_control,obj.travel_destination,'travel_destination_filter');
		
		// UPDATE THE TRAVEL INTEREST CONTROL
		this.updateSelectOptions(this.travel_interest_control,obj.travel_interest,'travel_interest_filter');
		
		// UPDATE THE DEPARTURE DATE CONTROL
		this.updateSelectOptions(this.departure_date_control,obj.departure_date,'departure_date_filter');
		
		// UPDATE THE PRICE RANGE CONTROL
		this.updateSelectOptions(this.price_range_control,obj.price_range,'price_range_filter');
		
		// UPDATE THE RECORD COUNT CONTROL
		this.record_count_control.getChildren('strong')[0].set('html', obj.record_count);
		
		// MAKE SURE THE FILTER SECTION HAS 4 LIS
		/*var filter_count = this.active_filter_control.getChildren('li').length;
		var li = '';
		while (filter_count < 4) {
			li = new Element('li', {
				'html': '&nbsp;'
			});
			li.inject(this.active_filter_control);
			filter_count++;
		}*/
		
	},
	updateSelectOptions: function(control,value_obj,filter_name) {
		var optionCount = 0;
		var option = '';
		var i = 0;
		
		// REMOVE ALL OF THE OPTIONS
		control.empty();
		
		// GET THE NUMBER OF OPTIONS TO ADD
		optionCount = value_obj.value.length;
		
		for(i = 0; i < optionCount; i++) {
			// CREATE A NEW OPTION ELEMENT
			option = new Element('option', {
				'value': value_obj.value[i]
				,'html': value_obj.description[i]
			});
			
			// IF THERE IS AN ACTIVE FILTER FOR THIS CONTROL, CHECK THE OPTIONS TO FIND A MATCH
			if( this.active_filters[filter_name].value != 0 && this.active_filters[filter_name].value != '') {
				if( value_obj.value[i] == this.active_filters[filter_name].value ) {
					// IF THE OPTION VALUE MATCHES THE ACTIVE FILTER VALUE, SELECT THE OPTION
					option.setProperty('selected',true);
					
					// DISABLE THE DROPDOWN AND FORCE THEM TO REMOVE THE FILTER BY USING THE LINK BELOW THE FILTERS
					control.setProperty('disabled',true);
				}
			} else {
				// IF THERE IS NO ACTIVE FILTER FOR THIS CONTROL, MAKE SURE IT IS ENABLED
				control.setProperty('disabled',false);
			}
			
			// ADD THE OPTION TO THE SELECT CONTROL
			option.inject(control);
			// CLEAR THE OPTION
			option = '';
		}
		
		// ADD THE FILTER TO THE FILTER BOX
		this.addFilter(filter_name);
		
	},
	addFilter: function(filter_name) {
		var li = '';
		var a = '';
		
		// IF THERE IS A REAL VALUE, ADD THE LI AND AN A TAG
		if( this.active_filters[filter_name].value != 0 && this.active_filters[filter_name].value != '') {
			li = new Element('li');
			a = new Element('a',{
				'html': this.active_filters[filter_name].description
				,'href': 'javascript:void(0);'
				,'class': 'icon remove'
				,'events': {
					'click': function(){
						this.removeFilter(filter_name);
					}.bind(this)
				}
				
			});
			a.set('title', a.get('text'));
			a.inject(li);
		} else {
			li = new Element('li',{
				'html': this.active_filters[filter_name].default_filter_text
			});
		}
		li.inject(this.active_filter_control);
	},
	removeFilter: function(filter_name) {
		// CLEAR THE FILTER FROM THE ACTIVE_FILTERS OBJECT
		this.active_filters[filter_name].value = '';
		this.active_filters[filter_name].description = '';
		// EXECUTE THE SEARCH
		this.executeSearch();
	},
	hideControls: function(){
		// THIS FUNCTION IS USED FOR IE6 TO HIDE THE CONTROLS JUST BEFORE THE AJAX REQUEST STARTS
		this.travel_destination_control.setStyle('visibility','hidden');
		this.travel_interest_control.setStyle('visibility','hidden');
		this.departure_date_control.setStyle('visibility','hidden');
		this.price_range_control.setStyle('visibility','hidden');
	},
	showControls: function(){
		// THIS FUNCTION IS USED FOR IE6 TO SHOW THE CONTROLS AFTER THE AJAX REQUEST ENDS
		this.travel_destination_control.setStyle('visibility','visible');
		this.travel_interest_control.setStyle('visibility','visible');
		this.departure_date_control.setStyle('visibility','visible');
		this.price_range_control.setStyle('visibility','visible');
	},
	generateSearchURL: function(){
		// INITIALIZE THE URL TO START A NEW SEARCH
		var url = '/search.cfm?new_search=1';
		var year_filter = 0;
		var month_filter = 0;
		var price_low_filter = 0;
		var price_high_filter = 0;
		
		// ADD FILTERS AS NEEDED
		if( this.active_filters["travel_destination_filter"].value != 0 && this.active_filters["travel_destination_filter"].value != '' ) {
			url = url + '&tdgf=' + this.active_filters["travel_destination_filter"].value;
		}
		
		if( this.active_filters["travel_interest_filter"].value != 0 && this.active_filters["travel_interest_filter"].value != '' ) {
			url = url + '&tif=' + this.active_filters["travel_interest_filter"].value;
		}
		
		if( this.active_filters["departure_date_filter"].value != 0 && this.active_filters["departure_date_filter"].value != '' ) {
			// EXTRACT THE YEAR AND MONTH FROM THE VALUE
			year_filter = this.active_filters["departure_date_filter"].value.split('_')[0];
			month_filter = this.active_filters["departure_date_filter"].value.split('_')[1];
			url = url + '&dryf=' + year_filter + '&drmf=' + month_filter;
		}
		
		if( this.active_filters["price_range_filter"].value != 0 && this.active_filters["price_range_filter"].value != '' ) {
			// EXTRACT THE LOW AND HIGH PRICE FROM THE VALUE
			price_low_filter = this.active_filters["price_range_filter"].value.split('_')[0];
			price_high_filter = this.active_filters["price_range_filter"].value.split('_')[1];
			url = url + '&prlf=' + price_low_filter + '&prhf=' + price_high_filter;
		}
		
		return url;
	},
	resetForm: function() {
		// MAKE SURE ALL OF THE CONTROLS ARE ENABLED AND VISIBLE
		this.travel_destination_control.setProperty('disabled',false);
		this.travel_interest_control.setProperty('disabled',false);
		this.departure_date_control.setProperty('disabled',false);
		this.price_range_control.setProperty('disabled',false);
		
		// FOR IE6, MAKE SURE ALL CONTROLS ARE VISIBLE
		if( navigator.userAgent.indexOf("MSIE 6") != -1 ){
			this.travel_destination_control.setStyle('visibility','visible');
			this.travel_interest_control.setStyle('visibility','visible');
			this.departure_date_control.setStyle('visibility','visible');
			this.price_range_control.setStyle('visibility','visible');
		}
		
		// RESET THE SELECTED INDEX FOR THE CONTROLS
		this.travel_destination_control.selectedIndex = 0;
		this.travel_interest_control.selectedIndex = 0;
		this.departure_date_control.selectedIndex = 0;
		this.price_range_control.selectedIndex = 0;
		
		// CLEAR THE ACTIVE FILTERS OBJECT
		this.active_filters = {
			travel_destination_filter: { value: '', description: '', default_filter_text: 'No Travel Destination Selected' }
			,travel_interest_filter: { value: '', description: '', default_filter_text: 'No Travel Interest Selected' }
			,departure_date_filter: { value: '', description: '', default_filter_text: 'No Departure Month Selected' }
			,price_range_filter: { value: '', description: '', default_filter_text: 'No Price Range Selected' }
		};
		
		/*// RESET THE ACTIVE FILTERS OBJECT BASED ON THE CONTROLS
		this.active_filters["travel_destination_filter"].value = this.travel_destination_control.getSelected()[0].get('value');
		this.active_filters["travel_destination_filter"].description = this.travel_destination_control.getSelected()[0].get('html');
		
		this.active_filters["travel_interest_filter"].value = this.travel_interest_control.getSelected()[0].get('value');
		this.active_filters["travel_interest_filter"].description = this.travel_interest_control.getSelected()[0].get('html');
		
		this.active_filters["departure_date_filter"].value = this.departure_date_control.getSelected()[0].get('value');
		this.active_filters["departure_date_filter"].description = this.departure_date_control.getSelected()[0].get('html');
		
		this.active_filters["price_range_filter"].value = this.price_range_control.getSelected()[0].get('value');
		this.active_filters["price_range_filter"].description = this.price_range_control.getSelected()[0].get('html');
		
		if (this.travel_destination_control.selectedIndex > 0 || this.travel_interest_control.selectedIndex > 0 || this.departure_date_control.selectedIndex > 0 || this.price_range_control.selectedIndex > 0 ) {
			this.executeSearch();
		}*/
		
		// RUN THE SEARCH TO GET VALID OPTIONS
		//this.executeSearch();
	},
	status: function() {
		alert(
			this.travel_destination_control.getSelected().get('value') + '\n' +
			this.travel_interest_control.getSelected().get('value') + '\n' +
			this.departure_date_control.getSelected().get('value') + '\n' +
			this.price_range_control.getSelected().get('value') + '\n' +
			this.active_filter_control.get('html') + '\n' +
			this.record_count_control.get('html')
		);
		//this.active_filter_control.set('html',this.travel_destination_control.getSelected().get('html'));
	}
});