/** 
* [A] Helper for understanding the month number of days
* @param Integer month the month ( 0 for january , 11 for december )
* @param Integer year The year ( 2009 for 2009 )
* @return the number of days in that month
* @type Integer
*/
Date.daysInMonth = function (month, year) {
	return 32 - new Date( year, month, 32).getDate();
};

/**
* Extends the date object by adding this method that will help to adddays.
* @param Integer days to add on the Date object
*/
Date.prototype.addDays = function(days) {
	this.setDate(this.getDate()+days);
};
Date.parseDate = function (date, format) {
				if (date.constructor == Date) {
					return new Date(date);
				}
				var parts = date.split(/\W+/);
				var against = format.split(/\W+/), d, m, y, h, min, now = new Date();
				now = null;
				for (var i = 0; i < parts.length; i++) {
					switch (against[i]) {
						case 'd':
						case 'e':
							d = parseInt(parts[i],10);
							break;
						case 'm':
							m = parseInt(parts[i], 10)-1;
							break;
						case 'Y':
						case 'y':
							y = parseInt(parts[i], 10);
							y += y > 100 ? 0 : (y < 29 ? 2000 : 1900);
							break;
						case 'H':
						case 'I':
						case 'k':
						case 'l':
							h = parseInt(parts[i], 10);
							break;
						case 'P':
						case 'p':
							if (/pm/i.test(parts[i]) && h < 12) {
								h += 12;
							} else if (/am/i.test(parts[i]) && h >= 12) {
								h -= 12;
							}
							break;
						case 'M':
							min = parseInt(parts[i], 10);
							break;
					}
				}
};
Date.prototype.formatDate = function (format ) {
	var r = format || Date.format;
	return r
			.split('yyyy').join(this.getFullYear())
			.split('yy').join((this.getFullYear() + '').substring(2))
			.split('mmmm').join(this.getMonthName(false))
			.split('mmm').join(this.getMonthName(true))
			.split('mm').join(Date._zeroPad(this.getMonth()+1))
			.split('dd').join(Date._zeroPad(this.getDate()))
			.split('hh').join(Date._zeroPad(this.getHours()))
			.split('min').join(Date._zeroPad(this.getMinutes()))
			.split('ss').join(Date._zeroPad(this.getSeconds()));
	

};
/**
* Utility method that place 0 before a Date number
**/
Date._zeroPad = function (num ) {
	var s = '0'+num;
	return s.substring(s.length-2);
};
/*/
* This function helps the developer to extends his classes
* @param Class subclass class that will extends the superclass
* @param Class superclass class that will be extended.
/
function extend(subclass, superclass) { 
	function Dummy() {}
	Dummy.prototype = superclass.prototype;
	subclass.prototype = new Dummy();
	subclass.prototype.constructor = subclass;
	subclass.superclass = superclass;
	subclass.superproto = superclass.prototype;
}
*/


function FBBFDates() {
	log.debug("FBBFDates.constructor");

}
/**
* Returns the date object form the booking form. If the date is not valid then it returns null
* @return date object if the date compiled by the user is valid and null if it's not valid (Eg: 29 february, 31 April ... )
*/
FBBFDates.prototype.getDateObject = function () {log.debug("FBBFDates.getDateObject");};
/**
* Method that returns the day choosen by 
* @return the day from 1 to 31
* @type Integer
*/
FBBFDates.prototype.getDate = function () {log.debug("FBBFDates.getDate");};
/**
* Method that returns the month from the booking form
* @return the month from 1 to 12
* @type Integer
*/
FBBFDates.prototype.getMonth = function () {log.debug("FBBFDates.getMonth");};
/**
* Method that get the year choosen by user on the booking form
* @return the four digit year (Ex: 2010 , 2010 .. )
* @type Integer
*/
FBBFDates.prototype.getFullYear = function () {log.debug("FBBFDates.getFullYear");};

/**
* Method that will update the html and the booking form according to the dateobject
* @param Date dateObject the date you would like to set on the booking form
* @return <ul><li><strong>true</strong>: if the data was setted successfully</li><li><strong>false</strong>: If the date cannot be setted on the booking form</li></ul>
* @type boolean
*/
FBBFDates.prototype.setDateObject = function (dateObject) {
	log.debug("FBBFDates.setDateObject");
	if (dateObject === null ) { 
		return false;
	} else {
		this.setDate(dateObject.getDate());
		this.setMonth(dateObject.getMonth());
		this.setFullYear(dateObject.getFullYear());
		return true;
	}
};

/**
* Add the number of days on the current booking form value 
* @param Integer ndays the number of days to add. Could be both positive or negative
* @return <ul><li><strong>true</strong>: if the data was setted successfully</li><li><strong>false</strong>: If the date cannot be setted on the booking form</li></ul>
* @type boolean
*/
FBBFDates.prototype.addDays = function (ndays) {
	log.debug("FBBFDates.addDays");
	var dateObject = this.getDateObject();
	if (dateObject !== null) {
		dateObject.addDays(ndays);
		return this.setDateObject(dateObject);
	} else {
		return false;
	}
};

/**
* Set that date on the booking form html
* @param integer day from 1 to 31. 
*/
FBBFDates.prototype.setDate = function (day) {log.debug("FBBFDates.setDate");};

/**
* Set the month on the booking form html
* @param integer month from 1 to 12.
*/
FBBFDates.prototype.setMonth = function (month) {log.debug("FBBFDates.setMonth");};

/**
* Set the year on the booking form html
* @param integer year set the 4 digit year on the bf
*/
FBBFDates.prototype.setFullYear = function(year) {log.debug("FBBFDates.setFullYear");};

/**
* This method will fill the booking form ( if it's needed ) with the right data.
*/
FBBFDates.prototype.initializeBf = function() {log.debug("FBBFDates.initializeBf");};/**
* ArrivalDate object constructor
* @param String configurator ('hidden', 'select');
* @constructor
*/
function ArrivalDate(bookingFormConfiguration) {
	log.debug("ArrivalDate.constructor");
	this.BFC = bookingFormConfiguration;
	this.bookingForm = Fblib.getFormFromIDorName(bookingFormConfiguration.formId);
}
ArrivalDate.prototype = new FBBFDates();
ArrivalDate.prototype.constructor = ArrivalDate;

