/**************
flyglobespan.com Searchbox
Developer: G Bradley
© Globespan PLC 2008

Utilises FormControl classes to manage display of the searchbox & calendars,
as well as handling redirects, autoselection etc.

**************/

FLYG.search=(function(){

	/* set up the search object and copy over the config settings */
	var me={
		isHoliday:false,
		dateCache:{},
		jump:function(url,params){
			var qs=[];
			for (var x in params){
				if (params[x]) qs.push(x+"="+params[x]);
				}
			qs.push("stype="+(this.isHoliday ? 'h' : 'f'));
			window.location=(url.match(/$http/) ? '' : FLYG.Info.pathToRoot)+url+(url.match(/\?/) ? '&' : '?')+qs.join('&');
			}
		};
		
	for (x in searchboxConfig) me[x]=searchboxConfig[x];
	return me;
	
	})();
	
FLYG.ready(function(){
	
	/* first get a shortcut to the search object and add some error handling methods */
	var search=FLYG.search;
	search.isHoliday=search.params.stype=='h';
	search.err={
		control:FLYG.$('search_error'),
		update:function(result){
			if (result==-1){
				this.control[0].innerHTML='You have selected a return date that is before your departure date.';
				this.control.show();
				}
			else if (!result){
				this.control[0].innerHTML='Your departure and return flights are on the same day.';
				this.control.show();
				}
			else this.control.hide();
			},
		hide:function(){
			search.err.control.hide();
			}
		};

	var optSort=function(a){																				// a private function to sort option objects by name
		return a.sort(function(a,b){
			if (a.name<b.name) return -1;
			if (a.name>b.name) return 1;
			return 0;
			});
		};
	
	// create links in the chain and create FormControl instances for each Link
	
	// DIFFERENT OPTIONS FOR DIFFERENT PAGES - SEARCH "pageKicker" TO FIND ALL
	var pageKicker=0;
	if (location.pathname=='/promo/sispins.asp' || location.pathname=='/promo/lasingala.asp'){
		pageKicker = 1;
	} else if(location.pathname=='/promo/easter.asp') {
		pageKicker = 2;
	}
	// END DIFFERENT OPTIONS FOR DIFFERENT PAGES
	var outdepair=new FLYG.FormControls.Link(new FLYG.FormControls.SelectBox('outdepair','From'),'change',[search.err.hide]);
	var outarrair=new FLYG.FormControls.Link(new FLYG.FormControls.SelectBox('outarrair','To'),'change',[search.err.hide]);
	var fclass=new FLYG.FormControls.Link(new FLYG.FormControls.SelectBox('fclass','Class'),'change',[search.err.hide]);
	var outdepdate=new FLYG.FormControls.Link(new FLYG.FormControls.SelectBox('outdepdate','Departing'),'change',[search.err.hide]);
	var retdepdate=new FLYG.FormControls.Link(new FLYG.FormControls.SelectBox('retdepdate','Returning'),'change',[search.err.hide]);
	var pkg=new FLYG.FormControls.Link(new FLYG.FormControls.RadioGroup('package'),'click',[search.err.hide]);
	var submit=new FLYG.FormControls.Link(new FLYG.FormControls.SubmitBttn('submit'),'click',[search.err.hide]);
	
	// now set the order of the links
	outdepair.setSuccessor(outarrair.setSuccessor(fclass.setSuccessor(outdepdate.setSuccessor(retdepdate.setSuccessor(pkg.setSuccessor(submit))))));
	
	/* handle outdepair */
	outdepair.activate=function(){
		var domestic=[], intl=[];
		for (var x in routes){																					// create 2 airport lists
			if (pageKicker!=0){
				if (x=='ABZ'||x=='EDI'||x=='GLA'){
					domestic.push(x);
				}
			}else{
				domestic.push(x);	
			}
			
			if (search.allowReverse){
				routes[x].forEach(function(y){
						if (pageKicker!=0){				
						}else{
							if (y!='ATQ') intl.push(y);															// fix to exclude ATQ from the reverse departures
						}
					});
				}
			}

		domestic=optSort(domestic.unique().map(function(z){														// add in airport names
			return {name:airports[z] ? getAirportName(z,'longName') : '---',value:z||''};
			}));
		intl=optSort(intl.unique().map(function(z){
			return {name:airports[z] ? getAirportName(z,'longName') : '---',value:z||''};
			}));
		this.formControl.populate(domestic.concat(search.allowReverse ? [{name:'---',value:''}] : [],intl));	// populate the control
		if (search.params[this.formControl.id]) this.autoSelect(search.params[this.formControl.id]);			// trigger autoSelect if the associated search parameter exists
		};
	outdepair.handleSelection=function(auto){
		this.formControl.rename();
		var v=this.formControl.getValue();
		this.successor.clear();
		if (!auto && search.redirects[v] && search.redirects[v].outdepair){
			var p=this.collectValues();
			p.outdepair=v;
			search.jump(search.redirects[v].outdepair,p);
			}
		else this.successor.activate();
		};
		
	/* handle outarrair */
	outarrair.activate=function(){
	
		var v=this.collectValues(), list=[];
		if (routes[v.outdepair]) list=routes[v.outdepair];
		else{
			for (var x in routes){		
					if (routes[x].indexOf(v.outdepair)>=0) list.push(x);					
				}
			}
			this.formControl.populate(optSort(list.unique().map(function(x){
				return {name:getAirportName(x,'longName'),value:x};
				})));
	
		if (search.params[this.formControl.id]) this.autoSelect(search.params[this.formControl.id]);
		};
		
	outarrair.handleSelection=function(auto){
		this.formControl.rename();
		var v=this.formControl.getValue();
		this.successor.clear();
		if (!auto && search.redirects[v] && search.redirects[v].outarrair){
			var p=this.collectValues();
			p.outarrair=v;
			search.jump(search.redirects[v].outarrair,p);
			}
		else this.successor.activate();
		};
		
	/* handle class */
	fclass.activate=function(){
		var v=this.collectValues(), wc=this.formControl, c=wc.control;
		if (search.businessClass.indexOf(v.outdepair)>=0 || search.businessClass.indexOf(v.outarrair)>=0){
			if (v.outarrair == "SFB"){
			wc.populate([{name:'Economy',value:'E'},{name:'Business',value:'B'}],true);
			}else
			{
			wc.populate([{name:'Economy',value:'E'},{name:'Business',value:'B'}],true);
			}

			c.show('inline');
			c.parent().show();
			if (search.params[this.formControl.id]) this.autoSelect(search.params[wc.id],1);
			else this.autoSelect('E',1);
			}
		else{
			c.hide();
			c.parent().hide();
			this.successor.activate();
			}
		};
		
	fclass.handleSelection=function(){
		this.formControl.rename(1);
		if (!this.formControl.getValue()) this.successor.clear();
		else this.successor.activate();
		};
		
	fclass.clear=function(){
		this.formControl.control.hide();
		FLYG.FormControls.Link.prototype.clear.call(this);
		};
		
	/* handle outdepdate */
	function trimDayName(str){			
		var a=str.split(" ");
		return [a.shift().substring(0,3)].concat(a).join(" ");
		};
	
	outdepdate.activate=function(){
		var v=this.collectValues(), self=this;
		
		FLYG.FormControls.Link.displayDates=function(d){
			if (!d.out) return;
			search.dateCache[d.outdepair+d.outarrair]=d;
			
			var out=[], ret=[];
			d.out.forEach(function(x){
				if (pageKicker==2){
					if (trimDayName(x.text).substring(7,10)=='Apr' && trimDayName(x.text).substring(4,6)<13) out.push({name:trimDayName(x.text),value:x.value});
					if (trimDayName(x.text).substring(7,10)=='Mar') out.push({name:trimDayName(x.text),value:x.value});
				}else if (pageKicker==1){
					if (trimDayName(x.text).substring(7,10)!='Mar') out.push({name:trimDayName(x.text),value:x.value});					
				}else{
					out.push({name:trimDayName(x.text),value:x.value});
				}
				
				});
			ret.push({name:'One-way flight only',value:'-1'});
			d.ret.forEach(function(x){
				ret.push({name:trimDayName(x.text),value:x.value});
				});
			self.formControl.populate(out);
			if (search.params[self.formControl.id]) self.autoSelect(search.params[self.formControl.id]);
			};
			
		if (search.dateCache[v.outdepair+v.outarrair]) FLYG.FormControls.Link.displayDates(search.dateCache[v.outdepair+v.outarrair]);
		else FLYG.Http.script(FLYG.Info.rootURL+'XML/flights.asp?outdepair='+v.outdepair+'&outarrair='+v.outarrair+'&callback=FLYG.FormControls.Link.displayDates');
		
		};
		
	outdepdate.handleSelection=function(){
		this.formControl.rename();
		var v=this.formControl.getValue();
		if (!v) this.successor.clear();
		else {
			var ret=this.successor.formControl.getValue();
			search.savedRetDate=ret;
			if (ret && ret!='-1') search.err.update((new FLYG.Date(v)).compare(new FLYG.Date(ret)));
			}
		this.successor.activate();
		};
		
	/* handle retdepdate */
	retdepdate.activate=function(){
		var v=this.collectValues(), cache=search.dateCache[v.outdepair+v.outarrair];
		var dt=v.outdepdate.split('/').reverse().join(''), retdates=cache.ret, ret=[], allow=false;
		ret.push({name:'One-way flight only',value:'-1'});
		for (var i=0;i<retdates.length;i++){
			if (!allow){
				if (retdates[i].value.split('/').reverse().join('') > dt) allow=true;
				else continue;
				}
			ret.push({name:trimDayName(retdates[i].text),value:retdates[i].value,selected:(search.savedRetDate && search.savedRetDate==retdates[i].value)});
			}

		this.formControl.populate(ret);
		if (search.savedRetDate) this.formControl.rename();
		this.successor.activate();
		if (search.params[this.formControl.id]) this.autoSelect(search.params[this.formControl.id]);
		};
		
	retdepdate.handleSelection=function(){
		var v=this.formControl.getValue();
		this.formControl.rename(false,v=='-1');
		if (search.isHoliday && !v) this.successor.clear();
		else if (v!='-1') search.err.update((new FLYG.Date(this.collectValues().outdepdate)).compare(new FLYG.Date(v)));
		};
		
	/* handle packages */
	pkg.activate=function(){
	
		var v=this.collectValues();
		if (search.packages[v.outarrair]){
			if (search.packages[v.outarrair].constructor==Array) var pkgList=search.packages[v.outarrair];
			else{
				if (v.outdepdate) var pkgList=search.packages[v.outarrair][getSeason(v.outdepair,v.outarrair,v.outdepdate)];
				else{
					for (var x in search.packages[v.outarrair]){
						 var pkgList=search.packages[v.outarrair][x];
						 break;
						}
					}
				}
			this.formControl.populate(pkgList.length ? pkgList.map(function(x){
				return {name:search.packageLabels[x],value:x};
				}) : [{name:'Flight Only - holiday packages for this flight will be available soon',value:'FO'}]);
			if (search.isHoliday) this.formControl.control.show();
			else this.formControl.control.hide();
			}
		else this.formControl.control.hide();
		if (search.params[this.formControl.id]) this.autoSelect(search.params[this.formControl.id]);	// trigger autoSelect if the associated search parameter exists
		this.successor.activate();
		};
		
	/* handle submit */
	var _submit=function(){document.getElementById('search').submit();};
		
	submit.activate=function(){
		this.formControl.control.addClass('enabled');
		this.formControl.control.click(_submit);
		};
		
	submit.clear=function(){
		this.formControl.control.removeClick(_submit);
		};
	
	/* setup handlers for switching the search type */
	search.handleSearchType=function(t){
	
		this.isHoliday=t=='h';
		var tabs=FLYG.$('searchtype').$byTag('a');
		
		var o=retdepdate.formControl.control[0].options;
			FLYG.$(tabs[0].parentNode).addClass('select');
			FLYG.$(tabs[1].parentNode).removeClass('select');
			FLYG.$('sidebar_atol').removeClass('holiday');
			var l=o.length, si=retdepdate.formControl.control[0].selectedIndex;
			if (outarrair.formControl.getValue()!='ATQ'){								// ATQ fix
				for (var i=l;i>=2;i--){
					o[i]=new Option(o[i-1].text, o[i-1].value, o[i-1].selected);
					}
				o[1]=new Option("One-way flight only","-1");
				if (si) o[si+1].selected=true;
				}
			pkg.formControl.control.hide();
		}
	
	FLYG.$('searchtype').$byTag('a').click(function(e){
		FLYG.Event.handleBubble(e,false);
		this.blur();
		
		FLYG.$('stype')[0].value=this.name;
		if ((this.name=='h' && !search.isHoliday) || (this.name=='f' && search.isHoliday)) search.handleSearchType(this.name);
		
		});

	outdepair.activate();
	
	/* the calendar stuff */
	search.calendar={																	// there's only one calendar required so just create this as a literal rather than from a class
		box:FLYG.$('calendar'),
		month:new FLYG.FormControls.SelectBox('calendar_month'),
		grid:new FLYG.FormControls.Calendar('calendar_grid'),
		activeSelectBox:false,
		blurSelectBox:true
		};
		
	search.calendar.show=function(link,selectedDate){
		var fc=link.formControl;
		if (fc.control[0].options.length<=(search.isHoliday ? 1 : 2)) return;			// quit if there's no dates
		if (selectedDate) d=selectedDate;												// if a date has been passed, use it
		else {
			var d=fc.getValue();														// otherwise get the current value
			if (!d || d=='-1'){															// if its no good, get the first date from the list
				d=(fc.control[0].options[search.isHoliday ? 2 : 2].value);
				}
			}
		
		var m=d.split("/");
		var avail=[], months=[], o=fc.control[0].options, l=o.length;
		for (i=0;i<l;i++){																// loop through dates and pick out available dates / months
			var s=o[i].value.split("/");
			if (s.length==1) continue;
			if (m[1]==s[1] && m[2]==s[2]) avail.push(o[i].value);
			if (months.indexOf(s[1]+"/"+s[2])==-1) months.push(s[1]+"/"+s[2]);
			}
		
		this.grid.populate(d,avail,selectedDate ? false : fc.getValue());				// populate the grid
		var c=fc.control.getCoord()[0];
		this.box.setCoord({x:208,y:c.y-(FLYG.Info.browser()=='IE' ? 13 : 5)});			// position the calendar (offset differs between btowsers)
		
		if (this.activeSelectBox!=link){												// if its a different selectbox, we need to populate the month list too
			this.activeSelectBox=link;
			months=months.map(function(x){
				var z=x.split("/");
				return {name:FLYG.Date.months[FLYG.Info.lang || 'EN'][(z[0]*1)-1]+' '+z[1],value:x};
				});
			this.month.populate(months);
			this.month.setValue(m[1]+'/'+m[2]);
			this.box.show();
			}
		};
		
	search.calendar.hide=function(){
		this.activeSelectBox=false;
		this.box.hide();
		};
		
	search.calendar.grid.control.click(function(e){										// do this whenever the user clicks the grid
		var target=FLYG.Event.target(e);
		if (target.className.match(/avail|current/)){									// if the target element was a date with availability
			var d=target.innerHTML*1;													// construct the full date and set the active select box value
			d= (d<10 ? '0'+d : d)+'/'+search.calendar.month.getValue();
			search.calendar.activeSelectBox.formControl.setValue(d);
			search.calendar.activeSelectBox.handleSelection();
			search.calendar.hide();
			}
		});
		
	search.calendar.month.control.change(function(){									// reload grid when user changes month
		search.calendar.show(search.calendar.activeSelectBox,'01/'+search.calendar.month.getValue());
		this.blur();
		});
		
	var cl=function(){search.calendar.hide()};
		
	outdepdate.formControl.control.focus(function(x){									// show calendar when user focuses on outdepdate
		search.calendar.show(outdepdate);
		FLYG.search.err.control.hide();
		}).change(function(){															// hide calendar when user changes outdepdate
		cl();
		this.blur();
		});
		
	retdepdate.formControl.control.focus(function(x){									// repeat for retdepdate
		search.calendar.show(retdepdate);
		FLYG.search.err.control.hide();
		}).change(function(){
		cl();
		this.blur();
		});
		
	[outdepair,outarrair,fclass].forEach(function(x){									// hide calendar when focus placed on Links above the dates
		x.formControl.control.focus(cl);
		});
		
	FLYG.$('close').click(cl);															// finally hide when user clicks on the close button
	
	});