/* ---------- VARIABLES ---------- */
var cl_OK = 'ok';
var cl_Error = 'error';
var cl_OmitError = 'error-omit';

Date.dayNames = ['Niedziela', 'Poniedziałek', 'Wtorek', 'Środa', 'Czwartek', 'Piątek', 'Sobota'];
Date.abbrDayNames = ['Nd', 'Pn', 'Wt', 'Śr', 'Cz', 'Pt', 'So'];
Date.monthNames = ['Styczeń', 'Luty', 'Marzec', 'Kwiecień', 'Maj', 'Czerwiec', 'Lipiec', 'Sierpień', 'Wrzesień', 'Październik', 'Listopad', 'Grudzień'];
Date.abbrMonthNames = ['Sty', 'Lut', 'Mar', 'Kwi', 'Maj', 'Cze', 'Lip', 'Sie', 'Wrz', 'Paź', 'Lis', 'Gru'];
Date.format = "yyyy-mm-dd";
Date.firstDayOfWeek = 1;

var cal_info = "Informacja\nRezerwacje on-line możliwe są na 2 dni w przód od dzisiejszej daty. W celu rezerwacji na dni wcześniejsze prosimy o kontakt z Infolinią pod numerem telefonu:\n0 300 103 111";
var cal_text = {NEXT:'Następny miesiąc',PREV:'Poprzedni miesiąc',THISMONTH:'Obecny m-c',CLOSE:'Zamknij'};

var TXT_TIP_Lowcost = "Wybrane połączenie jest obsługiwane przez jedną z tanich linii lotniczych. W przypadku jakichkolwiek wątpliwości, prosimy o kontakt z naszą Infolinią pod numerem telefonu 0 300 103 111.";
var TXT_TIP_Overnight = "Lot typu &quot;Overnight&quot; oznacza, że lądowanie samolotu następuje dnia następnego niż dzień wylotu, wedle czasu lokalnego.";
var TXT_TIP_CityChanged = "Proszę zwrócić uwagę na zmianę lotniska w stosunku do zadanych kryteriów wyszukiwania.";
var TXT_PRICE_UPDATE = "trwa aktualizacja ceny...";
var TXT_DEAR_CLIENT = "SZANOWNY KLIENCIE";

var F_SF_MinStartDate = 2;
var F_SF_MaxDateRange = 90;

var FS_ERRORS_Title = "Wykryto następujące błędy w formularzu:";
var FS_ERROR_Title = "Nieprawidłowe dane";

var F_SF_ERROR_BadCityName = "Podana nazwa miasta jest błędna. Proszę wprowadzić poprawną nazwę lub trzyliterowy kod lotniska.";

var F_SF_ERROR_MinPassangersViolation = "Błędna liczba pasażerów. Należy wybrać przynajmniej jednego pasażera (osobę dorosłą/młodzież).";
var F_SF_ERROR_MaxPassangersExceeded = "Błędna liczba pasażerów. Maksymalna liczba pasażerów nie może być wieksza niż 9.";
var F_SF_ERROR_MinPassangersAdultsViolation = "Błędna liczba pasażerów. Należy wybrać przynajmniej jednego dorosłego pasażera (osobę dorosłą/młodzież).";
var F_SF_ERROR_ToManyInfants = "Błędna liczba pasażerów. Liczba niemowląt musi być mniejsza lub równa sumarycznej liczbie osób dorosłych (dorosły/młodzież).";

var F_SF_ERROR_BadDateFormat = "Podany format daty jest błędny. Proszę podać datę w formacie: "+Date.format;
var F_SF_ERROR_OutDateToCloseToCurrentDate = "Data wylotu powinna być wyznaczona minimum na "+F_SF_MinStartDate+" dni od dnia dzisiejszego.";
var F_SF_ERROR_OutDateIsGraterThenReturnDate = "Data powrotu powinna być dalsza od daty wylotu.";
var F_SF_ERROR_DatesOutOfRange = "Maksymalna rozpiętość czasu między datą wylotu oraz powrotu wynosi "+F_SF_MaxDateRange+" dni."
var F_SF_ERROR_DateOutOfRange = "Data wylotu/powrotu powinna być nie dalsza niż 365 dni od dzisiaj.";

var F_SF_ERROR_BadPreviousDate = "Data lotu wcześniejszego jest błędna. Proszę podać datę w formacie: "+Date.format;
var F_SF_ERROR_StDateIsGraterThenNdDate = "Data powinna być dalsza niż data lotu poprzedniego.";
var F_SF_ERROR_PairCityCantBeEmpty = "Należy określić zarówno miasto wylotu jak i przylotu.";

var F_OF_ERROR_BadName = "Błędne imię i/lub nazwisko. Proszę nie używać polskich liter oraz spacji.";
var F_OF_ERROR_BadNameFirst = "Błędne imię. Proszę nie używać polskich liter oraz spacji.";
var F_OF_ERROR_BadNameLast = "Błędne nazwisko. Proszę nie używać polskich liter oraz spacji.";

