// script dependent on/depended by searchform.inc.php for form to work
// requires jquery, jquery-ui, jquery.cookie
// contains object definitions and HTML DOM methods to manipulate form based on user input


// variable and object initialisation

var defaultCheckInDaysInFuture = 14;
var autocompleteData, searchCityId = false;
var skipCheckoutWarning = false;
var roomsObj = {
	rooms : [ new roomObj(0) ],
	numRooms : 1,
	init : initRooms,
	showRooms : showRooms,
	setHandlers : setHandlers,
	clearForm : function() {
		$.cookie('j1h_srch', null, { path : '/' });
		$('#errorDialogues div').dialog('disable');
		$('#siteSearch')[0].reset();
		this.rooms = [ new roomObj(0) ];
		this.numRooms = 1;
		this.init();
	}
};


// roomsObj object methods
function showRooms()
{
	$('#searchFormRooms').empty();
	for (var i=0; i<this.numRooms; i++)
	{
		$('#searchFormRooms').append(this.rooms[i].showRoom(i));
		$('#siteSearch select[name^="room_' + i + '_num"]').unbind().change(function() {
			var idSplit = $(this).attr('id').split('_');
			var quantifier = (idSplit[2]=='numchildren') ? 'numChildren' : 'numAdults';
			roomsObj.rooms[idSplit[1]][quantifier] = Number($(this).val());
			
			roomsObj.rooms[idSplit[1]].showRoomOptions(
				$('#room_' + idSplit[1] + '_type_container'),
				$('#room_' + idSplit[1] + '_childages')
			);

			roomsObj.setHandlers(idSplit[1]);
			$('#searchFormRooms select[name^="room_' + idSplit[1] + '"]').change(function() {
				$.cookie('j1h_srch', $("#siteSearch").serialize(), { path : '/' });
			});
		});
		this.setHandlers(i);
	}
	if (this.numRooms > 1)
	{
		$('#searchFormRooms [id$="_detail"]').addClass('roomDetail');
		$('#searchFormRooms .roomNumber').show();
	}
	$('#searchFormRooms select').change(function() {
		$.cookie('j1h_srch', $("#siteSearch").serialize(), { path : '/' });
	});
}


function setHandlers(roomNum)
{
	if (this.rooms[roomNum].numAdults < 3)
	{
		$('#room_' + roomNum + '_roomtype').unbind().change(function() {
			var idSplit = $(this).attr('id').split('_', 2);
			roomsObj.rooms[idSplit[1]].roomType = $(this).val();
		});
	}
	if (this.rooms[roomNum].numChildren > 0)
	{
		for (var i=0; i<this.rooms[roomNum].numChildren; i++)
		{
			$('#room_' + roomNum + '_childage_' + i).unbind().change(function() {
				var idSplit = $(this).attr('id').split('_');
				var roomNum = Number(idSplit[1]), ageNum = Number(idSplit[3]);
				roomsObj.rooms[roomNum].childAges[ageNum] = $(this).val();
			});
		}
	}
}


function initRooms()
{
	if ($.cookie('j1h_srch'))
	{
		var arr = $.cookie('j1h_srch').split('&'), keyVal, savedVals = {};
		for (var i=0; i<arr.length; i++)
		{
			keyVal = arr[i].split('=');
			savedVals[keyVal[0]] = decodeURIComponent(keyVal[1]).replace(/\+/g, ' ');
		}
		$('#numrooms_input').val(savedVals.numrooms).change();
		roomsObj.showRooms();
		for (i in savedVals)
		{
			$('#siteSearch [name="' + i + '"]').val(savedVals[i]).change();
		}
		if ($.cookie('formdest'))
		{
			$('#siteSearch').attr('action', $.cookie('formdest'));
		}
	}
	else
	{
		roomsObj.showRooms();
		// initialise form date by ajax to php script
		// avoids problems caused by bad time setting on user's machine
		$.get('index_elements/date.ajax.php', 'days='+defaultCheckInDaysInFuture, function(data) {
			var sel = $('#siteSearch :input[name="check_in_select"]');
			$(sel).val(data).change();
		});
		$.cookie('j1h_srch', $("#siteSearch").serialize(), { path : '/' });
	}
	
	$('#errorDialogues div').dialog({
		autoOpen : false,
		modal : true,
		width : 235,
		resizable : false,
		buttons: { Ok: function() { $( this ).dialog( "close" ); } }
	});
	
	$('#dest_input').click(function() {
		$(this).val('');
		$(this).focus();
		$(this).unbind('click');
	});
}