ArrivalDate.prototype.getDateObject = function () {
	log.debug("ArrivalDate.getDateObject");
	var dataJs = new Date( this.getFullYear(), this.getMonth()-1, this.getDate());
	if ( this.getMonth() == dataJs.getMonth()+1 && this.getDate() == dataJs.getDate() && this.getFullYear() == dataJs.getFullYear()) {
		return dataJs;
	} else {
		return null;
	}
};

ArrivalDate.prototype.setDateObject = function (dateObject) {
	log.debug("ArrivalDate.setDateObject");
	if (dateObject === null ) { 
		return false;
	} else {
		this.setDate(dateObject.getDate());
		this.setMonth(dateObject.getMonth()+1);
		this.setFullYear(dateObject.getFullYear());
		return true;
	}
};

ArrivalDate.prototype.getMonth = function () {
	log.debug("ArrivalDate.getMonth");
	return parseInt ( this.bookingForm.frommonth.value,10 );
};
ArrivalDate.prototype.setMonth = function (month) {
	log.debug("ArrivalDate.setMonth");
	if (this.BFC.type == "hidden" ) {
		this.bookingForm.frommonth.value= month;
	} else {
		this.bookingForm.frommonth.selectedIndex = month - 1;
	}
};

ArrivalDate.prototype.getDate = function () {
	log.debug("ArrivalDate.getDate");
	return parseInt ( this.bookingForm.fromday.value,10);
};
ArrivalDate.prototype.setDate = function (day) {
	log.debug("ArrivalDate.setDate");
	if (this.BFC.type == "hidden" ) {
		this.bookingForm.fromday.value = day ;
	} else {
		this.bookingForm.fromday.selectedIndex = day - 1;
	}
};

ArrivalDate.prototype.getFullYear = function () {
	log.debug("ArrivalDate.getFullYear");
	return parseInt ( this.bookingForm.fromyear.value,10);
};

ArrivalDate.prototype.setFullYear = function (year) {
	log.debug("ArrivalDate.setFullYear");
	if (this.BFC.type == "hidden" ) {
		this.bookingForm.fromyear.value = year;
	} else {
		this.bookingForm.fromyear.selectedIndex = year - new Date().getFullYear();
	}
};

ArrivalDate.prototype.initializeBf = function() {
	log.debug("ArrivalDate.initializeBf");
	var cur_date = new Date();
	if (this.BFC.type == "hidden" ) {
	
		this.setDate(cur_date.getDate());
		this.setMonth(cur_date.getMonth()+1);
		this.setFullYear(cur_date.getFullYear());
		return;
	}

	var cur_year = cur_date.getFullYear();
		
	var cur_y = new Option(cur_year, cur_year, true, true);
	
	this.bookingForm.fromyear.options[0] = cur_y;
		
	var next_y = new Option(cur_year + 1, cur_year + 1, false, false);
	this.bookingForm.fromyear.options[1] = next_y;
	
	this.bookingForm.fromday.length = 0;
	// Creating the days options.
	for (var i=1; i<=31; i++) {
		var cur_opt = null;
		if (i==1) {
			cur_opt = new Option(i, i, true, true);
		} else {
			cur_opt = new Option(i, i, false, false);
		}
		this.bookingForm.fromday.options[i-1] = cur_opt;
	}
	
};

/**
* DepartureDate object constructor
* @param String configurator ('hidden', 'select');
*/
function DepartureDate(arrivalDate, bookingFormConfiguration, fblibInstance) {
	log.debug("DepartureDate.constructor");
	this.arrivalDate = arrivalDate;
	this.BFC = bookingFormConfiguration;
	this.bookingForm = Fblib.getFormFromIDorName(bookingFormConfiguration.formId);
	this.fblibInstance = fblibInstance;
}
DepartureDate.prototype = new FBBFDates();
DepartureDate.prototype.constructor = DepartureDate;

DepartureDate.prototype.getDateObject = function () {
	log.debug("DepartureDate.getDateObject");
	var dataJs = new Date( this.getFullYear(), this.getMonth()-1, this.getDate());
	if ( this.getMonth() == dataJs.getMonth()+1 && this.getDate() == dataJs.getDate() && this.getFullYear() == dataJs.getFullYear()) {
		return dataJs;
	} else {
		return null;
	}
};


DepartureDate.prototype.getMonth = function () {
	log.debug("DepartureDate.getMonth");
	return parseInt ( this.bookingForm.frommonth.value,10 );
};

DepartureDate.prototype.setMonth = function (month) {
	log.debug("DepartureDate.setMonth");
	if (this.BFC.type == "hidden" ) {
		this.bookingForm.frommonth.value = month;
	} else {
		this.bookingForm.frommonth.selectedIndex = month - 1;
	}
};

DepartureDate.prototype.getDate = function () {
	log.debug("DepartureDate.getDate");
	return parseInt ( this.bookingForm.fromday.value,10);
};

DepartureDate.prototype.setDate = function (day) {
	log.debug("DepartureDate.setDate");
	if (this.BFC.type == "hidden" ) {
		this.bookingForm.fromday.value = day;
	} else {
		this.bookingForm.fromday.selectedIndex = day - 1;
	}
};

DepartureDate.prototype.getFullYear = function () {
	log.debug("DepartureDate.getFullYear");
	return parseInt ( this.bookingForm.fromyear.value,10);
};

DepartureDate.prototype.setFullYear = function (year) {
	log.debug("DepartureDate.setFullYear");
	if (this.BFC.type == "hidden" ) {
		this.bookingForm.fromyear.value = year;
	} else {
		this.bookingForm.fromyear.selectedIndex = year - new Date().getFullYear();
	}
};