var F_OF_ERROR_BadStreet = "Błędna nazwa ulicy. Proszę nie używać polskich liter oraz spacji.";
var F_OF_ERROR_BadStreetNo = "Błędny numer ulicy. Przynajmniej pierwsze pole musi być uzupełnione. Proszę nie używać spacji.";
var F_OF_ERROR_BadCityName = "Błędna nazwa miejscowości. Proszę nie używać polskich liter oraz spacji.";
var F_OF_ERROR_BadZipCode = "Poprawny kod pocztowy składa się wyłącznie z cyfr i jest zapisany w formacie XX-XXX.";
var F_OF_ERROR_BadPhoneFormat = "Podany numer telefonu jest zapisany błędnie. Proszę używać tylko cyfr."
var F_OF_ERROR_BadEmail = "Podany adres jest błędny."
var F_OF_ERROR_BadEmailCheck = "Adres e-mail w obu polach musi być jednakowy.";
var F_OF_ERROR_BadCity = "Błędna nazwa miasta. Proszę nie używać polskich liter oraz spacji.";
var F_OF_ERROR_BadNIPLenghtOrFormat = "Format numeru NIP jest błędny. Proszę podać jedynie cyfry bez znaku '-'.";
var F_OF_ERROR_BadNIPChecksum = "Podany numer NIP jest błędny.";
var F_OF_ERROR_BadDOB = "Błędna data urodzenia. Prosze podać poprawną datę w formacie "+Date.format;
var F_OF_ERROR_BadInfantAge = "Niemowlę nie może mieć więcej niż 2 lata. Wiek liczony jest w stosunku do daty wylotu ostatniego połączenia, czyli: ";
var F_OF_ERROR_BadChildAge = "Dziecko nie może mieć więcej niż 12 lat i mniej niż 2 lata. Wiek liczony jest w stosunku do daty wylotu, czyli: ";
var F_OF_ERROR_BadYoughtAge = "Młodzież nie może mieć więcej niż 18 lat i mniej niż 12 lat. Wiek liczony jest w stosunku do daty wylotu, czyli: ";
var F_OF_ERROR_BadFormat = "Błędny format danych. Proszę wpisywać jedynie cyfry.";
var F_OF_ERROR_FFNumbers = "Niepoprawna ilość znaków. Numer karty składa się z następującej liczby znaków: ";
var F_OF_ERROR_BadRegExp = "Podane pole jest błędnie wypełnione. Prosimy sprawdzić i poprawić wpisane dane.";

var F_OF_ERROR_BadInfantAgeCC1 = "Informujemy, że dziecko uczestniczące w Państwa podróży w dniu powrotu będzie miało ukończone 2 lata. Zgodnie z przepisami IATA i linii lotniczych oznacza to, że zniżka przysługująca niemowlętom w wieku do 2 lat może być zastosowana tylko dla podróży w jedną stronę. W związku z zaistniałą sytuacją powinny zostać wystawione dwa oddzielne bilety dla dziecka w każdą stronę lub jeden bilet na całą trasę ze zniżką dla dziecka do lat 12.";
var F_OF_ERROR_BadInfantAgeCC2 = "Ze względu na powyższe przepisy, rezerwacja nie może zostać zrealizowana online. Prosimy o kontakt z naszą Infolinią. Nasi konsultanci pomogą Państwu wybrać najkorzystniejszy wariant cenowy.";

var F_PF_ERROR_BadCCFormat = "Podany numer karty nie odpowiada formatowi wybranego operataora. W numerze karty proszę nie używać spacji oraz znaku '-'.";
var F_PF_ERROR_BadCCChecksum = "Podany numer karty jest błędny. Proszę sprawdzić wszystkie cyfry. W numerze karty proszę nie używać spacji oraz znaku '-'.";
var F_PF_ERROR_BadCCDate = "Data ważności karty jest błędna. Data na karcie musi być aktualna.";
var F_PF_ERROR_BadCVV = "Numer CVV/CVV2 jest błędnie wprowadzony. Numer powinien składać się z 3 cyfr (lub 4 w przypadku kart AmericanExpress).";
var F_PF_ERROR_MustBeSelected = "Aby kontynuować należy wyrazić zgodę na warunki regulaminu i taryfy.";

var F_ERROR_Required = "Wskazane pole jest wymagane. Proszę podać wymagane informacje.";
var TXT_CLOSE = 'Zamknij';


// -------------------------------------

/*
 * Date prototype extensions. Doesn't depend on any
 * other code. Doens't overwrite existing methods.
 *
 * Adds dayNames, abbrDayNames, monthNames and abbrMonthNames static properties and isLeapYear,
 * isWeekend, isWeekDay, getDaysInMonth, getDayName, getMonthName, getDayOfYear, getWeekOfYear,
 * setDayOfYear, addYears, addMonths, addDays, addHours, addMinutes, addSeconds methods
 *
 * Copyright (c) 2006 JÄÅrn Zaefferer and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 *
 * Additional methods and properties added by Kelvin Luck: firstDayOfWeek, dateFormat, zeroTime, asString, fromString -
 * I've added my name to these methods so you know who to blame if they are broken!
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 */