// roomObj object definitions for storing data relating to form inputs as obbject
// and building HTML DOM based on room choices

function roomObj(roomNum)
{
	this.roomNum = roomNum;
	this.childAges = [];
}

roomObj.prototype.numAdults = 2;
roomObj.prototype.numChildren = 0;
roomObj.prototype.roomType = 'TW';
roomObj.prototype.maxChildAge = 12;
roomObj.prototype.validRoomtypes =
{
	1 : { S : 'Single', TSU : 'Double (Sole Use)' },
	2 : { TW : 'Twin', DB : 'Double' },
	3 : 'Triple',
	4 : 'Quad'
};
roomObj.prototype.showRoom = showRoom;
roomObj.prototype.showRoomOptions = showRoomOptions;
roomObj.prototype.showChildAges = showChildAges;
roomObj.prototype.getGuests = getGuests;


// roomObj object methods

function showRoom()
{
	var rowDiv, div, typeDiv, agesDiv, input, opt;
	var roomDiv = $('<div/>').attr('id', 'room_' + this.roomNum + '_detail');

	rowDiv = $('<div/>').addClass('row');
	$(rowDiv).append('<div class="roomNumber">Room ' + (this.roomNum+1) + '</div>');
	div = $('<div/>').addClass('basicInput');
	input = $('<select/>').attr({
		id : 'room_' + this.roomNum + '_numadults',
		name : 'room_' + this.roomNum + '_numadults'
	});
	for (var a=1; a<=4; a++)
	{
		opt = $('<option value="' + a + '">' + a + '</option>');
		if (a==this.numAdults)
		{
			$(opt).attr('selected', true);
		}
		$(input).append(opt);
	}
	$(div).append(input);
	$(div).append('Adults');
	$(rowDiv).append(div);
	$(roomDiv).append(rowDiv);

	typeDiv = $('<div/>').addClass('row').attr('id', 'room_' + this.roomNum + '_type_container');
	$(roomDiv).append(typeDiv);
	
	rowDiv = $('<div/>').addClass('row');
	div = $('<div/>').addClass('basicInput');
	input = $('<select/>').attr({
		id : 'room_' + this.roomNum + '_numchildren',
		name : 'room_' + this.roomNum + '_numchildren'
	});
	for (var c=0; c<=2; c++)
	{
		opt = $('<option value="' + c + '">' + c + '</option>');
		$(input).append(opt);
		if (c==this.numChildren)
		{
			$(opt).attr('selected', true);
		}
	}
	$(div).append(input);
	$(div).append('Children');
	$(rowDiv).append(div);
	agesDiv = $('<div/>').addClass('childAges').attr('id', 'room_' + this.roomNum + '_childages');
	$(rowDiv).append(agesDiv);

	$(roomDiv).append(rowDiv);

	this.showRoomOptions(typeDiv, agesDiv);
	
	return roomDiv;
}


function showRoomOptions(typeDiv, agesDiv)
{
	var div, input, opt;
	div = $('<div/>').addClass('basicInput');
	switch (this.numAdults)
	{
		case 1 : case 2 :
			input = $('<select/>').attr({
				id : 'room_' + this.roomNum + '_roomtype',
				name : 'room_' + this.roomNum + '_type'
			});
			for (var i in this.validRoomtypes[this.numAdults])
			{
				opt = $('<option value="' + i + '">' + this.validRoomtypes[this.numAdults][i] + '</option>');
				if (i==this.roomType)
				{
					$(opt).attr('selected', true);
				}
				$(input).append(opt);
			}
			$(div).append(input);
			$(div).append('Room Type');
			break;
		 
		case 3 : case 4 :
			$(div).append('<span>' + this.validRoomtypes[this.numAdults] + '</span>').addClass('defaultInfo');
			$(div).append('Room Type:');
			break;
			
		default : null; //this.roomType = '';
	}
	$(typeDiv).empty().append(div);
	$(agesDiv).empty();
	if (this.numChildren>0)
	{
		this.showChildAges(agesDiv);
	}
}


