/* 
 * A QSF widget
 * Revision : $Id: jquery.ui.qsf.js,v 1.11 2011/03/23 12:18:12 zdravkosh Exp $
 */

(function($) {
	/* global private variables */
	/**
	 * @private
	 */
	var tabType;
	/**
	 * @private
	 */
	var advancePurchase;
	var actionUrl ='http://www.travelfos.gr/index.php';

	$.widget("ui.qsf",
	{
		options : {
			qsfType : 'horizontal',
			psgrsMax : 9,
			agentUrl : {
				protocol : 'http',
				server : 'test1',
				version : 'ibe',
				agentid : {
					flights : 'travelfos',
					flightHotel : 'travelfos'
				},
				cgi : 'runhttl',
				getFullAgentUrl : function(agentidType, newCgi) {
					var cgi = this.cgi;

					if (newCgi) {
						cgi = newCgi;
					}
					return this.protocol + '://' + this.server + '/' + this.version+ '/' + this.agentid[agentidType] + '/' + cgi;
				}
			},
			displayLevel : 'full',
			acLang : 'en',
			qsfLanguage : 'en',
			tsmHotels : {
				geonameid : '',
				hotelid : '',
				addForHotDynpkgs : false,
				advancePurchase : 0,
				hotelLocation : {
					fullName : '',
					IATACode : ''
				}
			},
			flights : {
				advancePurchase : 2,
				minResPeriod : 0,
				useSuggestions : true,
				useAnalyticsTracker : false
			},
			hotels : {
				advancePurchase : 0,
				minResPeriod : 0,
				useSuggestions : true,
				hotelProviders : []
			},
			cars : {
				advancePurchase : 0,
				minResPeriod : 0,
				useSuggestions : true
			},
			flightHotel : {
				advancePurchase : 2,
				minResPeriod : 0,
				useSuggestions : true
			},
			flightCar : {
				advancePurchase : 0,
				minResPeriod : 0,
				useSuggestions : true
			},

			creditCardCurrency : 'EUR', // put empty string to
			// disable the "Credit
			// Card Currency" field
			debug : false,
			dateFormat: 'dd/mm/yy'
		},

		_create : function() {
			this.option(this.options);

			var self = this, $qsf = this.widget();

			var $tabs = $qsf.children('div');
			self._createTabs($qsf);

			$tabs.each(function(index, tab) {
				var $tab = $(tab);
				var tabId = $tab.attr('id');

				if (tabId == 'tabFlights') {
					self._createFlightsTab($tab);
				}

				if (tabId == 'tabHotels') {
					self._createHotelsTab($tab);
				}
				if (tabId == 'tabTsmHotels') {
					self._createTsmHotelsTab($tab);
				}
				if (tabId == 'tabCars') {
					self._createCarsTab($tab);
				}

				if (tabId == 'tabFlightsHotel') {
					self._createFlightHotelTab($tab);
				}

				if (tabId == 'tabFlightsCar') {
					self._createFlightCarTab($tab);
				}
			});
		},

		_init : function() {
			var self = this, o = this.options, $qsf = this.widget();

			var $tabs = $qsf.children('div');
			var $fullMode = $tabs.find('.full');

			self._addTooltips($tabs);

			if ('simple' == o.displayLevel) {
				$tabs.find('.advanced').hide();
				$fullMode.hide();
			} else if ('advanced' == o.displayLevel) {
				$fullMode.hide();
			}
		},

		_createBaseTab : function($tab, fromAc, fromH, fromIataCode, dp_outDay,
				dp_outMonth, datepicker_arr, toAc, toH, toIataCode, dp_retDay,
				dp_retMonth, datepicker_ret, geonameid, hotelid) {
			var o = this.options;
			var $form = $tab.find('form');
			var $advSearchLink = $form.find('a.advanced-search-link');
			var fields = {
				$fromCityAc : $form.find(fromAc),
				$fromcityH : $form.find(fromH),
				$from_iata_code_is_used : $form.find(fromIataCode),
				$outDay : $form.find(dp_outDay),
				$outMonth : $form.find(dp_outMonth),
				$toCityAc : $form.find(toAc),
				$tocityH : $form.find(toH),
				$to_iata_code_is_used : $form.find(toIataCode),
				$retDay : $form.find(dp_retDay),
				$retMonth : $form.find(dp_retMonth),
				$datepicker_arr : $form.find(datepicker_arr),
				$datepicker_ret : $form.find(datepicker_ret),
				$form : $form,
				$advSearchLink : $advSearchLink,
				$hotelid : $form.find(hotelid),
				$geonameid : $form.find(geonameid)
			};

			if (o.debug && window.console) {
				console.info($tab.attr('id'), fields);
			}

			return fields;
		},

		_createFlightsTab : function($tab) {
			var self = this, o = this.options;
			var flightTabFields = self._createBaseTab($tab, '#fromcityAc',
					'#fromcityH', '#from_iata_code_is_used', '#dp_OutDayhFlights',
					'#dp_OutMonthFlights', '#datepicker_arr', '#tocityAc',
					'#tocityH', '#to_iata_code_is_used', '#dp_RetDayhFlights',
					'#dp_RetMonthFlights', '#datepicker_ret');

			tabType = 'flights';
			advancePurchase = o.flights.advancePurchase;

			var formUrl = o.agentUrl.getFullAgentUrl(tabType);
			var advSearchLinkHref = o.agentUrl.getFullAgentUrl(tabType, 'porch');

			flightTabFields.$advSearchLink.attr("href", advSearchLinkHref);
			//flightTabFields.$form.attr('action', formUrl);
			flightTabFields.$form.attr('action', actionUrl);

			if (o.flights.useSuggestions) {
				self._initAirAc($tab, flightTabFields);
			}

			if (o.flights.useAnalyticsTracker) {
				self._addTrackerParamsField(flightTabFields.$form);
			}

			self._initPassengersCountCheck($tab);
			self._setTripType($tab);
			self._initDatePickerField(flightTabFields, o.flights.minResPeriod);
			self._addOnSubmit(flightTabFields);
			self._addFlightsValidation(flightTabFields,
					self._errorMsgs[o.qsfLanguage].flights);
		},

		_createHotelsTab : function($tab) {
			var self = this, o = this.options;

			var hotelTabFields = self._createBaseTab($tab, '', '', '',
					'#dp_cindayH', '#dp_cinmonthH', '#datepicker_cinH', '#hotcity',
					'', '', '#dp_cotdayH', '#dp_cotmonthH', '#datepicker_cotH',
					'#geonameid_h');

			tabType = 'hotels';
			advancePurchase = o.hotels.advancePurchase;

			var formUrl = o.agentUrl.getFullAgentUrl(tabType, 'runhttl');
			var advSearchLinkHref = o.agentUrl.getFullAgentUrl(tabType, 'porch');

			hotelTabFields.$form.attr('action', formUrl);
			hotelTabFields.$advSearchLink.attr("href", advSearchLinkHref);

			if (o.hotels.useSuggestions) {
				self._initHotelAc($tab, hotelTabFields);
			}

			self._initDatePickerField(hotelTabFields, o.hotels.minResPeriod);
			self._addHotelsValidation(hotelTabFields,
					self._errorMsgs[o.qsfLanguage].hotels);
		},

		_createTsmHotelsTab : function($tab) {
			var self = this, o = this.options;

			var hotelTabFields = self._createBaseTab($tab, '', '', '',
					'#dp_cindayTsmH', '#dp_cinmonthTsmH', '#datepicker_cinTsmH',
					'', '', '', '#dp_cotdayTsmH', '#dp_cotmonthTsmH',
					'#datepicker_cotTsmH', '#geonameid_Tsmh', '#hotelid_Tsmh');

			tabType = 'hotelsTsm';
			advancePurchase = o.tsmHotels.advancePurchase;

			var formUrl = o.agentUrl.getFullAgentUrl(tabType, 'runhttl');
			var advSearchLinkHref = o.agentUrl.getFullAgentUrl(tabType, 'porch');

			hotelTabFields.$form.attr('action', formUrl);
			hotelTabFields.$advSearchLink.attr('href', advSearchLinkHref);

			hotelTabFields.$geonameid.val(o.tsmHotels.geonameid);
			hotelTabFields.$hotelid.val(o.tsmHotels.hotelid);

			self._initDatePickerField(hotelTabFields, o.tsmHotels.minResPeriod);
			self._addHotelsValidation(hotelTabFields,
					self._errorMsgs[o.qsfLanguage].hotels, true);
		},

		_createCarsTab : function($tab) {
			var self = this, o = this.options;

			var carsTabFields = self._createBaseTab($tab, '#pupcityAc',
					'#pupcityH', '#from_iata_code_is_used_cars', '#dp_pupdayC',
					'#dp_pupmonthC', '#datepicker_pup', '', '', '', '#dp_doffdayC',
					'#dp_doffmonthC', '#datepicker_doff');

			tabType = 'cars';
			advancePurchase = o.cars.advancePurchase;

			var formUrl = o.agentUrl.getFullAgentUrl(tabType, 'runhttl');
			var advSearchLinkHref = o.agentUrl.getFullAgentUrl(tabType, 'porch');

			carsTabFields.$form.attr('action', formUrl);
			carsTabFields.$advSearchLink.attr("href", advSearchLinkHref);

			if (o.cars.useSuggestions) {
				self._initCarAc($tab, carsTabFields);
			}

			self._initCreditCardCurrency($tab);
			self._initDatePickerField(carsTabFields, o.cars.minResPeriod);
			self._addCarsValidation(carsTabFields,
					self._errorMsgs[o.qsfLanguage].cars);
		},

		_createFlightHotelTab : function($tab) {
			var self = this, o = this.options;

			var flightTabFields = self._createBaseTab($tab, '#fromcityAcFH',
					'#fromcityHFH', '#from_iata_code_is_used_FH', '#dp_outdayFH',
					'#dp_OutMonthFH', '#datepicker_arr_fh', '#tocityAcFH',
					'#tocityHFH', '#to_iata_code_is_used_fh', '#dp_retdayFH',
					'#dp_retmonthFH', '#datepicker_ret_fh');

			var hotcity = self._createBaseTab($tab, null, null, null, null, null, null, '#hotcity',
					null, null,null,null,null, '#geonameid_h');

			tabType = 'flightHotel';
			advancePurchase = o.flightHotel.advancePurchase;

			var formUrl = o.agentUrl.getFullAgentUrl(tabType);
			var advSearchLinkHref = o.agentUrl.getFullAgentUrl(tabType, 'porch');

			flightTabFields.$advSearchLink.attr("href", advSearchLinkHref);
			//flightTabFields.$form.attr('action', formUrl);
			flightTabFields.$form.attr('action', actionUrl);

			if (o.flightHotel.useSuggestions) {
				self._initHotelAc($tab, hotcity);
				self._initAirAc($tab, flightTabFields);
			}

			if (o.tsmHotels.addForHotDynpkgs) {
				flightTabFields.$toCityAc.val(o.tsmHotels.hotelLocation.fullName)
						.attr('readonly', 'readonly');
				flightTabFields.$tocityH.val(o.tsmHotels.hotelLocation.IATACode);
				flightTabFields.$to_iata_code_is_used.val('Y');
			}

			self._initPassengersCountCheck($tab);
			self._setTripType($tab);
			self._initDatePickerField(flightTabFields, o.flightHotel.minResPeriod);
			self._addOnSubmit(flightTabFields);
			self._addFlightsHotelValidation(flightTabFields, self._errorMsgs[o.qsfLanguage].flightshotel);
		},
		_createFlightCarTab : function($tab) {
			var self = this, o = this.options;

			var flightTabFields = self._createBaseTab($tab, '#fromcityAcFC',
					'#fromcityHFC', '#from_iata_code_is_used_fc', '#dp_outdayFC',
					'#dp_OutMonthFC', '#datepicker_cf_arr', '#tocityAcFC',
					'#tocityHFC', '#to_iata_code_is_used_fc', '#dp_retdayFC',
					'#dp_retmonthFC', '#datepicker_cf_ret');

			tabType = 'flightCar';
			advancePurchase = o.flightCar.advancePurchase;

			var formUrl = o.agentUrl.getFullAgentUrl(tabType);
			var advSearchLinkHref = o.agentUrl.getFullAgentUrl(tabType, 'porch');

			flightTabFields.$advSearchLink.attr("href", advSearchLinkHref);
			flightTabFields.$form.attr('action', formUrl);

			if (o.flightCar.useSuggestions) {
				self._initAirAc($tab, flightTabFields);
			}

			self._initPassengersCountCheck($tab);
			self._setTripType($tab);
			self._initDatePickerField(flightTabFields, o.flightCar.minResPeriod);
			self._addFlightsValidation(flightTabFields,
					self._errorMsgs[o.qsfLanguage].flights);
		},

		_errorMsgs : {
			en : {
				hotels : {
					invalidPickUpCity : "No city/airport specified.\n",
					invalidPickUpDate : "You have selected an invalid check in date.\n",
					invalidDropOffDate : "You have selected an invalid check-out date.\n",
					invalidPickUpMore11 : "The check-in date cannot be more than 11 months in the future.\n",
					invalidDropOffMore11 : "The check-out date cannot be more than 11 months in the future.\n",
					invalidDropOffBeforePickUp : "The departure date should be before the return date.\n",
					invalidSelectRoom : "Please select room type.\n",
					invalidRoomFirst : "Please select number of rooms first!\n",
					// TODO to add the correct geonameid message
					invalidGeonameId : "Invalid geonameid",
					invalidHotelId : "Invalid hotelid"
				},
				cars : {
					invalidPickUpCity : "You have selected an invalid pick-up city/airport.\n",
					invalidPickUpDate : "You have selected an invalid pick-up date.",
					invalidDropOffDate : "You have selected an invalid drop-off date.\n",
					invalidPickUpMore11 : "The pick-up date cannot be more than 11 months in the future.\n",
					invalidDropOffMore11 : "The drop-off date cannot be more than 11 months in the future.\n",
					invalidDropOffBeforePickUp : "The pick-up date should be before the drop-of date.\n"
				},
				flights : {
					invalidPickUpDate : "You have selected an invalid departure date.\n",
					invalidDropOffDate : "You have selected an invalid return date.\n",
					invalidPickUpCity : "Travel origin not specified. Please enter city name or airport code. \n",
					invalidDropOffCity : "Travel destination not specified. Please enter city name or airport code. \n",
					invalidDropOffBeforePickUp : "The departure date should be before the return date \n",
					invalidPickUpMore11 : "The departure date cannot be more than 11 months in the future. \n",
					invalidDropOffMore11 : "The return date cannot be more than 11 months in the future. \n"
				},
				flightshotel : {
					invalidPickUpCity : "Travel origin not specified. Please enter city name or airport code. \n",
					invalidDropOffCity : "Travel destination not specified. Please enter city name or airport code. \n",
					invalidDropOffBeforePickUp : "The departure date should be before the return date \n",
					invalidPickUpMore11 : "The departure date cannot be more than 11 months in the future. \n",
					invalidDropOffMore11 : "The return date cannot be more than 11 months in the future. \n"
				},
				flightscars : {
					invalidPickUpCity : "Travel origin not specified. Please enter city name or airport code.\n",
					invalidDropOffCity : "Travel destination not specified. Please enter city name or airport code. \n",
					invalidPickUpDate : "You have selected an invalid pick-up date.",
					invalidDropOffDate : "You have selected an invalid drop-off date.\n",
					invalidPickUpMore11 : "The pick-up date cannot be more than 11 months in the future.\n",
					invalidDropOffMore11 : "The drop-off date cannot be more than 11 months in the future.\n",
					invalidDropOffBeforePickUp : "The pick-up date should be before the drop-of date.\n"
				}
			}
		},
		/**
		 * @param jQueryDomObj
		 *			A collection with input elements
		 * @param Function
		 *			Provides advanced markup for an item
		 * @param Function
		 * @param Function
		 *			Extra parameters for the backend.
		 * @param Function
		 *			Handle the result of a search event.
		 * @param Object
		 *			A collection with addtional events
		 * @param Boolean
		 *			Activates and deactivates autofill option
		 */
		_initAc : function(acFields, formatItemFunc, parseFunc, extraParamsObj,
				resultFunc, events, autofill) {
			var o = this.options, self = this;
			var url;

			if (extraParamsObj.type == 'air') {
				url = o.agentUrl.getFullAgentUrl(tabType, 'airsearchlocation');
			}

			if (extraParamsObj.type == 'hotel') {
				url = o.agentUrl.getFullAgentUrl(tabType, 'hotsearchlocation');
			}

			acFields.autocomplete(url, {
				autoFill : (autofill) ? true : false,
				scroll : false,
				clearCustomInput : false,
				delay : 15,
				width : 280,
				max : 10,
				minChars : 2,
				formatItem : formatItemFunc,
				parse : parseFunc,
				extraParams : extraParamsObj,
				dataType : 'jsonp'
			}).result(function(e, item, formated, check) {
				self._putTxtCursorBeforeTextIE(this);
				resultFunc(e, item, formated, check);
			});

			if (events) {
				$.each(events, function(eventName, action) {
					acFields.bind(eventName, action);
				});
			}
		},

		_initAirAc : function($tab, flightTabFields) {
			var self = this, o = this.options;

			var $acFields = $([]).pushStack(
					[ flightTabFields.$fromCityAc.get(0),
							flightTabFields.$toCityAc.get(0) ]);

			tabType = 'flights';
			var formatItem = function(data, i, n, value) {
				return data.displayname;
			};

			var parse = function(data) {
				return $.map(data, function(row) {
					return {
						data : row,
						value : row.displayname,
						result : row.displayname
					};
				});
			};

			var extraParams = {
				'lang' : o.acLang,
				'type' : 'air'
			};

			var resultFunc = function(e, item, formated, check) {
				if (/^fromcityAc/.test(e.target.id)) {
					flightTabFields.$fromcityH.val(item.code);
					flightTabFields.$from_iata_code_is_used.val('Y').attr('name',
							'from_iata_code_is_used');

				} else if (/^tocityAc/.test(e.target.id)) {
					flightTabFields.$tocityH.val(item.code);
					flightTabFields.$to_iata_code_is_used.val('Y').attr('name',
							'to_iata_code_is_used');
				}
			};

			self._initAc($acFields, formatItem, parse, extraParams, resultFunc);
		},

		_initHotelAc : function($tab, ff) {
			var self = this, o = this.options;
			var $acFields = ff.$toCityAc;

			var formatItem = function(data, i, n, value) {
				return data.name + ((data.area_name) ? ', ' + data.area_name : '')
						+ ', ' + ((data.country) ? data.country : data.countrycode);
			};

			var parse = function(data) {
				return $.map(data, function(row) {
					return {
						data : row,
						value : row.name,
						result : row.name
								+ ((row.area_name) ? ', ' + row.area_name : '')
								+ ', '
								+ ((row.country) ? row.country : row.countrycode)
					};
				});
			};

			var extraParams = {
				'lang' : o.acLang,
				provider : o.hotels.hotelProviders,
				'type' : 'hotel'
			};

			var resultFunc = function(e, item, formated, check) {
				ff.$geonameid.val(item.geoname_id);
			};

			var keyUpFunc = function(evt, request, settings) {
				if ((evt.keyCode >= 48 && evt.keyCode <= 90) || evt.keyCode === 0) {
					ff.$geonameid.val("");
				}

				if (evt.keyCode == 8) {
					if (!this.value.length) {
						ff.$geonameid.val("");
					}
				}
			};
			var blurFunc = function() {
				if (!ff.$geonameid.val()) {
					this.value = '';
				}
			};
			var events = {
				'keyup' : keyUpFunc,
				'blur' : blurFunc
			};
			self._initAc($acFields, formatItem, parse, extraParams, resultFunc,
					events, true);
		},
		_initCarAc : function($tab, ff) {
			var self = this, o = this.options;
			var $acFields = ff.$fromCityAc;

			var formatItem = function(data, i, n, value) {
				return data.displayname;
			};

			var parse = function(data) {
				return $.map(data, function(row) {
					return {
						data : row,
						value : row.displayname,
						result : row.displayname
					};
				});
			};

			var extraParams = {
				'lang' : o.acLang,
				'type' : 'air'
			};

			var resultFunc = function(e, item, formated, check) {
				if ('pupcityAc' == e.target.id) {
					ff.$fromcityH.val(item.code);
					ff.$from_iata_code_is_used.val('Y').attr('name',
							'from_iata_code_is_used');
				}
			};

			self._initAc($acFields, formatItem, parse, extraParams, resultFunc);
		},

		_createTabs : function($qsfConteiner) {
			var $tabs = $qsfConteiner.tabs();

			if (this.options.qsfType == 'vertical') {
				var tabs_lenght = $tabs.tabs('length');
				var $tabs_ul = $tabs.find('ul:first');
				var selector = 'li';

				if (tabs_lenght % 2) {
					selector = 'li:lt(' + (tabs_lenght - 1) + ')';
					$tabs_ul.find('li:last').width('98%');
				}

				$tabs_ul.find(selector).addClass('qsf-two-columns-tabs');
			}
		},
		_elevenMonthsPeriod : function(dateObj) {
			var tmpDate = new Date();
			tmpDate.setMonth(tmpDate.getMonth() + 11);
			return (dateObj < tmpDate);
		},

		_exportToDateObject : function($dayField, $monthField) {
			var day = $dayField.val();
			var month = $monthField.val();

			var advPurchDate = new Date();
			advPurchDate.setDate(advPurchDate.getDate() + advancePurchase);

			var date = new Date();
			date.setMonth(month, day);

			if (day != date.getDate() || month != date.getMonth()) {
				return null;
			} else {
				if (date < advPurchDate) {
					date.setFullYear(advPurchDate.getFullYear() + 1);
				}
				// TODO: Should be added support for leap year in the following calculation
				advPurchDate.setDate(advPurchDate.getDate() + 365);

				if( (date >= advPurchDate) ) {
					date.setFullYear(year - 1, month, day);
				}
				
				return date;
			}
		},

		_importFromDateObject : function($dayField, $monthField, $fullDateField, dateObj) {
			var o = this.options;
			
			$dayField.val(dateObj.getDate());
			$monthField.val(dateObj.getMonth());
			$fullDateField.val($.datepicker.formatDate(o.dateFormat, dateObj));
		},

		_setDateSelectors : function($dayField, $monthField, $fullDateField) {
			var self = this;
			var date = new Date();

			date.setDate(date.getDate() + advancePurchase);
			self._importFromDateObject($dayField, $monthField, $fullDateField, date);
		},

		_initDatePickerField : function(ff, minResPeriod) {
			var self = this, o = this.options;
			var $dpPlaceHolders = $([]).pushStack(
					[ ff.$datepicker_arr.get(0), ff.$datepicker_ret.get(0) ]);
			var $daysObjs = self._getDaysObjs();
			var selectedDate;

			var $outDayMonthArr = $([]).pushStack([ ff.$outMonth.get(0), ff.$outDay.get(0)]);
			var $retDayMonthArr = $([]).pushStack([ ff.$retMonth.get(0), ff.$retDay.get(0)]);
			
			$outDayMonthArr.change(function(e) {
				var dropDownsDate = self._exportToDateObject(ff.$outDay, ff.$outMonth);
				var newCalDate = $.datepicker.formatDate(o.dateFormat, dropDownsDate);
				
				if(/month/i.test(e.target.name)){
					self._setMonthDaysNumber(e.target.value, ff.$outDay, $daysObjs);
					ff.$retMonth.val(ff.$outMonth.val());
				}
				
				if(/day/i.test(e.target.name)){
					ff.$retDay.val(dropDownsDate.getDate() + minResPeriod);
				}
				
				ff.$datepicker_arr.val(newCalDate);
				ff.$retMonth.triggerHandler('change');   
			});

			$retDayMonthArr.change(function(e) {
				var dropDownsDate = self._exportToDateObject(ff.$retDay, ff.$retMonth);
				var newCalDate = $.datepicker.formatDate(o.dateFormat, dropDownsDate);

				if(/month/i.test(e.target.name)){
					self._setMonthDaysNumber(e.target.value, ff.$retDay, $daysObjs);
				}
				
				ff.$datepicker_ret.val(newCalDate);
			});

			$($dpPlaceHolders).datepicker(
					{
						showAnim : false,
						inline : true,
						showOn : 'both',
						buttonText : '&nbsp;',
						minDate : "+" + advancePurchase,
						maxDate : "+10m +4w",
						dateFormat: o.dateFormat,
						onSelect : function(dateText, inst) {
							selectedDate = $.datepicker.parseDate(o.dateFormat, dateText);
							// here we check if this is the departure calendar
							if ($dpPlaceHolders.index(inst.input) === 0) {
								self._importFromDateObject(
										ff.$outDay, ff.$outMonth, 
										ff.$datepicker_arr, selectedDate);
								selectedDate.setDate(selectedDate.getDate() + minResPeriod);   
							}
							self._importFromDateObject(
									ff.$retDay, ff.$retMonth, 
									ff.$datepicker_ret, selectedDate);
						}
					});

			self._setDateSelectors(ff.$outDay, ff.$outMonth, ff.$datepicker_arr);
			self._setDateSelectors(ff.$retDay, ff.$retMonth, ff.$datepicker_ret);

			ff.$form.find('.ui-datepicker-trigger').addClass('ui-corner-all ui-icon');
		},
		// TODO add numpts to base tab object?
		_initPassengersCountCheck : function($tabFlights) {

			var o = this.options;
			var $numptcDropDown = $tabFlights.find("select[name^='numptc']");

			$numptcDropDown.change(function(event) {
				var passengersNum = 0;
				$numptcDropDown.find("option:selected").each(
						function(index, option) {
							passengersNum += parseInt($(option).val(), 10);
						});
				if (o.psgrsMax < passengersNum) {
					alert('Too many passengers. The maximum number is: '
							+ o.psgrsMax);
					$(event.target).val('0');
				}
			});
		},

		_addHotelsValidation : function(ff, hotelErrorMsgs, isTsmHotels) {
			var self = this, o = this.options;
			var rTypeOk;
			var $roomNumsTypesHotel = ff.$form.find('#roomNumsTypesHotel'), $roomTypes = self
					._getRoomTypes($roomNumsTypesHotel), $roomNums = self
					._getRoomNums($roomNumsTypesHotel);

			ff.$form.submit(function(event) {
				var errorMsg = self._addFormValidationDefRulls(ff, hotelErrorMsgs);

				$roomTypes.each(function(i, $roomType) {
					if ($roomType.value !== '') {
						rTypeOk = 'ok';
					}
				});

				if (rTypeOk != 'ok') {
					errorMsg += hotelErrorMsgs.invalidSelectRoom;
				}

				if (o.useHotelSuggestions && !ff.$geonameid.val()) {
					errorMsg += hotelErrorMsgs.invalidGeonameId;
				}

				if (ff.$hotelid.length && !ff.$hotelid.val()) {
					errorMsg += hotelErrorMsgs.invalidHotelId;
				}

				if (errorMsg !== "") {
					alert(errorMsg);
					return false;
				} else {
					return true;
				}
			});

			$roomTypes.change(function() {
				var index = $roomTypes.index(this);
				var $numSelector = $roomNums.eq(index);
				var num_rooms = parseInt($numSelector.val(), 10);

				if (!num_rooms) {
					if ($(this).val() !== "") {
						alert(hotelErrorMsgs.invalidRoomFirst);
						$numSelector.focus();
					}
				}
			});
		},
		_getRoomTypes : function($parent) {
			return $parent
					.find("select[name^='roomtype']:not([name^='roomtypenum'])");
		},

		_getRoomNums : function($parent) {
			return $parent.find("select[name^='roomtypenum']");
		},

		_addCarsValidation : function(ff, hotelErrorMsgs) {
			var self = this;

			ff.$form.submit(function(event) {
				var errorMsg = self._addFormValidationDefRulls(ff, hotelErrorMsgs);

				if (errorMsg !== "") {
					alert(errorMsg);
					return false;
				} else {
					return true;
				}
			});
		},
		/**
		 * 
		 * @param ff
		 *			Object Form fields Object
		 */
		_addFlightsValidation : function(ff, flightsErrorMsgs) {
			var self = this;

			ff.$form
					.submit(function(event) {
						var errorMsg = self._addFormValidationDefRulls(ff,
								flightsErrorMsgs);
						var isToCityAcExist = (ff.$toCityAc.length !== 0), isToCityAcEmpty = ff.$toCityAc
								.val() === '';

						if (isToCityAcExist && isToCityAcEmpty) {
							errorMsg += flightsErrorMsgs.invalidDropOffCity;
						}

						if (errorMsg !== "") {
							alert(errorMsg);
							return false;
						} else {
							return true;
						}
					});
		},
		_addFlightsHotelValidation : function(ff, flightsErrorMsgs) {
			var self = this;

			ff.$form.submit(function(event) {

				var errorMsg = self._addFormValidationDefRulls(ff, flightsErrorMsgs);

				if (ff.$form.find('input[name="tocity"]').val() === "") {
					errorMsg += flightsErrorMsgs.invalidDropOffCity;
				}

				if (errorMsg !== "") {
					alert(errorMsg);
					return false;
				} else {
					return true;
				}
			});
		},

		_addFormValidationDefRulls : function(ff, eMsgs) {
			var self = this;
			var errorMsg = "";
			var isFromCityAcExist = (ff.$fromCityAc.length !== 0), isFromCityAcEmpty = ff.$fromCityAc
					.val() === '';

			if (isFromCityAcExist && isFromCityAcEmpty) {
				errorMsg += eMsgs.invalidPickUpCity;
				ff.$fromCityAc.focus();
			}

			var outDate = self._exportToDateObject(ff.$outDay, ff.$outMonth);

			if (!outDate) {
				errorMsg += eMsgs.invalidPickUpDate;
			}

			var retDate = self._exportToDateObject(ff.$retDay, ff.$retMonth);

			if (!retDate) {
				errorMsg += eMsgs.invalidDropOffDate;
			}

			if (outDate && retDate) {

				if (!self._elevenMonthsPeriod(outDate)) {
					errorMsg += eMsgs.invalidPickUpMore11;
				}

				if (!self._elevenMonthsPeriod(retDate)) {
					errorMsg += eMsgs.invalidDropOffMore11;
				}

				if (outDate > retDate) {
					errorMsg += eMsgs.invalidDropOffBeforePickUp;
				}
			}



			return errorMsg;
		},

		_addTrackerParamsField : function($form) {
			var newTrackerUrl = pageTracker._getLinkerUrl($form.attr('action'));
			var trackerParams = newTrackerUrl.split('?')[1];
			var $hiddenField = $('<input type="hidden" name="keytrack"').val(
					escape(trackerParams));
			$form.appendChild($hiddenField);
		},
		_addTooltips : function($tabs) {
			$tabs.find('.info').tooltip({
				track : true,
				extraClass : 'ui-corner-all ui-state-highlight',
				delay : 20,
				top : -5,
				left : 20
			});
		},
		/**
		 * This function manage the autocompleter fields
		 * 
		 * @param ff Object Form fields Object
		 */
		_addOnSubmit : function(ff) {
			ff.$form.submit(function(event) {
				if (ff.$fromCityAc.val().slice(0, 3) != ff.$fromcityH.val()) {
					ff.$fromcityH.val(ff.$fromCityAc.val());
					ff.$from_iata_code_is_used.removeAttr('name');
				}

				if (ff.$toCityAc.val().slice(0, 3) != ff.$tocityH.val()) {
					ff.$tocityH.val(ff.$toCityAc.val());
					ff.$to_iata_code_is_used.removeAttr('name');
				}

				if(ff.$form.find('#dp_OutMonthH')){
					ff.$form.find('#dp_OutMonthH').val(ff.$outMonth.val());
					ff.$form.find('#dp_OutDayH').val(ff.$outDay.val());
					ff.$form.find('#dp_RetMonthH').val(ff.$retMonth.val());
					ff.$form.find('#dp_RetDayH').val(ff.$retDay.val());
				}

				ff.$fromCityAc.removeAttr('name');
				ff.$toCityAc.removeAttr('name');
			});
		},

		_putTxtCursorBeforeTextIE : function(txtInputObj) {
			if (txtInputObj.createTextRange) {
				var range = txtInputObj.createTextRange();
				range.move("character", 0);
				range.select();
			}
		},

		_getDaysObjs : function() {
			var daysArr = [];

			for (i = 1; i <= 31; i++) {
				daysArr.push('<option value="' + i + '">' + i + '</option>');
			}

			return $(daysArr.join(''));
		},

		_setMonthDaysNumber : function(selMonthNum, $daySelObj, $daysList) {
			var februaryDays;
			var date = new Date();
			var thisYear = date.getFullYear();

			if(selMonthNum < date.getMonth()){
				++thisYear;
			}

			if ((thisYear % 4) && ((thisYear % 100 !== 0) || (thisYear % 400 === 0))) {
				februaryDays = 28;
			} else {
				februaryDays = 29;
			}

			var monthsDaysArr = [ 31, februaryDays, 31, 30, 31, 30, 31, 31, 30, 31,
					30, 31 ];
			var daysToAdd = monthsDaysArr[selMonthNum];
			var $slicedDays = $($daysList.slice(0, daysToAdd));
			var tmpDay = $daySelObj.val();

			$daySelObj.children().remove();
			$daySelObj.append($slicedDays.clone());
			$daySelObj.val(tmpDay);
		},

		setLanguage : function(lngObj) {
			var self = this;
			self._errorMsgs = lngObj;
		},

		_setTripType : function($tab) {
			var o = this.options;
			var $retDateTimeSelectors = $tab.find('.retDateTimeSelectors');
			var $tripTypeField = $tab.find("select[name='triptype']");

			$tripTypeField.change(function(event) {
				if ('ONEWAY' == event.target.value) {
						$retDateTimeSelectors.hide();
				} else {
					$retDateTimeSelectors.show();
				}
			});

			if ($tripTypeField.val() == 'ONEWAY') {
				$tripType.change();
			}
		},

		_initCreditCardCurrency : function($tab) {
			var o = this.options;
			var $ccCurrencyFields = $tab.find("select[name='cccardcurrency']");

			if (o.creditCardCurrency !== '') {
				$ccCurrencyFields.each(function(index) {
					$tab.val(o.creditCardCurrency);
				});
			} else {
				$ccCurrencyFields.each(function(index) {
					$tab.closest('.simple').hide();
				});
			}
		}
	});
}(jQuery));