(function() {

	/**
	 * Adds a given method under the given name
	 * to the Date prototype if it doesn't
	 * currently exist.
	 *
	 * @private
	 */
	function add(name, method) {
		if( !Date.prototype[name] ) {
			Date.prototype[name] = method;
		}
	};

	/**
	 * Checks if the year is a leap year.
	 *
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.isLeapYear();
	 * @result true
	 *
	 * @name isLeapYear
	 * @type Boolean
	 * @cat Plugins/Methods/Date
	 */
	add("isLeapYear", function() {
		var y = this.getFullYear();
		return (y%4==0 && y%100!=0) || y%400==0;
	});

	/**
	 * Checks if the day is a weekend day (Sat or Sun).
	 *
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.isWeekend();
	 * @result false
	 *
	 * @name isWeekend
	 * @type Boolean
	 * @cat Plugins/Methods/Date
	 */
	add("isWeekend", function() {
		return this.getDay()==0 || this.getDay()==6;
	});

	/**
	 * Check if the day is a day of the week (Mon-Fri)
	 *
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.isWeekDay();
	 * @result false
	 *
	 * @name isWeekDay
	 * @type Boolean
	 * @cat Plugins/Methods/Date
	 */
	add("isWeekDay", function() {
		return !this.isWeekend();
	});

	/**
	 * Gets the number of days in the month.
	 *
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.getDaysInMonth();
	 * @result 31
	 *
	 * @name getDaysInMonth
	 * @type Number
	 * @cat Plugins/Methods/Date
	 */
	add("getDaysInMonth", function() {
		return [31,(this.isLeapYear() ? 29:28),31,30,31,30,31,31,30,31,30,31][this.getMonth()];
	});

	/**
	 * Gets the name of the day.
	 *
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.getDayName();
	 * @result 'Saturday'
	 *
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.getDayName(true);
	 * @result 'Sat'
	 *
	 * @param abbreviated Boolean When set to true the name will be abbreviated.
	 * @name getDayName
	 * @type String
	 * @cat Plugins/Methods/Date
	 */
	add("getDayName", function(abbreviated) {
		return abbreviated ? Date.abbrDayNames[this.getDay()] : Date.dayNames[this.getDay()];
	});

	/**
	 * Gets the name of the month.
	 *
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.getMonthName();
	 * @result 'Janurary'
	 *
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.getMonthName(true);
	 * @result 'Jan'
	 *
	 * @param abbreviated Boolean When set to true the name will be abbreviated.
	 * @name getDayName
	 * @type String
	 * @cat Plugins/Methods/Date
	 */
	add("getMonthName", function(abbreviated) {
		return abbreviated ? Date.abbrMonthNames[this.getMonth()] : Date.monthNames[this.getMonth()];
	});

	/**
	 * Get the number of the day of the year.
	 *
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.getDayOfYear();
	 * @result 11
	 *
	 * @name getDayOfYear
	 * @type Number
	 * @cat Plugins/Methods/Date
	 */
	add("getDayOfYear", function() {
		var tmpdtm = new Date("1/1/" + this.getFullYear());
		return Math.floor((this.getTime() - tmpdtm.getTime()) / 86400000);
	});

	/**
	 * Get the number of the week of the year.
	 *
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.getWeekOfYear();
	 * @result 2
	 *
	 * @name getWeekOfYear
	 * @type Number
	 * @cat Plugins/Methods/Date
	 */
	add("getWeekOfYear", function() {
		return Math.ceil(this.getDayOfYear() / 7);
	});

	/**
	 * Set the day of the year.
	 *
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.setDayOfYear(1);
	 * dtm.toString();
	 * @result 'Tue Jan 01 2008 00:00:00'
	 *
	 * @name setDayOfYear
	 * @type Date
	 * @cat Plugins/Methods/Date
	 */
	add("setDayOfYear", function(day) {
		this.setMonth(0);
		this.setDate(day);
		return this;
	});

	/**
	 * Add a number of years to the date object.
	 *
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.addYears(1);
	 * dtm.toString();
	 * @result 'Mon Jan 12 2009 00:00:00'
	 *
	 * @name addYears
	 * @type Date
	 * @cat Plugins/Methods/Date
	 */
	add("addYears", function(num) {
		this.setFullYear(this.getFullYear() + num);
		return this;
	});
	add("substractYears", function(num) {
		this.setFullYear(this.getFullYear() - num);
		return this;
	});
	/**
	 * Add a number of months to the date object.
	 *
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.addMonths(1);
	 * dtm.toString();
	 * @result 'Tue Feb 12 2008 00:00:00'
	 *
	 * @name addMonths
	 * @type Date
	 * @cat Plugins/Methods/Date
	 */
	add("addMonths", function(num) {
		var tmpdtm = this.getDate();

		this.setMonth(this.getMonth() + num);

		if (tmpdtm > this.getDate())
			this.addDays(-this.getDate());

		return this;
	});

	/**
	 * Add a number of days to the date object.
	 *
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.addDays(1);
	 * dtm.toString();
	 * @result 'Sun Jan 13 2008 00:00:00'
	 *
	 * @name addDays
	 * @type Date
	 * @cat Plugins/Methods/Date
	 */
	add("addDays", function(num) {
		this.setDate(this.getDate() + num);
		return this;
	});

	/**
	 * Add a number of hours to the date object.
	 *
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.addHours(24);
	 * dtm.toString();
	 * @result 'Sun Jan 13 2008 00:00:00'
	 *
	 * @name addHours
	 * @type Date
	 * @cat Plugins/Methods/Date
	 */
	add("addHours", function(num) {
		this.setHours(this.getHours() + num);
		return this;
	});

	/**
	 * Add a number of minutes to the date object.
	 *
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.addMinutes(60);
	 * dtm.toString();
	 * @result 'Sat Jan 12 2008 01:00:00'
	 *
	 * @name addMinutes
	 * @type Date
	 * @cat Plugins/Methods/Date
	 */
	add("addMinutes", function(num) {
		this.setMinutes(this.getMinutes() + num);
		return this;
	});

	/**
	 * Add a number of seconds to the date object.
	 *
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.addSeconds(60);
	 * dtm.toString();
	 * @result 'Sat Jan 12 2008 00:01:00'
	 *
	 * @name addSeconds
	 * @type Date
	 * @cat Plugins/Methods/Date
	 */
	add("addSeconds", function(num) {
		this.setSeconds(this.getSeconds() + num);
		return this;
	});

	/**
	 * Sets the time component of this Date to zero for cleaner, easier comparison of dates where time is not relevant.
	 *
	 * @example var dtm = new Date();
	 * dtm.zeroTime();
	 * dtm.toString();
	 * @result 'Sat Jan 12 2008 00:01:00'
	 *
	 * @name zeroTime
	 * @type Date
	 * @cat Plugins/Methods/Date
	 * @author Kelvin Luck
	 */
	add("zeroTime", function() {
		this.setMilliseconds(0);
		this.setSeconds(0);
		this.setMinutes(0);
		this.setHours(0);
		return this;
	});

	/**
	 * Returns a string representation of the date object according to Date.format.
	 * (Date.toString may be used in other places so I purposefully didn't overwrite it)
	 *
	 * @example var dtm = new Date("01/12/2008");
	 * dtm.asString();
	 * @result '12/01/2008' // (where Date.format == 'dd/mm/yyyy'
	 *
	 * @name asString
	 * @type Date
	 * @cat Plugins/Methods/Date
	 * @author Kelvin Luck
	 */
	add("asString", function() {
		var r = Date.format;
		return r
			.split('yyyy').join(this.getFullYear())
			.split('yy').join((this.getFullYear() + '').substring(2))
			.split('mmm').join(this.getMonthName(true))
			.split('mm').join(_zeroPad(this.getMonth()+1))
			.split('dd').join(_zeroPad(this.getDate()));
	});

	/**
	 * Returns a new date object created from the passed String according to Date.format or false if the attempt to do this results in an invalid date object
	 * (We can't simple use Date.parse as it's not aware of locale and I chose not to overwrite it incase it's functionality is being relied on elsewhere)
	 *
	 * @example var dtm = Date.fromString("12/01/2008");
	 * dtm.toString();
	 * @result 'Sat Jan 12 2008 00:00:00' // (where Date.format == 'dd/mm/yyyy'
	 *
	 * @name fromString
	 * @type Date
	 * @cat Plugins/Methods/Date
	 * @author Kelvin Luck
	 */
	Date.fromString = function(s)
	{
		var f = Date.format;
		var d = new Date('01/01/1977');
		var iY = f.indexOf('yyyy');
		if (iY > -1) {
			d.setFullYear(Number(s.substr(iY, 4)));
		} else {
			// TODO - this doesn't work very well - are there any rules for what is meant by a two digit year?
			d.setFullYear(Number(Date.fullYearStart + s.substr(f.indexOf('yy'), 2)));
		}
		var iM = f.indexOf('mmm');
		if (iM > -1) {
			var mStr = s.substr(iM, 3);
			for (var i=0; i<Date.abbrMonthNames.length; i++) {
				if (Date.abbrMonthNames[i] == mStr) break;
			}
			d.setMonth(i);
		} else {
			d.setMonth(Number(s.substr(f.indexOf('mm'), 2)) - 1);
		}
		d.setDate(Number(s.substr(f.indexOf('dd'), 2)));
		if (isNaN(d.getTime())) {
			return false;
		}
		return d;
	};

	// utility method
	var _zeroPad = function(num) {
		var s = '0'+num;
		return s.substring(s.length-2)
		//return ('0'+num).substring(-2); // doesn't work on IE :(
	};

})();