DepartureDate.prototype.initializeBf = function() {
	log.debug("DepartureDate.initializeBf");
	var cur_date = new Date();
	if (this.BFC.type == "hidden" ) {
		
		this.setDate(cur_date.getDate());
		this.setMonth(cur_date.getMonth()+1);
		this.setFullYear(cur_date.getFullYear());
		return;
	}
	var cur_year = cur_date.getFullYear();
		
	var cur_yb = new Option(cur_year, cur_year, true, true);
	this.form.toyear.options[0] = cur_yb;
	var next_yb = new Option(cur_year + 1, cur_year + 1, false, false);
	this.form.toyear.options[1] = next_yb;
	
	this.bookingForm.fromday.length = 0;
	// Creating the days options.
	for (var i=1; i<=31; i++) {
		var cur_opt = null;
		if (i==1) {
			cur_opt = new Option(i, i, true, true);
		} else {
			cur_opt = new Option(i, i, false, false);
		}
		this.bookingForm.fromday.options[i-1] = cur_opt;
	}
	
	// setto gli onchange;
	var tmp1 = this.bookingForm.fromday.onchange;
	var fblibInstance2 = this.fblibInstance;
	this.bookingForm.fromday.onchange = function() {
		tmp1();
		fblibInstance2.updateDeparture();
	}
	
	var tmp2 = this.bookingForm.frommonth.onchange;
	this.bookingForm.frommonth.onchange = function() {
		tmp2();
		fblibInstance2.updateDeparture();
	}
	
	var tmp3 = this.bookingForm.fromyear.onchange;
	this.bookingForm.fromyear.onchange = function() {
		tmp3();
		fblibInstance2.updateDeparture();
	}
	
};
/**
* DepartureDateNbNights object constructor
* @param FBBFDates ArrivalDate .
*/
function DepartureDateNbNights(arrivalDate, bookingFormConfiguration, fblibInstance) {
	log.debug("DepartureDateNbNights.constructor");
	this.arrivalDate = arrivalDate;
	this.bookingForm = Fblib.getFormFromIDorName(bookingFormConfiguration.formId);
	this.fblibInstance = fblibInstance;
}
DepartureDateNbNights.prototype = new FBBFDates();
DepartureDateNbNights.prototype.constructor = DepartureDateNbNights;

DepartureDateNbNights.prototype.getDateObject = function () {
	log.debug("DepartureDateNbNights.getDateObject");
	var ad= this.arrivalDate.getDateObject();
	if (ad=== null ) {
		return null;
	}
	ad.addDays(this.bookingForm.nbdays.selectedIndex+1);
	return ad;
};

DepartureDateNbNights.prototype.setDateObject = function (data) {
	log.debug("DepartureDateNbNights.setDateObject");
	if (data === null) {
		return false;
	}
	var currentDate = this.getDateObject();
	if (currentDate === null ) {
		return false;
	}
	
	var one_day = 1000*60*60*24;
	var days_more = 0;
	
	// this if is neede due to Math.ceil behaviour.
	if ( data < currentDate ) {
		days_more = - Math.floor( (currentDate.getTime() - data.getTime())/one_day);
	} else {
		days_more = Math.floor( (data.getTime() - currentDate.getTime())/one_day);
	}
	
	if ( days_more + this.bookingForm.selectedIndex+1 > 31  || days_more + this.bookingForm.selectedIndex+1 < 1) {
		return false;
	} else {
		// Going to insert :)
		this.bookingForm.nbdays.selectedIndex = this.bookingForm.nbdays.selectedIndex + days_more;
		return true;
	}
	
	
};

DepartureDateNbNights.prototype.initializeBf = function() {
	log.debug("DepartureDateNbNights.initializeBf");
	// rimuovo tutte le opzioni :Source : http://blog.techsaints.com/2007/08/12/how-to-remove-all-options-from-a-dropdown-select-box-with-javascript/
	this.bookingForm.nbdays.length=0;
	
	for (var i=1; i<=31; i++) {
		var cur_opt = null;
		if (i==1) {
			cur_opt = new Option(i, i, true, true);
		} else {
			cur_opt = new Option(i, i, false, false);
		}
		this.bookingForm.nbdays.options[i-1] = cur_opt;
	}
	
	// setto gli onchange;
	var tmp1 = this.bookingForm.fromday.onchange;
	var fblibInstance2 = this.fblibInstance;
	this.bookingForm.fromday.onchange = function() {
		if ( typeof tmp1 == 'undefined' || tmp1 === null ) {
			log.debug('DepartureDateNbNights.iniitializeBf tmp1 is undefined');
		} else {
			tmp1();
		}
		fblibInstance2.updateDeparture();
	}
	
	var tmp2 = this.bookingForm.frommonth.onchange;
	this.bookingForm.frommonth.onchange = function() {
		if ( typeof tmp2 == 'undefined' || tmp2 === null ) {
			log.debug('DepartureDateNbNights.iniitializeBf tmp2 is undefined');
		} else {
			tmp2();
		}
		fblibInstance2.updateDeparture();
	}
	
	var tmp3 = this.bookingForm.fromyear.onchange;
	this.bookingForm.fromyear.onchange = function() {
		if (typeof tmp3 == 'undefined' || tmp3 === null ) {
			log.debug('DepartureDateNbNights.iniitializeBf tmp3 is undefined');
		} else {
			tmp3();
		}
		fblibInstance2.updateDeparture();
	}
	
};
/*****
 * Copyright b,g @ FASTBOOKING  1999-2010
 * 2010
 *
*/
var Fblib;
/**
* Fblib constructor. 
* @constructor
* @version 1
*/
function Fblib(bookingFormConfiguration) {
	log.debug("Fblib constructor");
	this.form = Fblib.getFormFromIDorName(bookingFormConfiguration.formId);
	if ( bookingFormConfiguration.nbnights === true ) {
		this.arrivalDate = new ArrivalDate(bookingFormConfiguration);
		this.departureDate = new DepartureDateNbNights(this.arrivalDate, bookingFormConfiguration,  this);
	} else {
		if (bookingFormConfiguration.haveNights !== undefined || bookingFormConfiguration.haveNights=== false ) {
			this.arrivalDate= new ArrivalDate(bookingFormConfiguration);
		} else {
			this.arrivalDate= new ArrivalDate(bookingFormConfiguration);
			this.departureDate = new DepartureDate(this.arrivalDate, bookingFormConfiguration, this);
		}
	}
}
Fblib.getFblibInstance = function ( name ) {
	return FblibConf.bookingForms[name];
};
Fblib.setFblibInstance = function ( name, bfConfiguration ) {
	log.debug("Fblib.setFblibInstance("+name+")");
	var tmp = new Fblib(bfConfiguration);
	FblibConf.bookingForms[name] = tmp;
	return tmp;
};
Fblib.getFormFromIDorName = function (formId ) {
	log.debug("getFormFromIDOrName("+formId+")");
	var allForms = document.getElementsByTagName("form");
	var bookingForm = null;
	for (var i=0; allForms !== undefined && i< allForms.length ; i++) {
		if (allForms.item(i).getAttribute("name") == formId ) {
			bookingForm = allForms.item(i);
			break;
		}
	}
	if ( bookingForm === null )  {
		bookingForm = document.getElementById(formId);
	}
	return bookingForm;
	
};
/**
* Static method we should invoke instead of calling the constructor
*/
Fblib.get = function() {
	log.debug("Fblib.get");
	if (Fblib.instance === undefined || Fblib.instance === null ) {
		var oldLoad = window.onload;
		

		window.onload = function () {
			Fblib.instance = new Fblib(FblibConf.bookingForm); 
			FblibConf.bookingForms.defaultBf= Fblib.instance ;
			
			Fblib.instance.start();
			if (oldLoad !== undefined && oldLoad !== null ) {
				oldLoad();
			}
		};
	}	
	
	return Fblib.getFblibInstance('defaultBf');
};