function showChildAges(agesDiv)
{
	var input, opt, j;
	if (this.numChildren > 0)
	{
		$(agesDiv).append(this.numChildren>1 ? 'Ages' :  'Age');
		for (var i=0; i<this.numChildren; i++)
		{
			input = $('<select/>').attr({
				id : 'room_' + this.roomNum + '_childage_' + i,
				name : 'room_' + this.roomNum + '_childage_' + i
			}).addClass('childAge');
			opt = $('<option value="">-</option>');
			$(input).append(opt);
			for (var j=0; j<=this.maxChildAge; j++)
			{
				opt = $('<option value="' + j + '">' + j + '</option>');
				if (j==this.childAges[i])
				{
					$(opt).attr('selected', true);
				}
				$(input).append(opt);
			}
			$(agesDiv).append(input);
		}
	}
}


function getGuests(occStr)
{
	var occArr = occStr.split(':', 2);
	this.numAdults = Number(occArr[0]);
	this.numChildren = Number(occArr[1]);
	this.showRoomOptions($('#room_' + this.roomNum + '_options'));
	return { adults : this.numAdults, children : this.numChildren };
}





/*
*************************************************************
*
*
*				dynamic form initialisation on DOM ready (jQuery)
*
*
*************************************************************
*/

// initialise destination input autocomplete
// ajax to flat xml file to populate options
function initAutocomplete()
{
	$.ajax({
		url : '/search/searchable_client_websites.xml',
		success : function(xml) {
			autocompleteData = parseAutocompleteData(xml, 'city');
			
			$('#dest_input').autocomplete({
				source : function(rqst, callback) {
					var returnBegin = new Array(), returnEnd = new Array(), pos;
					for (var i=0; i<autocompleteData.length; i++)
					{
						pos = autocompleteData[i].label.toLowerCase().indexOf(rqst.term.toLowerCase());
						if (pos==0)	{	returnBegin.push(autocompleteData[i]); }
						else if (pos > 0)	{	returnEnd.push(autocompleteData[i]); }
					}
					callback( returnBegin.concat(returnEnd) );
				},
				minLength : 2,
				select : setSearchSite
			});
		}
	});
}

// uses autocompleteData to set correct form values when
// autocomplete value is selected (or city is hard set)
function setSearchSite(event, ui)
{
	var urlPatt = /^http:\/\/([^\/]+)\/?/
	var frm = $('#siteSearch');
	$('input[name="city"]', frm).val(ui.item.cityId);
	$('input[name="clientid"]', frm).val(ui.item.clientId);
	$('input[name="formhost"]', frm).val(ui.item.url.replace(urlPatt, '$1'));
	$('input[name="formpage"]', frm).val('/' + ui.item.path);
	$(frm).attr('action', (ui.item.path.length > 0)
												? ui.item.url + ui.item.path
												: 'http://www.justonehotel.com/interface/search.php');
	switch ($('#currency_input').val())
	{
		case 'GBP' : case 'EUR' : case 'USD' : break;
		case 'default' : default :
			$('#currency_input').val(ui.item.currency).change();
	}
	$.cookie('j1h_srch', $("#siteSearch").serialize(), { path : '/' });
	$.cookie('formdest', $(frm).attr('action'));
}

// uses [xml] retrieved by xhr (ajax) and parses from this
// required autocomplete data using jQuery selector syntax [selector]
function parseAutocompleteData(xml, selector)
{
	return $(selector, xml).map(function() {
		var cityName = $('name:first', this).text();
		var defaultWebsite = $(this).attr('default_website_id');
		var cityObj = {
			label : cityName,
			cityId : $(this).attr('city_id')
		};
		var areas = {};
		var cityArr = $('website', this).map(function() {
			var clientId = $(this).attr('client_id');
			var currency = $('defaultCurrency', this).text();
			if (clientId==defaultWebsite)
			{
				cityObj.clientId = clientId;
				cityObj.url = $('url', this).text();
				cityObj.path = $('searchPage', this).text();
				cityObj.currency = currency;
			}
			var locale = $('localeDescription', this).text();
			if (locale.length > 0)
			{
				return {
					label : cityName + ', ' + locale,
					cityId :  cityObj.cityId,
					clientId : clientId,
					url : $('url', this).text(),
					path : $('searchPage', this).text(),
					currency : currency
				}
			}
		}).get();
		cityArr.unshift(cityObj);
		return cityArr;
	}).get();
}