/* ---------- FUNCTIONS ---------- */
/**
 * Special function for spliting form element name/id
 * into 2 pieces: name (letters) and number (digits).
 * This function is used by hotels/flights ASF
 */
function splitValue(value) {
	if(typeof value != "string") value = value.toString();
	var objectName = value.match(/(\.|\#)?[\/\?\.=a-z_]+/g);
	var objectId = value.match(/\d+/g);
	return {
		name:objectName,
		id:objectId,
		array:( objectId != parseInt(objectId) && objectId != null )?true:false
	}
}
/**
 * Function for creating a cookie
 * @param {Object} name
 * @param {Object} value
 * @param {Object} days
 */
function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+escape(value)+expires+"; path=/";
}
/**
 * Function for reading a cookie.
 * @param {Object} name
 */
function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return unescape(c.substring(nameEQ.length,c.length));
	}
	return null;
}
function eraseCookie(name) {
	createCookie(name,"",-1);
}


/* ---------- VALIDATION FUNCTIONS ------------- */
function Luhn(digits){
	var sum = 0;
	var alt = false;
	var numvar = 0;
	for(var i = digits.length - 1; i >= 0; i--){
		numvar = parseInt(digits.charAt(i));
		if(alt){
			numvar *= 2;
			if(numvar > 9){
				numvar -= 9;
			}
		}
		sum += numvar;
		alt = !alt;
	}
	return sum % 10 == 0;
}
/**
 * errorBox displays list of error messages
 * or displays alert window
 */