/**
* FastBooking language code.
* Array containing the Fastbooking LangCodes.
* @see Fblib#hhotelLang2Img
*/
Fblib.FBLangCode = [
 "uk", "france", "germany", "spain", "portuguese", "italy", "nether", "russian",
 "dansk", "svensk", "islensk", "norsk", "turk", "hungria", "greek", "arab",
 "china", "coreen", "japan","croate","czech","poland"];

/**
* FastBooking image code.
* Array containing the LangIMG codes.
* @see Fblib#hhotelLang2Img
*/
Fblib.FBLangImg = [
 "grandbret", "france", "germany", "spain", "portuguese", "italy", "nether", "russia",
 "denmark", "sweeden", "iceland", "norway", "turkey", "hungary", "greek", "arab",
 "china", "coreen", "japan","croate","czech","poland"];

/**
* FastBooking langcodes.
* Array containing the Fastbooking Langcodes, used for match the browser language.
* @see Fblib#selectLang
*/
Fblib.langcodes = ["en", "uk", "fr", "france", "de", "germany", "es", "spain ", "pt", "portuguese", "it", "italy", "nl", "nether", "ja", "japan ", "ko", "coreen", "zh", "china", "ar", "arab", "ru", "russian", "tr", "turk", "el", "greek", "hu", "hungria", "da", "dansk", "sv", "svensk", "is", "islensk", "no", "norsk", "hr", "croate", "cs", "czech", "pl", "poland", "iw", "hebrew"];


/**
* Some function regarding the fidelity program
* @todo To document
*/
Fblib.hhotelProfil = function(code_interface, profil) {
	log.debug("Fblib.hhotelProfil");
	FblibConf.FB_code_interface = code_interface;
	FblibConf.FB_profil = profil;
};



/**
* Start the process
* @todo DOCUMENT
*/
Fblib.prototype.start = function() {
	log.debug("Fblib.start");		
	this.arrivalDate.initializeBf();
	this.departureDate.initializeBf();

	var tmpAd= new Date();
	tmpAd.addDays(FblibConf.FB_nb_day_delay);
	this.arrivalDate.setDateObject(tmpAd);
	
	var tmpDd = new Date();
	tmpDd.addDays(FblibConf.FB_nb_day_delay+1);
	this.departureDate.setDateObject(tmpDd);
	
};

/**
* [S] VALIDATED
* Generate the session 
* Used by the following functions:
* - hhotelFormValidation ()
* - fbOpenWindow ()
*/
Fblib.generateSession = function() {
	log.debug("Fblib.generateSession");		
	var time = new Date();
	var sec  = time.getSeconds();
	var f = Math.floor(Math.random() * 1000000000) + '';
	var sess = '' + sec + f;
	return sess;
};

/**
* [S] VALIDATED
* Transfer the GA data through pageTracker 
* We've to use the asynchronous code ( find the code on villaigiea ) 
*
* Used by the following functions : 
* - hhotelFormValidation ()
* - fbOpenWindow ()
* @todo fare figata del tracking
*/
Fblib.transferGAdata = function(sessId, cname) {
	log.debug("Fblib.transferGAdata");		
	var waction = FblibConf.FBRESA + "ga.phtml?clusterName="+cname + "&id=" + sessId;
	if ( FblibConf.googleAnalytics.asynch === false ) {
		var img_ga = new Image();
		img_ga.src = window[FblibConf.googleAnalytics.varName]._getLinkerUrl(waction);
		window[FblibConf.googleAnalytics.varName]._trackPageview('/FastBooking/ClicBook'); 
	} else {
		var tmpImage = new Image();
		tmpImage.src = _gaq.push(['_getLinkerUrl',waction]);
		_gaq.push(['_trackPageview','/FastBooking/ClicBook']);
	}
};

/**
* [S] VALIDATED
* This function will open the popup
* @param String cname this is the connect name of the hotel
* @param String waction this is the url of the popup
* @param String title this is the title of the popup
* @param Integer width the width of the popup
* @param Integer height the height of the popup
* Used by the following functions :
* - @see #popup
* - @see #hhotelSearchGrossSell
* - @see #hhotelSearch
* - @see #hhotelResa
* - @see #hhotelcheckrates
* - @see #hhotelExtract
* - @see #hhotelcancel
*/
Fblib.fbOpenWindow = function (cname, waction, title, width, height) {
	log.debug("Fblib.fbOpenWindow ");		
	if (FblibConf.FB_profil != "") {
		waction += "&code="+FblibConf.FB_code_interface;
		waction += "&profil="+FblibConf.FB_profil;
	}
	
	if (FblibConf.googleAnalytics.useGa === true) {
		var sessId = Fblib.generateSession();
		Fblib.hhotelProfil("GoogleAnalytics", escape("SESSION=" + sessId));
		Fblib.transferGAdata(sessId, cname);
	}
	
	window.open(waction, title, "toolbar=no,width=" + width + ",height=" + height +",menubar=no,scrollbars=yes,resizable=yes,alwaysRaised=yes");
};