// initialises search form for single city only
function initSearchCity(cityId)
{
	$.ajax({
		url : '/search/searchable_client_websites.xml',
		success : function(xml) {
			var cityArr = parseAutocompleteData(xml, 'city[city_id="' + cityId + '"]');
			var cityObj = { item : cityArr[0] };
			setSearchSite(null, cityObj);
		}
	});
}

// initialises datepicker (calendar) for both check in and check out
function initDatepickers()
{
	$("#searchForm input.staydate").datepicker({
		showAnim : 'fadeIn',
		showOn : 'button',
		buttonImage : '../images/calendar.jpg',
		buttonImageOnly : true,
		showButtonPanel: true,
		dateFormat: 'yy-mm-dd',
		changeMonth : true,
		changeYear : true
	});
	
	$('#check_in_date').datepicker('option', {
		minDate : 1,
		maxDate : '+1y -1d',
		onSelect : function(date) { $('#check_in_select').val(date).change(); }
	});
	
	$('#check_out_date').datepicker('option', {
		minDate : 2,
		maxDate : '+1y +20d',
		onSelect : function(date) { $('#check_out_select').val(date).change(); }
	});
}

function checkInChangeHandler()
{
	var checkIn = $(this).val();
	var dateArr = checkIn.split('-');
	var numNights = Number($('#duration_input').val());
	var maxNights = Number($('#duration_input option').length);
	
	var ciTimestamp = Date.UTC(dateArr[0], dateArr[1]-1, dateArr[2]);
	var coDateObj = new Date(ciTimestamp + (numNights * 86400000));
	var month = coDateObj.getUTCMonth() + 1;
	var day = coDateObj.getUTCDate();
	var checkOut = coDateObj.getUTCFullYear() + '-';
	checkOut += ((month < 10) ? '0' + month : month) + '-';
	checkOut += (day < 10) ? '0' + day : day;
	var minCoDateObj = new Date(ciTimestamp + 86400000);
	var maxCoDateObj = new Date(ciTimestamp + (86400000 * maxNights));

	$('#check_in_date').val(checkIn);

	skipCheckoutWarning = true;
	$('#check_out_date').datepicker('option', {
		minDate : minCoDateObj,
		maxDate : maxCoDateObj
	});
	$('#check_out_select').val(checkOut).change();
}

function checkOutChangeHandler()
{
	var dateArr;
	
	var checkOut = $(this).val();
	var checkIn = $('#check_in_date').val();
	
	dateArr = checkOut.split('-');
	var coTimestamp = Date.UTC(dateArr[0], dateArr[1]-1, dateArr[2]);
	dateArr = checkIn.split('-');
	var ciTimestamp = Date.UTC(dateArr[0], dateArr[1]-1, dateArr[2]);
	
	var numNights = (coTimestamp - ciTimestamp) / 86400000;
	var maxNights = Number($('#duration_input option').length);
	if ((numNights > 0) && (numNights <= maxNights))
	{
		$('#check_out_date').val(checkOut);
		$('#duration_input').val(numNights);
	}
	else if (!skipCheckoutWarning)
	{
		var errorDialogue = (numNights > 0) ? '#checkOutTooManyNightsError' : '#checkOutPreCheckinError';
		$(errorDialogue).dialog('open');
		checkOut = $('#check_out_date').val();
		$(this).val(checkOut);
	}
	skipCheckoutWarning = false;
}