var errorBox = function(errors,options) {
	$('div#msg-box').remove();
	$('table#stepper').after(
		$('<div></div>').attr('id','msg-box')
			.append(
				$('<h2></h2>')
					.text('Błędne pola')
			)
			.append(
				$('<div></div>')
					.addClass('textBox')
					.css({'paddingTop':'10px'})
			)
	)
	errors.each(function(){
		var text = jQuery.trim($(this).text());
		var info = jQuery.trim($(this).attr('title'));
		if (text.indexOf(':')!=-1) text = text.substring(0,text.lastIndexOf(':'));
		if (text.length>1) {
			text = '<strong>' + text + '</strong>';
			if(info != '') text += ' - ' + info;
			$('div#msg-box>div.textBox').append($('<p></p>').html(text));
		}
	});
	$('div#msg-box').show(100,function(){window.scroll(0,0)});
}
var isValidDateFormat = function(s,startFromYear){
	var reFormat =  /^([0-9]{2,4}[\.\-/]{1}){2}([0-9]{2,4})$/i.test(s);

	var f = Date.format; f.toLowerCase();

	var reSeparator = false;
	if(/^\d+\-\d+\-\d+$/i.test(s) && /^\w+\-\w+\-\w+$/i.test(f)) reSeparator = true;
	if(/^\d+\.\d+\.\d+$/i.test(s) && /^\w+\.\w+\.\w+$/i.test(f)) reSeparator = true;
	if(/^\d+\/\d+\/\d+$/i.test(s) && /^\w+\/\w+\/\w+$/i.test(f)) reSeparator = true;

	var y = parseInt(s.substr(f.indexOf('yyyy'),4),10);
	var m = parseInt(s.substr(f.indexOf('mm'),2),10);
	var d = parseInt(s.substr(f.indexOf('dd'),2),10);

	return ( !reFormat || !reSeparator || y<0 || m<1 || m>12 || d<1 || d>31 ) ? false : true ;
}
var isValidDOB = function(object){
	var this_date = Date.fromString(object.val());
	var today = new Date;

	//isValidDateFormat(object.val(),1900)==false ||
	if(this_date==false || jQuery.trim(object.val())=='' || this_date.zeroTime() >= today.zeroTime() ){
		return false;
	}
	return true;
}
var isValidDOBInfant = function(object){
	var dob = new Date.fromString(object.val());
	var dob = new Date(dob).addYears(2);

	var arrival = new Date.fromString(ibeConfig.arrivalDate);
	var departure = new Date.fromString(ibeConfig.departureDate);

	if(isValidDOB(object)){
		// Age 0 - 2
		if(dob > departure && dob < arrival)
		{
			//infantSpecialInfo();
			return F_OF_ERROR_BadInfantAgeCC1;
		}
		return (dob < arrival) ? F_OF_ERROR_BadInfantAge + ibeConfig.arrivalDate : true;
	}else{
		return false;
	}
}
var isValidDOBChild = function(object){
	var dob = new Date.fromString(object.val());
	var today = new Date.fromString(ibeConfig.departureDate);

	if(isValidDOB(object)){
		// Age 2 - 12(2+10)
		return (new Date(dob).addYears(2) > today || new Date(dob).addYears(12) < today) ? F_OF_ERROR_BadChildAge + ibeConfig.departureDate : true;
	}else{
		return false;
	}
}
var isValidDOBYought = function(object){
	var dob = new Date.fromString(object.val());
	var today = new Date.fromString(ibeConfig.departureDate);

	if(isValidDOB(object)){
		// Age 12 - 18(12+6)
		return (new Date(dob).addYears(12) > today || new Date(dob).addYears(18) < today) ? F_OF_ERROR_BadYoughtAge + ibeConfig.departureDate : true;
	}else{
		return false;
	}
}
/**
 * Checks if date is valid (F-QSF)
 */
var isValidDateFQSF = function(object){
	var this_date = Date.fromString(object.val());
	var today = new Date;

	if(this_date==false || jQuery.trim(object.val())=='' || isValidDateFormat(object.val(),new Date().getFullYear())==false) return F_SF_ERROR_BadDateFormat;

	if( object.attr('name').indexOf('_from_')!=-1 ){
		var fly_from = this_date;
		var fly_to = Date.fromString($('#wylot_data2').val());

		if(fly_from>new Date().addDays(364)) return F_SF_ERROR_DateOutOfRange;
		if(fly_from < today.addDays(F_SF_MinStartDate)) return F_SF_ERROR_OutDateToCloseToCurrentDate;
	} else {
		var fly_from = Date.fromString($('#wylot_data1').val());
		var fly_to = this_date;

		if (object.not(':disabled')) {
			if (fly_to>new Date().addDays(364)) return F_SF_ERROR_DateOutOfRange;
			if (fly_from >= fly_to)	return F_SF_ERROR_OutDateIsGraterThenReturnDate;
			//if (parseInt((fly_to - fly_from) / 86400000) > F_SF_MaxDateRange) return F_SF_ERROR_DatesOutOfRange;
		}
	}
	return true;
}
/**
 * Checks if city is valid (F-ASF & F-QSF)
 */
var isValidCity = function(object){
	return /^.{3,}$/i.test(object.val());
}
/**
 * Checks if passengers are valid (F-QSF)
 */