/**
* 
* [S] VALIDATED
* @deprecated 
* @param String cname The connect name
* @param String lg The language slug
* @param String codeprice
* @param String codetrack Alfanumeric code that will let us track different sources (needs to be added on server before)
* @param String cluster Cluster name ?
* @see #hhotelResa
*/
Fblib.hhotelPTC = function (cname, lg, codeprice, codetrack, cluster) {
	log.debug("Fblib.hhotelPTC");		
	Fblib.hhotelResa(cname, lg, codeprice, "", "", codetrack, cluster, "", "");
};

/**
* [S] VALIDATED
* Standard promotion function
* @param String cname The connect name
* @param String lg The language slug
* @param Int theme Number of the Theme (1-10?)
* @see #hhotelResa
*/
Fblib.hhotelPromo = function (cname, lg, theme) {
	log.debug("Fblib.hhotelPromo");		
	Fblib.hhotelResa(cname, lg, "DYNPROMO", "", "", "", "", theme, "");
};

/**
* [S] VALIDATED
* Reservation promotion function: To show one promotion
* @param String cname The Connect name
* @param String codeprice Code for offers default selection
* @param String codetrack Alfanumeric code that will let us track different sources (needs to be added on server before)
* @param String cluster Cluster name
* @see Fblib#hhotelResa
*/
Fblib.hhotelOnePromo = function (cname, lg, codeprice, codetrack, cluster) {
	log.debug("Fblib.hhotelOnePromo");		
	Fblib.hhotelResa(cname, lg, codeprice, "", "", codetrack, cluster, "", "style=DIRECTPROMO");
};

/**
* [S] VALIDATED
* Reservation page WITHOUT the individual access
* @param String cname The Connect Name
* @param String lg The language slug
* @param String codeprice Code for offers default selection
* @param String codetrack Alfanumeric code that will let us track different sources (needs to be added on server before)
* @param String cluster Cluster Name
* @see #hhotelResa
*/
Fblib.hhotelNegociated = function(cname, lg, codeprice, codetrack, cluster) {
	log.debug("Fblib.hhotelNegociated");		
	Fblib.hhotelResa(cname, lg, codeprice, "", "", codetrack, cluster, "", "negociated=1");
};

/**
* Main direct reservation function
* [S] VALIDATED
* @param String cname The connect name
* @param String lg the language slug
* @param String codeprice Code for offers default selection
* @param String firstroom Alfanumeric code that will let you chose that room
* @param String codetrack Alfanumeric code that will let us track different sex
* @param String firstdate the date to start YYMMDD
* @see #hhotelResa
*/
Fblib.hhotelResaDirect= function(cname, lg, codeprice, firstroom, codetrack, firstdate) {
	log.debug("Fblib.hhotelResaDirect");		
	Fblib.hhotelResa(cname, lg, codeprice, firstroom, firstdate, codetrack, "", "", "style=DIRECT");
};

/**
* [S] VALIDATED
* Standard search availabilities in a group
* @param String cluster the cluster name
* @param String lg language slug
* @param String price ACCESSCODE
* @param Integer nights the number of nights
* @param String title The title of the popup == CRSTITLE
* @see #hhotelSearch
*/
Fblib.hhotelSearchGroup = function(cluster, lg, price, nights, title) {
	log.debug("Fblib.hhotelSearchGroup");		
	Fblib.hhotelSearch(cluster, lg, price, nights, title, "", "");
};

/**
* [S] VALIDATED
* standard search availabilities in a group for a partner
* @param String cluster the cluster name
* @param String lg the language slug
* @param String price ACCESSCODE
* @param String codetrack The Source tracking code
* @param String title The title of the popup
* @see #hhotelSearch
*/
Fblib.hhotelSearchPartner = function(cluster, lg, price, codetrack, title) {
	log.debug("Fblib.hhotelSearchPartner");		
	var args = "";
	if (codetrack != "") {
		args = "&from="+codetrack;
	}
	else {
		args = "";
	}
	Fblib.hhotelSearch(cluster, lg, price, "", title, "", args);
};

/**
* [S] VALIDATED
* search by giving the initial date
* @param String cluster the cluster name
* @param String price the price
* @param String nights the number of nights
* @param String firstdate the date to start YYMMDD
* @see #hhotelSearch
*/
Fblib.hhotelSearchPriceDate = function(cluster, price, nights, title, firstdate) {
	log.debug("Fblib.hhotelSearchPriceDate");		
	var args="";
	if (firstdate != "") {
		args = "FirstDate="+firstdate;
	}
	Fblib.hhotelSearch(cluster, "", price, nights, title, "", args);
};

/**
* [S] VALIDATED
* Search by date and tracks by source
* @param String cluster the cluster name
* @param String lg language slug
* @param String price ACCESSCODE
* @param String codetrack 
* @param String codetrack The Source tracking code
* @param Integer nights the number of nights
* @param String title The title of the popup
* @param Integer nights the number of nights
* @see #hhotelSearch
*/
Fblib.hhotelSearchPriceDateTrack = function(cluster, lg, price, codetrack, nights, title, firstdate) {
	log.debug("Fblib.hhotelSearchPriceDateTrack");		
	var args="";
	if (codetrack != "") {
		args = "from="+codetrack;
	}
	if (firstdate != "") {
		args += "&FirstDate="+firstdate;
	}
	Fblib.hhotelSearch(cluster, lg, price, nights, title, "", args);
};

/**
* search availabilities for selected promotions
* [S] VALIDATED
* @param String cluster the cluster name
* @param String lg the language slug
* @param int theme da 1 a 9
* @see #hhotelSearch
*/
Fblib.hhotelSearchPromo = function(cluster, lg, theme) {
	log.debug("Fblib.hhotelSearchPromo");
	Fblib.hhotelSearch(cluster, lg, "", "", "", theme, "");
};