function stayLengthChangeHandler()
{
	var numNights = Number($(this).val());
	var checkIn = $('#check_in_date').val();
	
	var dateArr = checkIn.split('-');
	var ciTimestamp = Date.UTC(dateArr[0], dateArr[1]-1, dateArr[2]);
	
	var coDateObj = new Date(ciTimestamp + (numNights * 86400000));
	var month = coDateObj.getUTCMonth() + 1;
	var day = coDateObj.getUTCDate();
	var checkOut = coDateObj.getUTCFullYear() + '-';
	checkOut += ((month < 10) ? '0' + month : month) + '-';
	checkOut += (day < 10) ? '0' + day : day;
	
	$('#check_out_select').val(checkOut).change();
}

function numRoomsChangeHandler()
{
	roomsObj.numRooms = Number(this.value);
	while (roomsObj.rooms.length < roomsObj.numRooms)
	{
		roomsObj.rooms.push(new roomObj(roomsObj.rooms.length));
	}
	roomsObj.showRooms();
}

function validateSearchSubmit()
{
	if ($('input[name="clientid"]', this).val().length > 0)
	{
		var date = $('input[name="check_in_date"]', this).val();
		var dateArr = date.split('-');
		$('input[name="year"]', this).val(dateArr[0]);
		$('input[name="month"]', this).val(dateArr[1]);
		$('input[name="day"]', this).val(dateArr[2]);
		var numRooms = Number($('#numrooms_input').val());
		var j=0;
		for (var i=0; i<numRooms; i++)
		{
			if (Number($('#room_' + i + '_numchildren')) > 0)
			{
				// check for child ages
			}
		}
		
		$.cookie('j1h_srch', $("#siteSearch").serialize(), { path : '/' });
		return true;
	}
	$('#missingDestinationError').dialog('open');
	return false;
}

function initOpeningTimes()
{
	$.get('index_elements/opening_times.ajax.php', function(html) {
		$('#header .contactDetail').empty().append($(html).html());
		if ($('#openingTimes'))
		{
			$('#openingTimes').dialog({
				autoOpen : false,
				resizable : false,
				modal : true,
				width : 300,
				dialogClass : 'openTimesDialogue',
				buttons: {
					Ok: function() { $( this ).dialog( "close" );	}
				}
			});
			$('#openingTimesOpener').click(function(e) {
				e.preventDefault();
				$('#openingTimes').dialog('open');
			});
		}
	});
}

function initInfoDialogues()
{
	$('#infoDialogues .infoDialogue').dialog({
		autoOpen: false,
		modal : true,
		width : 475,
		buttons: {
			Ok: function() { $( this ).dialog( "close" );	}
		}
	});

	$('#infoLinks a').click(function(e) {
		e.preventDefault();
		var dialogId = this.href.split('/').pop();
		$('#' + dialogId).dialog('open');
	});
}



function pageInit()
{
	if (searchCityId===false)	{ initAutocomplete(); }
	else { initSearchCity(searchCityId); }
	initDatepickers();
	
	// update checkout on checkin date change
	$('#check_in_select').change(checkInChangeHandler);
	
	// update duration on checkout date change + warn if the duration is excessive
	$('#check_out_select').change(checkOutChangeHandler);
	
	// update checkout value with duration change
	$('#duration_input').change(stayLengthChangeHandler);
	
	// show appropriate sets of room options for new number of rooms
	$('#numrooms_input').change(numRoomsChangeHandler);

	// validate form on submission and show any appropriate warnings
	$("#siteSearch").submit(validateSearchSubmit);
	
	// misc other form behaviour
	$('#submitSearch').button();
	$('#siteSearch select').change(function() {	$.cookie('j1h_srch', $("#siteSearch").serialize(), { path : '/' });	});
	$('#resetForm a').click(function(e) {
		e.preventDefault();	roomsObj.clearForm();
		if (searchCityId!==false) initSearchCity(searchCityId);
		});

	roomsObj.init();

	// non search-related page elements init
	initOpeningTimes();
	initInfoDialogues();

	//currency input not currently used
	/*$('#currency_input').change(function() {
		var selectedCurr = $(this).val().toLowerCase();
		$('#currencyFlags img').each(function() {
			if (this.src.slice(-7,-4) == selectedCurr)
			{
				$(this).show();
			}
			else
			{
				$(this).hide();
			}
		});
	});*/
}


$(document).ready(pageInit);