var isPassangerFQSF = function(object){

	var passengers = 0;
	for(i=1;i<=4;i++) {
		var p = parseInt($('#fly_passenger_no_'+i).val());
		passengers += ( !isNaN(p) && p != 'undefined' ) ? p : 0;
	}

	if (passengers == 0) return F_SF_ERROR_MinPassangersViolation;
	if (passengers > 9) return F_SF_ERROR_MaxPassangersExceeded;

	var passengers_adults = parseInt($('#fly_passenger_no_1').val()) + parseInt($('#fly_passenger_no_3').val());
	if (passengers_adults == 0) return F_SF_ERROR_MinPassangersAdultsViolation;

	//return isInfant(object);
	return true;
}
var isInfant = function(object){
	var passengers_adults = parseInt($('#fly_passenger_no_1').val()) + parseInt($('#fly_passenger_no_3').val());
//	passengers_adults = ( !isNaN(passengers_adults) && p != 'undefined' ) ? passengers_adults : 0;
	var passengers_infants = parseInt($('#fly_passenger_no_4').val());

	if (passengers_infants > passengers_adults) return F_SF_ERROR_ToManyInfants;
	return true;
}
var isValidNameLatin = function(object){
	return /^[a-z]{2,64}$/i.test(object.val());
}
var isValidName = function(object){
	return /^[_\w\-\. ęóąśłżźćń]{2,64}$/i.test(object.val());
}
var isValidStreet = function(object){
	return /^[_\w\-\. ęóąśłżźćń]{3,64}$/i.test(object.val());
}
var isValidStreetNo = function(dumy,f1,f2){
	var no1 = $(f1).val();
	var no2 = $(f2).val();
	if($.trim(no1)=='')	return false;
	if(!/^[\wł]{1,5}$/i.test(no1)) return false;
	if(!/^[\wł]{0,5}$/i.test(no2)) return false;
	return true;
}
var isValidStrretNoPayer = function(object,f1,f2){
	return isValidStreetNo(object,'#payer_streetno','#payer_streetno2');
}
var isValidStrretNoInvoice = function(object,f1,f2){
	return isValidStreetNo(object,'#fly_invoice_streetno','#fly_invoice_streetno2');
}
var isValidZipCode = function(object,f1,f2){
	return /^\d{2}-\d{3}$/.test($(f1).val()+'-'+$(f2).val());
}
var isValidZipCodePayer = function(object){
	return ($('#payer_country').val() != 'PL') ? /^.+$/.test(object.val()) : /^\d{2}-\d{3}$/.test(object.val());
}
var isValidZipCodeInvoice = function(object){
	return ($('#fly_invoice_country').val() != 'PL') ? /^.+$/.test(object.val()) : /^\d{2}-\d{3}$/.test(object.val());
}
var isValidPhone = function(object){
	return /^\+?[0-9 -]+$/i.test(object.val());
}
var isValidMobilePhone = function(object){
	return /^(\+?[0-9 -]+)?$/i.test(object.val());
}
var isValidEmail = function(object){
	return /^([_\w\-]+\.?[_\w\-]+)+@([_\w\-]+\.?[_\w\-]+)+\.[a-z]{2,4}$/i.test(object.val());
}
var isValidEmailCheck = function(object){
	return (object.val()==$('#payer_email').val());
}
var isValidNIP = function(object){
	if ($('#fly_invoice_country').val() != 'PL' || object.val() == '') {
		return true;
	} // Don't check NIP when selected country is different then Poland or when field is empty (ex. private person).
	var nip = $.trim(object.val());
	if(!/^\d{10}$/.test(nip)) return F_OF_ERROR_BadNIPLenghtOrFormat;
	var ratio = new Array(6,5,7,2,3,4,5,6,7);
	var checksum = 0;
	for(i=0;i<9;i++) {
		checksum += parseInt(nip.substring(i,(i+1))*ratio[i]);
	}
	if((checksum%11)!=nip.substring(9,10)) return F_OF_ERROR_BadNIPChecksum;
	return true;
}
var isValidVisa = function(cc){
	return /^4(\d{12}|\d{15})$/.test(cc);
}
var isValidVisaE = function(cc){
	return /^4((917|913|508|844)\d{12}|17500\d{10})$/.test(cc);
}
var isValidMC = function(cc){
	return /^5[1-5]\d{14}$/.test(cc);
}
var isValidAmEx = function(cc){
	return /^(34|34)\d{13}$/.test(cc);
}
var isValidDinersClub = function(cc){
	return /^(36\d{12}|55\d{14})$/.test(cc);
}
var isValidCC = function(object){
	var cc = $.trim(object.val());
	switch(parseInt($('#payment_card_cc_type').val())){
		case 1: //VISA
			if(!isValidVisa(cc)) return F_PF_ERROR_BadCCFormat;
		break;
		case 4: //VISA Electron
			if(!isValidVisaE(cc)) return F_PF_ERROR_BadCCFormat;
		break;
		case 2: //MasterCard
			if(!isValidMC(cc)) return F_PF_ERROR_BadCCFormat;
		break;
		case 3: //AmericanExpress
			if(!isValidAmEx(cc)) return F_PF_ERROR_BadCCFormat;
		break;
		case 5: //DinersClub
			if(!isValidDinersClub(cc)) return F_PF_ERROR_BadCCFormat;
		break;
	}
	if(!Luhn(cc)) return F_PF_ERROR_BadCCChecksum;
	return true;
}
var isValidCVV = function(object){
	var cvv = $.trim(object.val());
	switch(parseInt($('#payment_card_cc_type').val())){
		case 3: //AmericanExpress
			if(!/^\d{4}$/.test(cvv)) return false;
		break;
		default:
			if(!/^\d{3}$/.test(cvv)) return false;
		break;
	}
	return true;
}
var isValidCCDate = function(object){
	var m = parseInt($('#payment_card_cc_month').val())-1;
	var y = parseInt($('#payment_card_cc_year').val());

	var today = new Date();

	var selected = new Date();
	selected.zeroTime();

	selected.setFullYear(y);
	selected.setMonth(m);
	selected.setDate(selected.getDaysInMonth());

	return (today < selected);
}
var isNumeric = function(object){
	var num = object.val();
	var reg = object.attr('rel');
	var reg = reg.split('_');

	if( parseInt(num.length) == 0) {
		return true;
	}
	if ( parseInt(num.length) == parseInt(reg[1])) {
		return /^\d+$/.test(num);
	} else {
		return F_OF_ERROR_FFNumbers + reg[1];
	}
}
var isRegExp = function(object){
	var reg = object.attr('rel');

	if(reg.indexOf('NUMERIC')==0) return isNumeric(object); //temporary
	//console.log(reg);

	var rx = (reg.indexOf('^')!=0) ? new RegExp('^'+reg+'$','i') : new RegExp(reg,'i') ;
	return rx.test(object.val());
}
var isRequired = function(object){
	return ($.trim(object.val())=='') ? F_ERROR_Required : true;
}
var checkbox = function(object){
	return (object.is(':checked'));
}