/**
* search availabilities with Extra Field
* [S] VALIDATED
* @param String cluster the cluster name
* @param String lg the language slug
* @param String price ACCESSCODE
* @param String codetrack The Source tracking code
* @param String extratitle This should be another title?
* @param String extrashow ???????????
* @see #hhotelSearch
*/
Fblib.hhotelSearchExtra = function(cluster, lg, price, codetrack, extratitle, extraval, extrashow) {
	log.debug("Fblib.hhotelSearchExtra");
	var args = "Extrafield=" + escape(extratitle) + ";" + extraval + ";" + extrashow;
	if (codetrack != "") {
		args += "&from="+codetrack;
	}
	Fblib.hhotelSearch(cluster, lg, price, "", "", "", args);
};

/**
* go to the cancel reservation page
* [S] VALIDATED
* @param String cname the cluster name
* @param String lg the language slug
* @see #fbOpenWindow
*/
Fblib.hhotelcancel = function(cname,lg) {
	log.debug("Fblib.hhotelcancel");
	var waction = FblibConf.FBRESA + "cancel.phtml?state=77&Hotelnames="+cname;
	if (lg != "") {
		waction += "&langue="+lg;
	}
	Fblib.fbOpenWindow(cname, waction, "reservation", 400, 350);
};

/**
* go to the extract reservation page
* [S] VALIDATED
* @param String cname the cluster name
* @param String lg the language slug
* @see #fbOpenWindow
*/
Fblib.hhotelExtract = function(cname, lg) {
	log.debug("Fblib.hhotelExtract");
	var waction = FblibConf.FBRESA + "getresa.phtml?Hotelnames="+cname+"&langue="+lg;
	Fblib.fbOpenWindow(cname, waction, "getresa", 700, 300);
	
	return false;
};

/**
*  check interface
* [S] VALIDATED
* [S] Automatic selection of a CRS with at least one promotion, otherwise goes to a standard book page
* @param String cname the cluster name
* @param String lg the language slug
* @see #fbOpenWindow
*/
Fblib.hhotelcheckrates = function(cname, lg) {
	log.debug("Fblib.hhotelcheckrates");
	var waction = FblibConf.FBRESA + "crs.phtml?clusterName="+cname;
	if (lg != "") {
		waction += "&langue="+lg;
	}
	waction += "&checkPromo=1";
	Fblib.fbOpenWindow(cname, waction, "search", 800, 550);
};


/**
*  Main standard reservation function MSP
* [S] VALIDATED
* [S] NOT DOCUMENTED
* @param String cname the cluster name
* @param String lg the language slug
* @param String codeprice ACCESSCODE
* @param String firstroom Alfanumeric code that will let you chose that room
* @param String firstdate the date to start YYMMDD
* @param String codetrack Alfanumeric code that will let us track different sources (needs to be added on server before)
* @param Int theme Number of the Theme (1-10?)
* @param String args "The argument args supports other variables that are not described in this manual"
* @param String mastercluster ?????????????
* @param Int cartID id of the cart ?????????????
* @see #hhotelResa
*/
Fblib.hhotelResaMSP = function (cname, lg, codeprice, firstroom, firstdate, codetrack, cluster, theme, args, mastercluster, cartID) {
	log.debug("Fblib.hhotelResaMSP");
	if (mastercluster != "") {
		args += "&mastercluster=" + mastercluster;
	}
	if (cartID != "") {
		args += "&cartID=" + cartID;
	}
	Fblib.hhotelResa(cname, lg, codeprice, firstroom, firstdate, codetrack, cluster, theme, args);
};


/**
*  Main Search function MSP
* [S] VALIDATED
* [S] NOT DOCUMENTED
* @param String cluster the cluster name
* @param String lg the language slug
* @param String price ACCESSCODE
* @param Integer nights the number of nights
* @param String title this is the title of the popup
* @param Int theme Number of the Theme (1-10?)
* @param String args "The argument args supports other variables that are not described in this manual"
* @param String mastercluster ?????????????
* @param Int cartID id of the cart ?????????????
* @see #hhotelSearch
*/
Fblib.hhotelSearchMSP = function (cluster, lg, price, nights, title, theme, args, mastercluster, cartID) {
	log.debug("Fblib.hhotelSearchMSP");
	if (mastercluster != "") {
		args += "&mastercluster=" + mastercluster;
	}
	if (cartID != "") {
		args += "&cartID=" + cartID;
	}
	Fblib.hhotelSearch(cluster, lg, price, nights, title, theme, args);
};


/**
* Main standard reservation function
* [S] VALIDATED
* @param String cname the connect name
* @param String lg the language slug
* @param String codeprice ACCESSCODE
* @param String firstroom Alfanumeric code that will let you chose that room
* @param String firstdate the date to start YYMMDD
* @param String codetrack Alfanumeric code that will let us track different sources (needs to be added on server before)
* @param String cluster the cluster name
* @param Int theme Number of the Theme (1-10?)
* @param String args "The argument args supports other variables that are not described in this manual"
* @see #fbOpenWindow
*/
Fblib.hhotelResa = function (cname, lg, codeprice, firstroom, firstdate, codetrack, cluster, theme, args) {
	log.debug("Fblib.hhotelResa");
	var waction = FblibConf.FBRESA+"preresa.phtml?Hotelnames="+cname;
	if (lg != "") {
		waction += "&langue="+lg;
	}
	if (firstroom != "") {
		waction += "&FirstRoomName="+firstroom;
		if (codeprice == "") {
			codeprice = "DIRECT";
		}
	}
	if (firstdate != "") {
		waction += "&FirstDate="+firstdate;
		if (codeprice == "") {
			codeprice = "DIRECT";
		}
	}
	if (codeprice != "") {
		waction += "&FSTBKNGCode="+codeprice;
	}
	if (codetrack != "") {
		waction += "&FSTBKNGTrackLink="+codetrack;
	}
	if (cluster != "") {
		waction += "&clustername="+cluster;
	}
	if (theme != "") {
		waction += "&theme="+theme;
	}
	if (args != "" && (args.indexOf("=")!= -1) ) {
		waction += "&"+args;
	}
	waction += "&HTTP_REFERER="+escape(document.location.href);
	Fblib.fbOpenWindow(cname, waction, "reservation", 400, 350);
	
};


/**
* Main Search function
* [S] VALIDATED
* @param String cluster the cluster name
* @param String lg the language slug
* @param String price ACCESSCODE
* @param Integer nights the number of nights
* @param String title this is the title of the popup
* @param Int theme Number of the Theme (1-10?)
* @param String args "The argument args supports other variables that are not described in this manual"
* @see #fbOpenWindow
*/
Fblib.hhotelSearch = function (cluster, lg, price, nights, title, theme, args) {
	log.debug("Fblib.hhotelSearch");
	var waction = FblibConf.FBRESA + "crs.phtml?clusterName="+cluster;
	if (lg != "") {
		waction += "&langue="+lg;
	}
	if (price != "") {
		waction += "&FSTBKNGCode="+price;
	}
	if (nights != "") {
		waction += "&nights="+nights;
	}
	if (title != "") {
		waction += "&title="+escape(title);
	}
	if (theme != "") {
		waction += "&theme="+theme;
	}
	if (args != "" && (args.indexOf("=")!= -1) ) {
		waction += "&"+args;
	}
	Fblib.fbOpenWindow(cluster, waction, "search", 800, 550);
};


/**
* Main Search function for Multi Codes
* [S] Show all prices who code is "MULT-" or "PROMO-MULT-" --> Useless for websites because are private rates?!
* [S] VALIDATED
* @param String cluster the cluster name
* @param String lg the language slug
* @param String clecode MULTCODE
* @param String title this is the title of the popup
* @param String codetrack Alfanumeric code that will let us track different sources (needs to be added on server before)
* @see #fbOpenWindow
*/
Fblib.hhotelSearchMultCode = function(cluster, lg, clecode, title, codetrack) {
	log.debug("Fblib.hhotelSearchMultCode");
	var waction = FblibConf.FBRESA + "crs.phtml?clusterName="+cluster;
	if (lg != "") {
		waction += "&langue="+lg;
	}
	if (clecode != "") {
		waction += "&AccessCode="+clecode;
	}
	if (title != "") {
		waction += "&title="+escape(title);
	}
	if (codetrack != "") {
		waction += "&FSTBKNGTrackLink="+codetrack;
	}
	waction += "&crossSelling=NO"; // CROSS SELLING DEACTIVATED
	Fblib.fbOpenWindow(cluster, waction, "search", 800, 550);
	
};


/**
* Main Search function for Cross Selling
* [S] Cross Selling - buy another product
* [S] VALIDATED
* @param String cluster the cluster name
* @param String lg the language slug
* @param String codetrack Alfanumeric code that will let us track different sources (needs to be added on server before)
* @param String crossSelling NOMCROSSSELLING
* @see #fbOpenWindow
*/
Fblib.hhotelSearchCrossSell = function(cluster, lg, codetrack, crossSelling) {
	log.debug("Fblib.hhotelSearchCrossSell");
	var waction = FblibConf.FBRESA + "crs.phtml?clusterName="+cluster;
	if (lg != "") {
		waction += "&langue="+lg;
	}
	if (codetrack != "") {
		waction += "&FSTBKNGTrackLink="+codetrack;
	}
	if (crossSelling != "") {
		waction += "&crossSelling="+crossSelling;
	}
	Fblib.fbOpenWindow(cluster, waction, "search", 800, 550);
};


/**
* MAIN AVAILABILITY CHECK 
* [S] Result page of a hotel (wtf?)
* [S] VALIDATED
* @param String cname the connect name
* @param String lg the language slug
* @param String codetrack Alfanumeric code that will let us track different sources (needs to be added on server before)
* @param Int year The Year
* @param Int month The Month
* @param Int day The day
* @param Int nights Nb. of Nights
* @param String currency The Currency (EUR, AUD, etc.)
* @see #fbOpenWindow
*/
Fblib.hhotelDispopriceFHP = function(cname, lg, codetrack, year, month, day, nights, currency) {
	log.debug("Fblib.hhotelDispopriceFHP");
	var waction = FblibConf.FBRESA+"dispoprice.phtml?clusterName="+cname+"&Hotelnames="+cname;
	if (lg != "") {
		waction += "&langue="+lg;
	}
	if (codetrack != "") {
		waction += "&FSTBKNGTrackLink="+codetrack;
	}
	if (year != "") {
		waction += "&fromyear="+year;
	}
	if (month != "") {
		waction += "&frommonth="+month;
	}
	if (day != "") {
		waction += "&fromday="+day;
	}
	if (nights != "") {
		waction += "&nbdays="+nights;
	}
	if (currency != "") {
		waction += "&CurrencyLabel="+currency;
	}
	waction += "&showPromotions=3";
	Fblib.fbOpenWindow(cname, waction, "reservation", 750, 600);
};


///////////////////////////////////////////////////////////////////////////////////////
// Form functions

/**
* Simple form validation (used for compatibility issues)
* [S] VALIDATED
* @param Obj myForm Document Object
* @see #hhotelFormValidation
*/
Fblib.prototype.hhotelDispoprice = function() {
	log.debug("Fblib.hhotelDispoprice");
	this.hhotelFormValidation(0);
};


/**
* Form validation with control
* @param Int mandatoryCode Mandatory Code next to useless
* @see #transferGAdata
*/
Fblib.prototype.hhotelFormValidation = function (mandatoryCode){
	log.debug("Fblib.hhotelFormValidation");
	var sessId="";
	if (mandatoryCode == 1 && this.form.AccessCode.value == "") {
		alert("You must type in your code ID");
		return (false);
	}
	// Set form action
	this.form.action = FblibConf.FBRESA + "dispoprice.phtml";
	if (FblibConf.googleAnalytics.useGa === true) {	
		sessId = Fblib.generateSession();
		var profilValue = escape("SESSION=" + sessId + "&CODE=GoogleAnalytics");
		if ( this.form.profil === undefined) {
			var newInput = document.createElement("input");
			newInput.setAttribute("type", "hidden");
			newInput.setAttribute("name", "profil");
			newInput.setAttribute("value", profilValue);
			this.form.appendChild(newInput);
		} else {
			this.form.profil.value = profilValue;
		}
	}
	window.open('','dispoprice', 'toolbar=no,width=800,height=550,menubar=no,scrollbars=yes,resizable=yes');
	this.form.submit();
	if (FblibConf.googleAnalytics.useGa) {
		var cname = "";
		if ( this.form.AccountName !== undefined && this.form.AccountName.value != "") {
			cname = this.form.AccountName.value;
		}
		else {
			cname = this.form.Clusternames.value;
			Fblib.transferGAdata(sessId, cname);
		}
	}
	return true;
};