/* ---------- VALIDATION SETS ---------- */
var qsf_settings = {
	'#escape,#arrival' : {'validator':isValidCity,'error':F_SF_ERROR_BadCityName},
	'#wylot_data1,#wylot_data2': {'validator': isValidDateFQSF},
	'#fly_passenger_no_1,#fly_passenger_no_2' : {'validator':isPassangerFQSF,'label':'label[for="fly_passenger_no_1"]'},
	'#fly_passenger_no_4' : {'validator':isInfant}
};
var flight_options = {
	'payer_firstname' : {'validator':isValidName,'error':F_OF_ERROR_BadNameFirst},
	'payer_lastname' : {'validator':isValidName,'error':F_OF_ERROR_BadNameLast},

	'#payer_street' : {'validator':isValidStreet,'error':F_OF_ERROR_BadStreet},
	'payer_streetno' : {'validator':isValidStrretNoPayer,'error':F_OF_ERROR_BadStreetNo,'label':'label[for="payer_streetno"]'},
	'#payer_code1' : {'validator':isValidZipCodePayer,'error':F_OF_ERROR_BadZipCode,'label':'label[for="payer_code1"]'},
	'#payer_city' : {'validator':isValidCity,'error':F_OF_ERROR_BadCity},
	'#payer_phone' : {'validator':isValidPhone,'error':F_OF_ERROR_BadPhoneFormat},
	'#payer_mobile' : {'validator':isValidMobilePhone,'error':F_OF_ERROR_BadPhoneFormat},
	'#payer_email' : {'validator':isValidEmail,'error':F_OF_ERROR_BadEmail},
	'#payer_email_check' : {'validator':isValidEmailCheck,'error':F_OF_ERROR_BadEmailCheck},

	'.passenger_firstname' : {'validator':isValidNameLatin,'error':F_OF_ERROR_BadNameFirst},
	'.passenger_lastname' : {'validator':isValidNameLatin,'error':F_OF_ERROR_BadNameLast},
	'.passenger_dob_4' : {'validator':isValidDOBInfant,'error':F_OF_ERROR_BadDOB},
	'.passenger_dob_2' : {'validator':isValidDOBChild,'error':F_OF_ERROR_BadDOB},
	'.passenger_dob_3' : {'validator':isValidDOBYought,'error':F_OF_ERROR_BadDOB},
//	'NUMERIC' : {'validator':isNumeric,'error':F_OF_ERROR_BadFormat},
	'.reg-exp' : {'validator':isRegExp,'error':F_OF_ERROR_BadRegExp},
	'.required' : {'validator':isRequired},

	'#fly_invoice_name' : {'validator':isValidName,'error':F_OF_ERROR_BadName},
	'#fly_invoice_street' : {'validator':isValidStreet,'error':F_OF_ERROR_BadStreet},
	'fly_invoice_streetno' : {'validator':isValidStrretNoInvoice,'error':F_OF_ERROR_BadStreetNo,'label':'label[for="fly_invoice_streetno"]'},
	'#fly_invoice_code1' : {'validator':isValidZipCodeInvoice,'error':F_OF_ERROR_BadZipCode,'label':'label[for="fly_invoice_code1"]'},
	'#fly_invoice_city' : {'validator':isValidCity,'error':F_OF_ERROR_BadCity},
	'#fly_invoice_nip' : {'validator':isValidNIP}
}
var flight_payment = {
	'#payment_card_cc_number' : {'validator':isValidCC},
	'#payment_card_first_name' : {'validator':isValidNameLatin,'error':F_OF_ERROR_BadNameFirst},
	'#payment_card_last_name' : {'validator':isValidNameLatin,'error':F_OF_ERROR_BadNameLast},
	'#payment_card_cc_month,#payment_card_cc_year' : {'validator':isValidCCDate,'label':'label[for="payment_card_cc_month"]','error':F_PF_ERROR_BadCCDate},
	'#payment_card_cc_cvv' : {'validator':isValidCVV,'error':F_PF_ERROR_BadCVV},
	'#accept_terms,#accept_tariff' : {'validator':checkbox,'error':F_PF_ERROR_MustBeSelected }
};




/* ---------- JQUERY EXTENSIONS ---------- */
jQuery.fn.extend({
	/*
	 * VALIDATION EXTENSIONS
	 */
	getLabel: function(label){
		var o = $(this);
		if (label && $(label).size()>0){
			return $(label);
		} else if ($('label[for="'+o.attr('id')+'"]').size()>0) {
			return $('label[for="'+o.attr('id')+'"]');
		} else if (o.prevAll('label:first').size()>0) {
			return o.prevAll('label:first');
		} else {
			return o;
		}
	},
	toggleError: function(test){
		var o = $(this);
		var l = o.getLabel(test.label);

		test_result = test.validator(o);
		if( ( test_result == false || test_result.length > 0 ) && l.not($('.'+cl_OmitError)).size() > 0 ){
			var error_msg = (test_result.length > 0) ? test_result : test.error
			l.removeClass(cl_OK);
			l.addClass(cl_Error).attr('title',error_msg);
		} else {
			l.removeClass(cl_Error).removeAttr('title');
			l.addClass(cl_OK);
		}
	},
	checkInput: function(options,bind){
		$this = $(this);
		$this.each(function(){
			if(bind){
				switch($(this).attr('type'))
				{
					case 'text':
						$(this).keyup(function(){ $(this).toggleError(options); });
						break;
					default:
						$(this).change(function(){ $(this).toggleError(options); });
						break;
				}
				$(this).blur(function(){ $(this).toggleError(options); });
			}else{
				$(this).toggleError(options);
			}
		});
	},
	attachValidation: function(name,options,bind) {
		switch(name.substring(0,1)){
			case '#':
			case '.':
				$(name+':enabled').checkInput(options, bind);
				break;
			default:
				$('input[type="text"][id^="' + name + '"]:enabled').checkInput(options, bind);
				$('select[id^="' + name + '"]:enabled').checkInput(options, bind);
				break;
		}
	},
	checkAll: function(options,bind) {
		if ($(this).size() == 0) {
			return $(this);
		} else {
			$('p,label',$(this)).removeClass(cl_Error);
		}

		for(o in options) {
			var filelds = o.split(',');
			for (f in filelds) {
				range = splitValue(filelds[f]);
				if (range.array == false) {
					this.attachValidation(filelds[f],options[o], bind);
				} else {
					for(r=range.id[0];r<=range.id[1];r++) {
						this.attachValidation(range.name + r,options[o], bind);
					}
				}
			}
		}
		return $(this);
	},
	saveQuery: function(formId){
		var cookieId = (formId) ? formId : $(this).attr('id');
		var queryString = cookieId;
		$('input[type="text"],input[type="hidden"].hidden,select,input[type="radio"]:checked,input[type="checkbox"]:checked',$(this))
		.not(':disabled').each(function(){
			var val = $(this).val();
			if (typeof val != 'undefined' && val != '') {
				queryString += '|' + $(this).attr('type') + ':' + $(this).attr('name') + '=' + val;
			}
		});
		createCookie(cookieId,queryString,30);
	},
	loadQuery: function(formId){
		var cookieId = (formId) ? formId : $(this).attr('id');
		var cookie = readCookie(cookieId);
		if (cookie) {
			var fields = cookie.split('|');
			for (i in fields) {
				var a = fields[i].split(':'); if(a[1]) var b = a[1].split('='); else continue;
				switch(a[0]) {
					case 'radio':
					case 'checkbox':
					if($('*[@name=' + b[0] + '][@value=' + b[1] + ']', $(this)).get(0)) $('*[@name=' + b[0] + '][@value=' + b[1] + ']', $(this)).get(0).checked = true;
					break;
					default:
					$('*[@name=' + b[0] + ']', $(this)).val(b[1]);
					break;
				}
			}
		}
	},
	checkForm: function(options,errorbox,memorizeFormFields,onlyFirstError,filerHidden){
		if(memorizeFormFields) $(this).loadQuery(memorizeFormFields);
		$(this).submit(function(){
			$(this).checkAll(options);
			var n_Error = $('.' + cl_Error, $(this)).filter(filerHidden);
			if (onlyFirstError) {
				n_Error = n_Error.eq(0);
			}
			if(n_Error.size()>0){
				if(errorbox) errorbox(n_Error,options);
				return false;
			}else{
				if(memorizeFormFields) $(this).saveQuery(memorizeFormFields);
				return true;
			}
		});
	}
});
var filterHidden = function(index){
	// Don't check fields which are not visible
	return ($(this).parents(":hidden").size() == 0 && $(this).is(':visible'));
}
var filterCheckAll = function(index){
	return true;
}
var tip = function(text){
	var xy = $(this).offset();
	$('body').append(
		$('<div></div>').addClass('tip').css({'top':xy.top+15,'left':xy.left}).html(text)
	);
}
/* ---------- ACTIONS ---------- */
$(document).ready(function(){

	/**
	 * Enable Flights ASF Validation
	 * Remove checkAll(asf,true) to disable live evaluation - it's not very usefull with multiple flights
	 * $('#flight-asf').checkAll(asf_settings,true).checkForm(asf_settings,errorBox,true);
	 */
	$('#ticketsAdvSearchForm,#flight-qsf').checkForm(qsf_settings,errorBox,false,false,filterCheckAll);
	$('#options-form').checkForm(flight_options,errorBox,false,false,filterHidden);
	$('#payment-form').checkForm(flight_payment,errorBox,false,false,filterHidden);

	$('.datepicker')
	.unbind()
	.not('.btn-calendar-disabled')
	.attr('autocomplete','off')
	.click(function(){
		var o = $(this);
		o.esky_calendar({thisInput:o.attr('rel'),linkedInput:o.attr('rev'),loop:2});

		return false;
	});

	$('#onewaytrip').click(function(){
		$('#esky_calendar').remove();
		$('#wylot_data2').val('').attr('disabled','disabled').addClass('inactive');
	});
	$('#roundtrip').click(function(){
		if(date = $('#wylot_data1').val()) { var day = new Date.fromString(date); } else { var day = new Date(); }
		$('#esky_calendar').remove();
		$('#wylot_data2').val(day.addDays(3).asString()).removeAttr('disabled').removeClass('inactive');
	});
	$('.changed').hover(
		function(){
			var xy = $(this).offset();
			$('body').append(
				$('<div></div>').addClass('tip').css({'top':xy.top+15,'left':xy.left}).html(TXT_TIP_CityChanged)
			);
		},
		function(){$('div.tip').remove()}
	);
	$('.overnight').hover(
		function(){
			var xy = $(this).offset();
			$('body').append(
					$('<div></div>').addClass('tip').css({'top':xy.top+15,'left':xy.left}).html(TXT_TIP_Overnight)
			);
		},
		function(){$('div.tip').remove()}
	);

	$('#asf_tip').hover(
		function(){
			var xy = $(this).offset();
			$('#tooltip').css({'top':xy.top,'left':xy.left+$(this).width()-2}).show();
		},
		function(){
			$('#tooltip').hide();
		}
	);

	function correctFlyLink(u){
		if(u){
			if(u.indexOf('#')!=-1){
				var h = u.split('#');
				var hash = h[1];
				u = h[0];
			} else {
				var hash = false;
			}
			var g = (u.indexOf('?')!=-1) ? '&' : '/?';
			return ((u.indexOf('menu=')!=-1) ? u : u + g + 'menu=loty;1111') + ((hash) ? '#' + hash : false);
		}
	}
	/*$('a').each(function(){
		$o = $(this);
		$o.attr('href',correctFlyLink($o.attr('href')));
	})
	$('form').each(function(){
		$o = $(this);
		$o.attr('action',correctFlyLink($o.attr('action')));
	})*/
	//$('form').attr('action',correctFlyLink($(this).attr('action')));
});