/**
* Form: update the selected hotel name
*/
Fblib.prototype.hhotelFormUpdateHotelnames = function () {
	log.debug("Fblib.hhotelFormUpdateHotelnames");
	var menuNum = this.form.HotelList.selectedIndex;
	if (menuNum === null) {
		return;
	}
	this.form.Hotelnames.value = this.form.HotelList.options[menuNum].value;
};


/**
* Form: show the cancel page
* @param Obj myForm Document Object
* @see #hhotelcancel
*/
Fblib.prototype.hhotelFormCancel = function(){
	log.debug("Fblib.hhotelFormCancel");
	var CName = this.form.Hotelnames.value;
	var languetype = typeof this.form.langue;
	var langue;
	if (languetype === undefined) {
		langue = "";
	}
	else {
		langue = this.form.langue.value;
	}
	if (CName === null || CName == 'All' || CName == ''){ alert('Please select a hotel first'); return (false); }
	return Fblib.hhotelcancel(CName, langue);
};


/**
* Form: show the extract page
* @param Obj myForm Document Object
* @see #hhotelExtract
*/
Fblib.prototype.hhotelFormExtract = function() {
	log.debug("Fblib.hhotelFormExtract");
	var CName = this.form.Hotelnames.value;
	var languetype = typeof this.form.langue;
	var langue;
	if (languetype === undefined) {
		langue = "";
	}
	else {
		langue = this.form.langue.value;
	}
	if (CName === null || CName == 'All' || CName == ''){ alert('Please select a hotel first'); return (false); }
	return Fblib.hhotelExtract(CName, langue);
};


/**
* Form: show languages
* @param String lang The Lang in Languages Codes
* @see #hhotelShowLang__
* @todo check if it works
*/
Fblib.hhotelShowLang = function(lang) {
	log.debug("Fblib.hhotelShowLang");
	Fblib.hhotelShowLang__(window.document, lang);
};

/**
* Form: show languages opening popup
* @param String lang The Lang in Languages Codes
* @see #hhotelShowLang__
*/
Fblib.hhotelShowLangOpener = function (lang) {
	log.debug("Fblib.hhotelShowLangOpener");
	Fblib.hhotelShowLang__(window.opener.document, lang);
	window.close();
};

/**
* Form: show languages opening popup
* @param Obj mydoc Document Object
* @param String lang The Lang in Languages Codes
* Used by: 
* - hhotelShowLang
* - hhotelShowLangOpener
*/
Fblib.prototype.hhotelShowLang__ = function(mydoc, lang) {
	log.debug("Fblib.hhotelShowLang__");
	this.form.langue.value=lang;

	var imgLang = Fblib.hhotelLang2Img(lang);
	if (imgLang != "") {
		var formFlag = mydoc.selLgFlag;
		if (formFlag !== null) {
			mydoc.selLgFlag.src= "fastbooking/flags/"+imgLang+".gif";
		}
		formFlag = mydoc.selLgTxt;
		if (formFlag !== null) {
			mydoc.selLgTxt.src= "fastbooking/flags/"+imgLang+"lg.gif";
		}
	}
};

/**
* Return the image from the language using the previous array.
* @param String lang The Lang in Languages Codes
* @see Fblib#FBLangCode
* @see Fblib#FBLangImg
*/
Fblib.hhotelLang2Img = function(lang)  {
	log.debug("Fblib.hhotelLang2Img");
	var i;
	for(i = 0; i < Fblib.FBLangCode.length; i++) {
		if (Fblib.FBLangCode[i] == lang) {
			break;
		}
	}
	return Fblib.FBLangImg[i];
};

/**
* Open popup with language selection
*/
Fblib.hhotelLangSelector = function() {
	log.debug("Fblib.hhotelLangSelector");
	window.open('fastbooking/flags/langSelector.html', '', 'width=330,height=180');
};

/**
* VALIDATED
* Extract the language of the Browser!
*/
Fblib.selectLang = function () {
	log.debug("Fblib.selectLang");
	var UL;
	if (navigator.appName == "Microsoft Internet Explorer") { UL = navigator.userLanguage.substring(0, 2); }
	else if(navigator.appName == "Netscape") { UL = navigator.language; }
	else { return; }
	var i;
	for(i = 0; i < Fblib.langcodes.length; i += 2) {
		if(UL == Fblib.langcodes[i]) {
			break;
		}
	}
			
	var lang = (i < Fblib.langcodes.length) ? Fblib.langcodes[i+1] : "uk";
	Fblib.hhotelShowLang(lang);
};


	
/**
* Sets the departure date to +1 each time the arrivaldate is changed
* This is the old <strong>check_departure</strong>
* 
*/
Fblib.prototype.correctDeparture = function () {
	log.debug("Fblib.correctDeparture");
	this.departureDate.addDays(1);
};

/**
* This function tries to understand if the dates are correct, if not it will call check_departure
* @see ArrivalDate#getDateObject
* @see DepartureDate#getDateObject
*/
Fblib.prototype.updateDeparture = function () {
	log.debug("Fblib.updateDeparture");
	var arrivalDateObject = this.arrivalDate.getDateObject();
	var departureDateObject = this.departureDate.getDateObject();
	
	
	// If the dates are unavailable ( see getDateObject ) or they are incongruent ( departure date before arrival )
	if (arrivalDateObject === null || departureDateObject === null || departureDateObject <= arrivalDateObject ) {
		this.correctDeparture();
	}
	

};


/**
* @deprecated
* popup for quicksearch flash
* @param String url the url to open in the booking-popup
* @see #fbOpenWindow
*/
Fblib.popup = function(url) {
	log.debug("Fblib.pupup");
	Fblib.fbOpenWindow("", url, "", 800, 550);
};

// Initialize the default booking form
Fblib.get();