/// <reference path="jquery-1.3.2.min-vsdoc.js" />
// CONTENTS ====================================================================
/*
- MATRIX: Front end code for the booking engine calendar matrix
- MATRIX UTIL FUNCTIONS: Util functions for same
- ACCORDIAN LISTS: opening / closing lists in room / attraction module<br>
- ROOM DETAILS: logic handling the rooms & their add ons module
- SLIDESHOWS:	handling for room detail img slideshows
- COLORBOX: init colorbox modal windows
- DATEPICKERS:
- PRINTING:
*/

// MATRIX ======================================================================
function InitMatrix() {
	EQMatrix();
	InitMatrixVars();
	InitMatrixInteraction();
	InitSummary();
	InitSkip();
	SetMonthNames( $("#matrix-table td:first") );
	
	currScrolledTo = 0; // init currScrolledTo here instead of in InitMatrixVars() because we don't want it reset
	
	InitRoomDetail();
	
	if ( $.browser.msie && $.browser.version == "6.0") FixMatrixHover();
	if ( $.browser.safari ){
		$("#room-types").addClass("safari");
		$("#matrix-table").addClass("safari");
	}
	if ( $.browser.msie && $.browser.version == "8.0" ){
		$("#room-types").addClass("ie8");
		$("#matrix-table").addClass("ie8");
	}
	
	$("#matrix-table th a").click(function(){ return false; }); // quick fix to disable links on dates in header
	
	// load default month
	/*var tmpObj 				= new Object();
	tmpObj.rangeStart 		= "2009-07-01";
	tmpObj.rangeDuration 	= 0;
	tmpObj.direction 		= "july";
	GetNewDateRange(tmpObj);*/
}

function EQMatrix(){
	/*
	*	Checks the li's in the room type list, places their heights in an array, then applies heights
	*/
	var heights 		= [];
	var roomTypes 		= [];
	var rollDetails 	= [];
	// first get heights & names of room-type divs
	$("#room-types #room-list li:not(#room-types .book-room-form li)").each( function(){
		heights.push( $(this).height() );
		roomTypes.push( $(this).children("h4").children("a").text() );
		rollDetails.push( $(this).children(".rollover-detail").text() );
	});
	// then apply heights to the table
	var i = 0;
	$("#matrix-table tbody tr").each( function(){
		$(this).data("roomType", roomTypes[i]);
		$(this).data("rollDetail", rollDetails[i]);
		$(this).find("td:first").each( function(){
			if ( $.browser.msie || $.browser.safari ){
				$(this).height(heights[i]); // adjust by 1 for IE & safari
			}else{
				$(this).height(heights[i]+1);
			}
		});
		i++;
	});
	// resize 'viewing window'
	$("#calendar").height( $("#matrix-table").height() );
}

function FixMatrixHover() {
	/*
	*	:hover in IE6 doesn't work on table cells, jQuery fix for same
	*/
	$("#matrix-table td").hover(function(){
		if( !$(this).hasClass("sold") && !$(this).hasClass("not-available") ) $(this).addClass("hover");
	}, function(){
		$(this).removeClass("hover");
	});
}

function InitAutoSubmit() {
	$("input[@type=submit].submit-on-change").hide();
	$("select.submit-on-change").change(function() {
		$('body').prepend('<div id="updating"><img src=\"/images/colorbox/loading.gif\" /><p>Updating...</p></div>');
		$.fn.colorbox({ open: true, initialHeight: "100px", height: "100px", initialWidth: "300px", width: "300px", href: "#updating", inline: true, overlayClose:false, opacity:0.5 });
		$(this).parents("form").submit();
	});
}

function InitRoomDetail(){
	$().bind('cbox_complete', function(){
		// init slideshows in the LB
		InitSlideshow();
	});
}

function InitMatrixVars(){
	selectingStart		= true;
	currSelectedRowId 	= "";
	newSelectedRowId 	= "";
	isoStartDate		= "";
	isoEndDate			= "";
	feedbackActive		= false;
	hasRange			= false;
	summaryActive		= false;
	startObj			= new Object();
	endObj				= new Object();
	noNights			= 0;
	basePrice			= 0;
}

// Core Interaction ------------------------------------------------------------
function InitMatrixInteraction(){
	/*
	*	Sets up the interaction for the matrix
	*/

	InitMatrixVars();
	
	// Cell hover
	$("#matrix-table td").hover( function(){
		var copy = $(this).parents("tr").data("rollDetail");
		if( IsValidSelection($(this)) && copy != "" ){
			$("#calendar #display-rollover-detail").show();
			$("#calendar #display-rollover-detail p").text( copy );
			$(this).mousemove(function(e){
				var top = e.pageY - $("#calendar").offset().top + 10;
				var left = e.pageX - $("#calendar").offset().left + 5;
				$("#calendar #display-rollover-detail").css("top", top);
				$("#calendar #display-rollover-detail").css("left", left);
			});
		}
	}, function(){
		$(this).unbind("mousemove");
		$("#calendar #display-rollover-detail").hide();
	});
	
	// Cell click
	$("#matrix-table td").unbind("click")
	$("#matrix-table td").click( function(){
		
		// hide any feedback
		if(feedbackActive) KillFeedback();
		
		if( IsValidSelection($(this)) ){
			// cell is valid to click (i.e. not NA or Sold)
			if(selectingStart){
				// first click on a cell
				Deselect();
				$(this).addClass("selected");
				currSelectedRowId 		= $(this).parent().attr("id");
				isoStartDate			= $(this).attr("abbr");
				selectingStart 			= false;
				noNights				= 1;
				var lowestAvailability 	= parseInt($(this).find(".av").text());
				// do summary in case they're only after one night
				DoSummary( $(this).parents("tr").data("roomType"), GetPriceAsNumber($(this).find(".price").text()), $(this), isoStartDate, isoStartDate, lowestAvailability);
				startObj = $(this);
				// remove range indicators
				$("#range-ind-start").remove();
				$("#range-ind-end").remove();
			}else{
				// second click on a cell
				newSelectedRowId = $(this).parent().attr("id");
				isoEndDate = $(this).attr("abbr");
				//if(newSelectedRowId == currSelectedRowId && isoStartDate != isoEndDate){
				if(newSelectedRowId == currSelectedRowId && isoStartDate != isoEndDate && !(isoEndDate < isoStartDate && hasRange)){
					// click was in same row & not the same date, and if we already have a range it wasn't earlier than the start date, so valid
					$(this).addClass("selected");
					endObj = $(this);
					
					// if they clicked the range 'backwards' swap start & end dates (and objects)
					if(isoEndDate < isoStartDate){
						var tmpStr 		= isoEndDate;
						isoEndDate 		= isoStartDate;
						isoStartDate 	= tmpStr;
						var tmpObj 		= endObj;
						endObj 			= startObj;
						startObj 		= tmpObj;
					}
					
					// loop td's in row, selecting them if between & ensuring all are valid (i.e. not NA or Sold), also set lowest room availabilty number for use in summary
					var allDatesValid 		= true;
					var totalPrice 			= GetPriceAsNumber($(startObj).find(".price").text()) + GetPriceAsNumber($(endObj).find(".price").text());
					var lowestAvailability	= Math.min( parseInt($(startObj).find(".av").text()), parseInt($(endObj).find(".av").text()) );
					var targetErrorCell;
					noNights = 2;
					$("#"+newSelectedRowId).children("td").each( function(){
						// 'deselect' cell first
						$(this).removeClass("selected");
						$(this).removeClass("start-end");
						var cellDate = $(this).attr("abbr");
						if( cellDate > isoStartDate && cellDate < isoEndDate){
							if( IsValidSelection($(this)) ){
								$(this).addClass("selected");
								totalPrice += GetPriceAsNumber($(this).find(".price").text())
								noNights++;
								lowestAvailability = Math.min(lowestAvailability, parseInt($(this).find(".av").text()));
							}else{
								targetErrorCell = $(this);
								allDatesValid = false;
							}
						}
					});
					
					if(!allDatesValid){
						// invalid date in range = fail
						Deselect();
						InitMatrixVars();
						// trigger error
						DoFeedback("Invalid Date!", "Dates which have been sold, or which are Not Available (NA) can't be part of your date selection, sorry!", true, targetErrorCell);
					}else{
						// successfully selected a valid range
						hasRange = true;
						// trigger summary
						SetSummaryOnSelection($(this).parents("tr").data("roomType"), totalPrice, isoStartDate, isoEndDate, startObj, endObj, lowestAvailability);
						// recalculate price in summary
						CalcPrice();
						// remove and re-add range indicators
						$("#range-ind-start").remove();
						$("#range-ind-end").remove();
						$(startObj).append("<span class='range-ind' id='range-ind-start'>Start</span>");
						$(endObj).append("<span class='range-ind' id='range-ind-end'>End</span>");
						$(startObj).removeClass("selected");
						$(startObj).addClass("start-end");
						$(endObj).removeClass("selected");
						$(endObj).addClass("start-end");
					}
					
				}else{
					// click was in different row, so invalid, make this a new 'first' click
					Deselect();
					$(this).addClass("selected");
					currSelectedRowId 		= $(this).parent().attr("id");
					isoStartDate			= $(this).attr("abbr");
					var lowestAvailability 	= parseInt($(this).find(".av").text());
					// do summary in case they're only after one night
					DoSummary( $(this).parents("tr").data("roomType"), GetPriceAsNumber($(this).find(".price").text()), $(this), isoStartDate, isoStartDate, lowestAvailability);
					startObj = $(this);
					selectingStart = false;
				}
			}
		}
		
	});
	
	// reset the star PNG's to be gifs for ie6
	if ( $.browser.msie && $.browser.version == "6.0"){
		$(".hot-deal img").attr("src", "/images/interface/common/bg-star.gif");
	}
	
	// check whether to disable back buttons 
	CheckDisable();
	
}

function Deselect(){
	$("#matrix-table td").removeClass("selected");
	$("#matrix-table td").removeClass("start-end");
	// remove range indicators
	$("#range-ind-start").remove();
	$("#range-ind-end").remove();
	hasRange 		= false;
	selectingStart 	= true;
	return false;
}

// Feedback Messages -----------------------------------------------------------
function DoFeedback(title, msg, isBad, targetObject){
	KillSummary();
	feedbackActive = true;
	feedbackTarget = targetObject;
	// set text on bubble
	$("#feedback h5").text(title);
	$("#feedback p").text(msg);
	if(isBad){
		$("#feedback").addClass("bad-feedback");
	}else{
		$("#feedback").removeClass("bad-feedback");
	}
	// position it
	var top = $(targetObject).offset().top - $("#calendar").offset().top;
	// center vert
	top += ($(targetObject).height() - ($("#feedback").height() + parseInt($("#feedback").css("padding-top")) + parseInt($("#feedback").css("padding-bottom")) ) ) / 2;
	var left = $(targetObject).offset().left - $("#calendar").offset().left + $(targetObject).width();
	
	// check for reposition if too far right
	var animMod = -5;
	if( left > ( $("#calendar").width() - $("#feedback").outerWidth() ) ){
		$("#feedback").addClass("reverse-feedback");
		left -= $("#feedback").outerWidth() + $(targetObject).width();
		animMod = 5;
	}else{
		$("#feedback").removeClass("reverse-feedback");
	}
	
	$("#feedback").css("top", top);
	$("#feedback").css("left", left + animMod);
	
	$("#feedback a").unbind("click")
	$("#feedback a").click(KillFeedback);
	
	// animate it in
	if ( !$.browser.msie) $("#feedback").css("opacity", "0");
	$("#feedback").show();
	if ( $.browser.msie){
		// IE6 & 7 lose the indicator when animating opacity, so don't animate it
		$("#feedback").animate({
			left: left
		}, 300 );
	}else{
		$("#feedback").animate({
			opacity: 1,
			left: left
		}, 300 );
	}
	
	// highlight offending cell
	$(feedbackTarget).css("background", "#db1212");
	$(feedbackTarget).css("color", "#fff");
}

function KillFeedback(){
	feedbackActive = false;
	$("#feedback").fadeOut("fast");
	$(feedbackTarget).attr("style", " ");
	return false;
}

// Booking Summary -------------------------------------------------------------
function InitSummary(){
	
	// cancel button
	$("#selection-summary #cancel-feedback").unbind("click")
	$("#selection-summary #cancel-feedback").click(function() {
		KillSummary();
		Deselect();
		InitMatrixVars();
		return false;
	});

	// book room button
	$("#selection-summary #book-room").unbind("click")
	$("#selection-summary #book-room").click(function() {
		$("#checkInDate-" + currSelectedRowId).val(isoStartDate);
		$("#checkOutDate-" + currSelectedRowId).val(""); // matrix represents first thru last night. NOT checkin thru checkout
		$("#lastNightDate-" + currSelectedRowId).val(isoEndDate);
		$("#quantity-" + currSelectedRowId).val($("#summary-quantity option:selected").text());
		$("#form-for-" + currSelectedRowId).submit();
		return false;
	});
	
	// room no dropdown change
	$("#selection-summary select").change(function(){
		// var newPrice = basePrice * parseInt( $(this).find('option').filter(':selected').text() );
		// $("#selection-summary .big-number").text("$"+newPrice);
		CalcPrice();
	});
}

function CalcPrice(){
	var newPrice = basePrice * parseFloat( $("#selection-summary select").find('option').filter(':selected').text() );
	$("#selection-summary .big-number").text("$"+newPrice);
}

function DoSummary(roomtype, price, targetObject, startdate, enddate, lowestAvailability){
	summaryActive = true;
	
	// reset select
	$("#selection-summary select option:first").attr("selected", true);
	
	// set text
	SetSummaryText(roomtype, price, startdate, enddate);
	SetSummarySelect(lowestAvailability);
	
	// position it
	var msgWidth 	= $("#selection-summary").outerWidth();
	var top 		= $(targetObject).offset().top - $("#calendar").offset().top + $(targetObject).height();
	var left 		= ( $(targetObject).offset().left - $("#calendar").offset().left ) - Math.ceil( msgWidth / 2 ) + Math.ceil( $(targetObject).width() / 2 );
	left 			= CheckSummaryPosition(left, targetObject);
	top 			= CheckSummaryTopPosition(top, targetObject);
	
	SetSummaryArrow(left, targetObject);
	
	$("#selection-summary").css("top", top + 5);
	$("#selection-summary").css("left", left);
	
	// animate it in
	if ( !$.browser.msie) $("#selection-summary").css("opacity", "0");
	$("#selection-summary").show();
	if ( $.browser.msie){
		// IE6 & 7 lose the indicator when animating opacity, so don't animate it
		$("#selection-summary").animate({
			top: top
		}, 300 );
	}else{
		$("#selection-summary").animate({
			opacity: 1,
			top: top
		}, 300 );
	}
	
}

function SetSummaryOnSelection(roomtype, price, startdate, enddate, startObject, endObject, lowestAvailability){
	SetSummaryText(roomtype, price, startdate, enddate);
	SetSummarySelect(lowestAvailability);
	
	// reposition
	var msgWidth 	= $("#selection-summary").outerWidth();
	var startX 		= $(startObject).offset().left - $("#calendar").offset().left;
	var endX 		= $(endObject).offset().left - $("#calendar").offset().left;
	var dist 		= ( ( endX - startX ) + $(endObject).width() ) / 2;
	var newLeft 	= startX + dist - ( msgWidth / 2 );
	
	newLeft = CheckSummaryPosition(newLeft);
	
	$("#selection-summary").animate({
		left: newLeft
	}, 300 );
	
	// move indicator arrow if necessary
	if(newLeft > 0 && newLeft < ( $("#calendar").width() - $("#selection-summary").outerWidth() )){
		$("#selection-summary span.ind").animate({
			left: "45%"
		}, 300 );
	}
	
}

function CheckSummaryPosition(left, targetObject){
	if(left < 0) left = 0;
	if( left > ( $("#calendar").width() - $("#selection-summary").outerWidth() ) ) left = $("#calendar").width() - $("#selection-summary").outerWidth();
	return left;
}

function CheckSummaryTopPosition(top, targetObject){
	
	var calHeight = $("#calendar").height();
	var selHeight = $("#selection-summary").outerHeight();
	
	if( top > (calHeight - selHeight) ){
		top -= ( $("#matrix-table td:first").height() + selHeight );
		$("#selection-summary").addClass("reverse");
	}else{
		$("#selection-summary").removeClass("reverse");
	}
	
	return top;
}

function SetSummaryArrow(left, targetObject){
	var offset 		= $("#calendar").offset().left;
	var targLeft 	= $(targetObject).offset().left;
	var arrowPos = (targLeft - offset) - left;
	
	$("#selection-summary span.ind").css("left", arrowPos + ($("#selection-summary span.ind").width() / 2) );
}

function SetSummaryText(roomtype, price, startdate, enddate){
	
	// sort out date display
	jsStartdate 	= ParseISOToJsDate(startdate);
	jsEnddate		= ParseISOToJsDate(enddate);
	dispStartDate 	= ReturnDay(jsStartdate.getDay()) + ", " + jsStartdate.getDate() + "  " + ReturnMonth(jsStartdate.getMonth()) + " " + jsStartdate.getFullYear();
	dispEndDate 	= ReturnDay(jsEnddate.getDay()) + ", " + jsEnddate.getDate() + "  " + ReturnMonth(jsEnddate.getMonth()) + " " + jsEnddate.getFullYear();
	if(startdate == enddate){
		dateText = dispStartDate;
	}else{
		dateText = dispStartDate + " - " + dispEndDate;
	}
	
	// set text
	$("#selection-summary h5").text(roomtype);
	$("#selection-summary .big-number").text("$"+price);
	$("#selection-summary .date-summary").text(dateText);
	$("#selection-summary #no-nights").text(noNights);
	(noNights > 1) ? $("#following-s").show() : $("#following-s").hide();
	
	basePrice = price;
}

function SetSummarySelect(lowestAvailability){
	var i = 1;
	$(".calculated-price option").each(function(){
		$(this).removeClass("sold");
		$(this).find("span").remove();
		$(this).removeAttr("disabled");
		if(i > lowestAvailability){
			$(this).addClass("sold");
			$(this).append("<span> SOLD</span>");
			$(this).attr("disabled","disabled");
		}
		i++;
	});
}

function KillSummary(){
	summaryActive = false;
	$("#selection-summary").fadeOut("fast");
	return false;
}

// Date Range Changing ---------------------------------------------------------
function InitSkip(){
	// on select change check if they've selected a new month
	$("#change-date-range select").change(function() {
		var selection = $(this).find("option:selected").attr("value");
		/* MR: changed 
		if( !isNaN(ParseISOToJsDate(selection)) ){
		var tmpObj 				= new Object();
		tmpObj.rangeStart 		= selection;
		tmpObj.rangeDuration 	= 0;
		(selection == "2009-07-01") ? tmpObj.direction = "july" : tmpObj.direction = "september";
		GetNewDateRange(tmpObj);
		}
		*/
		if (selection.length > 0) {
			var tmpObj = new Object();
			tmpObj.rangeStart = selection;
			tmpObj.rangeDuration = 0;
			tmpObj.direction = "From";
			PopMatrixLoader();
			GetNewDateRange(tmpObj);
		}
	});
	// setup actions on buttons
	$("#change-date-range .btn-back").data("direction", "Before");
	$("#change-date-range .btn-fwd").data("direction", "After");
	$("#change-date-range a").unbind("click")
	$("#change-date-range a").click(ChangeDateBtnClick);
}

function ChangeDateBtnClick(){
	
	// OLD WAY
	var selection = $(this).attr("rel");
	if(selection < 0) selection = selection * -1;
	if( parseInt(selection) ){
		// only do something if there's a day value (1 or 7) selected in the select
		Deselect();
		if(summaryActive) KillSummary();
		if(feedbackActive) KillFeedback();
		var i 		= 0;
		var getData = true;
		var dir 	= $(this).data("direction");
		var mod		= 1;
		$("#matrix-table tbody tr:first td").each(function(){
			if(dir == "After"){
				if(i == (currScrolledTo + 13 + parseInt(selection)))getData = false;
			}else{
				if(i == currScrolledTo - parseInt(selection)){
					getData = false;
					mod = -1;
				}
			}
			i++;
		});
		
		if(getData){
			// not enough in the table to cover the range requested, go get some more html
			var tmpObj 				= new Object();
			tmpObj.rangeDuration 	= parseInt(selection);
			tmpObj.direction 		= dir;
			if( dir == "After" ){
				tmpObj.rangeStart 	= $("#matrix-table tbody td:last").attr("abbr");
			}else{
				tmpObj.rangeStart 	= $("#matrix-table tbody td:first").attr("abbr");
			}
			PopMatrixLoader();
			GetNewDateRange(tmpObj)
		}else{
			// we have enough in the table currently, just scroll by how many we need to
			currScrolledTo = currScrolledTo + (parseInt(selection) * mod);
			ScrollTableTo($("#matrix-table tbody tr:first td:eq("+currScrolledTo+")"), parseInt(selection));
		}
		
	}
	return false;
}

// Updating Data ---------------------------------------------------------------
function UpdateTable(html, moveBy){
	
	KillMatrixLoader();
	Deselect();
	if(summaryActive) KillSummary();
	if(feedbackActive) KillFeedback();

	var milliDay		= 86400000;	// milliseconds in a day
	var leftDate 		= ParseISOToJsDate( $("#matrix-table td:first").attr("abbr") );
	var rightDate 		= ParseISOToJsDate( $("#matrix-table td:last").attr("abbr") );
	var incLeftDate 	= ParseISOToJsDate( $(html).find("td:first").attr("abbr") );
	var incRightDate 	= ParseISOToJsDate( $(html).find("td:last").attr("abbr") );
	
	var append 		= ( ( rightDate.getTime() + milliDay ) == incLeftDate.getTime() );
	var prepend 	= ( ( leftDate.getTime() - milliDay ) == incRightDate.getTime() );
	
	var noNewCells 	= $(html).find("tbody tr:first td").size();
	var initWidth	= $("#matrix-table").outerWidth();
	
	if(append || prepend){
		// its a day change (7 or 1) - go through the rigamarole ==============
		
		if(prepend){
			currScrolledTo += noNewCells;
			moveBy = moveBy * -1;
		}
		// walk the rows of the incoming html, adding the content of them to the row on page with the corresponding id
		$(html).find("tr").each(function(){
			if(append){
				$("#matrix-table").find("tr[id='"+$(this).attr("id")+"']").append( $(this).html() );
			}else{
				$("#matrix-table").find("tr[id='"+$(this).attr("id")+"']").prepend( $(this).html() );
			}
		});
		// check new width against the initWidth (if we prepended cells we need to reposition back to where we were before we scroll)
		if(prepend){
			var change 	= $("#matrix-table").outerWidth() - initWidth;
			var newLeft = parseInt( $("#matrix-table").css("left") ) - change;
			$("#matrix-table").css("left", newLeft);
		}
		// get new cell to scroll to
		var i = 0;
		$("#matrix-table tbody tr:first td").each(function(){
			if(i == (currScrolledTo + moveBy)){
				currScrolledTo = i;
				ScrollTableTo($(this), moveBy);
				return false;
			}
			i++;
		});
		
	}else{
		// it's a month change - replace the whole table =======================
		if(html != ""){
			currScrolledTo = 0;
			$("#matrix-table").replaceWith(html);
			$("#matrix-table").css("left", $("#calendar").width());
			$("#matrix-table").css("opacity", "0");
			$("#matrix-table").animate({
				opacity: 1,
				left: "0"
			}, 800 );
			SetMonthNames();
		}else{
			// nothing returned
			currScrolledTo = 0;
			ScrollTableTo($("#matrix-table tbody tr:first td"), 0);
		}
	}
	
	EQMatrix();
	InitMatrixVars();
	InitMatrixInteraction();
	
}

function ScrollTableTo(cellObj, noDaysAdded){
	
	SetMonthNames(cellObj);
	
	// get incoming & current objs & work out new position
	var inc 	= $(cellObj).offset().left - $("#calendar").offset().left;
	var cur 	= parseInt($("#matrix-table").css("left")); //$("#matrix-table").offset().left - $("#calendar").offset().left;
	var gotoX 	= cur - inc + 1;
	
	// scroll to new position
	var animTime = 0;
	(noDaysAdded > 1) ? animTime = 800 : animTime = 400;
	$("#matrix-table").animate({
		left: gotoX
	}, animTime, "swing", CheckDisable );
}

function SetMonthNames(cellObj) {

	var firstShowing = null;
	// hide the month names - except for the one in view and any on the first of the month
	$("#month-start th").each(function() {
		var cellDate = ParseISOToJsDate($(this).attr("abbr"));
		if (cellDate.getDate() == 1) {
			firstShowing = $(this);
			$(this).find("p").show();
		} else {
			$(this).find("p").hide();
		}
	});

	$("#month-start th[abbr='" + $(cellObj).attr("abbr") + "']").find("p").fadeIn();
	$("#month-start th[abbr='" + $(cellObj).attr("abbr") + "']").prev().find("p").hide();
	if (firstShowing)
		firstShowing.prev().find("p").hide();
}

// Disabling going back past todays date ---------------------------------------------------------------
function CheckDisable(){
	
	if( $("#head-dates th:first").hasClass("today") ){
		var offset = $("#head-dates th:first").offset().left - $("#calendar").offset().left;
		if( offset > -10 ){
			$("#button-cover").show();
			$("#button-cover").css("opacity", 0.6);
		}else{
			$("#button-cover").hide();
		}
	}else{
		$("#button-cover").hide();
	}
	
}

// MATRIX UTIL FUNCTIONS =======================================================
function ParseISOToJsDate(isoDate){
	// takes an ISO formatted date and returns a javascript date object
	isoArr 		= isoDate.split("-");
	tmpDate 	= new Date( isoArr[0], isoArr[1]-1, isoArr[2], 0, 0, 0, 0 );
	return tmpDate;
}

function IsValidSelection(cell){
	// checks a Matrix table cell to see if it has the 'not-available' or 'sold' classes
	var valid = true;
	if( $(cell).hasClass("not-available") || $(cell).hasClass("sold") ) valid = false;
	return valid;
}

function GetPriceAsNumber(price){
	return parseFloat( price.split("$")[1] );
}

function ReturnDay(i){
	var weekday=new Array(7);
	weekday[0]="Sunday";
	weekday[1]="Monday";
	weekday[2]="Tuesday";
	weekday[3]="Wednesday";
	weekday[4]="Thursday";
	weekday[5]="Friday";
	weekday[6]="Saturday";
	return weekday[i];
}

function ReturnMonth(i){
	var month=new Array(12);
	month[0]="Jan";
	month[1]="Feb";
	month[2]="Mar";
	month[3]="Apr";
	month[4]="May";
	month[5]="Jun";
	month[6]="Jul";
	month[7]="Aug";
	month[8]="Sep";
	month[9]="Oct";
	month[10]="Nov";
	month[11]="Dec";
	return month[i];
}

function PopMatrixLoader(){
	$("#matrix").append("<div id='matrix-loader'><p>Loading...</p></div>");
	//$("#matrix-loader").css("opacity", "0.8");
	$("#matrix-loader").width($("#matrix").width());
	$("#matrix-loader").height($("#matrix").height());
}

function KillMatrixLoader(){
	$("#matrix-loader").remove();
}

// PACKAGE LISTING EXPAND / CONTRACT ===========================================
function InitPackageListing(){
	$("#show-packages").toggle(function(){
		//$(".activities-listing .js-hidden").show();
		$(".activities-listing .js-hidden").fadeIn();
		if ( !($.browser.msie && $.browser.version == "6.0") ) $(this).text("hide");
	}, function(){
		// $(".activities-listing .js-hidden").hide();
		$(".activities-listing .js-hidden").fadeOut();
		if ( !($.browser.msie && $.browser.version == "6.0") ) $(this).text("View all Packages");
	});
}

// ACCORDIAN LISTS =============================================================
function InitAccordianLists(){
	$(".accordian-list h5 a").toggle(function(){
		$(this).addClass("selected");
		$(this).parent().siblings(".accordian-list-content:first").show();
		return false;
	}, function(){
		$(this).removeClass("selected");
		$(this).parent().siblings(".accordian-list-content:first").hide();
		return false;
	});
}

// ROOM DETAILS ================================================================
function InitRoomDetails(){
	$(".accordian-list-content").each(function(){
		
		$(this).find(".add-extra-result").each(function(){
			$(this).closest(".accordian-list-content").show();
			$(this).siblings(".add-extra-item:not(:has(.form-error))").hide();
			//$(this).siblings(".add-extra-item").hide();
		})
		
	});
	
	$(".add-extra-result a.edit").click(function(){
		$(this).hide();
		$(this).parent().width(75);
		$(this).parent().parent().find("strong").show();
		$(this).parent().parent().siblings(".add-extra-item:next").show();
		
		return false;
	});
}

// SLIDESHOWS ==================================================================
function InitSlideshow() {
	var noImgs	= 0;
	var ulWidth = 0;
	$(".slideshow img").each(function(){
		ulWidth += $(this).width();
		noImgs ++;
	});
	$(".slideshow ul").width(ulWidth);
	$(".slideshow").data("currImg", 0);
	$(".slideshow").data("noImgs", noImgs);
	if($(".slideshow").length > 0)
		SlideshowAdvance(0);
}

function SlideshowAdvance(_amt) {
	// if multiple slideshows are on a page they will all animate at once?????????
	var gotoImg		= $(".slideshow").data("currImg") + _amt;
	var newLeft 	= 0 - $(".slideshow li").eq(gotoImg).position().left;
	$(".slideshow ul").animate({ left: newLeft }, 800 );
	
	$(".slideshow").data("currImg", gotoImg);
	if(gotoImg == 0){
		( !$.browser.msie ) ? $(".prev-img").css("opacity", 0.5) : $(".prev-img").hide();
		$(".prev-img").unbind('click'); 
		$(".prev-img").click(function(){
			return false;
		});
	}else{
		( !$.browser.msie ) ? $(".prev-img").css("opacity", 1) : $(".prev-img").show();
		$(".prev-img").unbind('click'); 
		$(".prev-img").click(function(){
			SlideshowAdvance(-1);
			return false;
		});
	}
	
	if(gotoImg == ( $(".slideshow").data("noImgs") - 1) ){
		( !$.browser.msie ) ? $(".next-img").css("opacity", 0.5) : $(".next-img").hide();
		$(".next-img").unbind('click'); 
		$(".next-img").click(function(){
			return false;
		});
	}else{
		( !$.browser.msie ) ? $(".next-img").css("opacity", 1) : $(".next-img").show();
		$(".next-img").unbind('click'); 
		$(".next-img").click(function(){
			SlideshowAdvance(1);
			return false;
		});
	}
	
}

// COLORBOX SETUP ==============================================================
function InitColorbox() {
	$("a.colorbox").each(function() {
		$(this).colorbox({ href: $(this).attr("href") + ($(this).hasClass("ajax") ? "/ajax" : ""), inline: $(this).hasClass("inline") });
	});
	$().bind('cbox_complete', function() {
		// hook up our close button on load
		$(".lb-close").click(function() {
			$.fn.colorbox.close();
			return false;
		});
	});
	$(".terms-box").hide();
}

// DATEPICKERS SETUP ===========================================================
function InitDatePickers() {
	// datepicker from http://www.eyecon.ro/datepicker/#about
	// author is working on a fix for month select bug: http://blog.eyecon.ro/javascript/colorpicker-and-datepicker-updates.html

	$('.datepicker-launch').each(function() {
		var currentElement = $(this);
		if (GetDate(currentElement).length > 0) {
			currentElement.siblings("span.tag-text").hide();
			/*Pat - DO NOT remove below line: Fixes obscure IE7 display:none hidden content bug. See following URL for bug description: http://www.positioniseverything.net/explorer/ienondisappearcontentbugPIE/index.htm */
			currentElement.siblings("span.tag-text").css("visibility", "hidden");
		}
		else
			currentElement.siblings("input.selected-date").hide();
	
		var firstEnabled=0;
		var lastEnabled=0;
		if (currentElement.siblings("input.first-enabled-date").length > 0)
			firstEnabled = ParseISOToJsDate(currentElement.siblings("input.first-enabled-date").val());
		if (currentElement.siblings("input.last-enabled-date").length > 0)
			lastEnabled = ParseISOToJsDate(currentElement.siblings("input.last-enabled-date").val());

		var now = new Date();

		$(this).DatePicker({
			format: 'Y-m-d',
			date: GetDate(currentElement),
			current: GetDate(currentElement),
			starts: 1,
			position: 'left',
			prev: "<",
			next: ">",
			onBeforeShow: function() {
				if (GetDate(currentElement).length > 0)
					currentElement.DatePickerSetDate(GetDate(currentElement), true);
			},
			onRender: function(date) {
				return {
					disabled: ((firstEnabled>0 && (date.valueOf() < firstEnabled.valueOf())) || (lastEnabled>0 && (date.valueOf() > lastEnabled.valueOf())))
					//className: (date.valueOf() < firstEnabled.valueOf() && date.valueOf() > lastEnabled.valueOf()) ? "unavailable" : false
				}
			},
			onChange: function(formated, dates) {
				if (formated != "NaN-NaN-NaN") // work around for month select bug
					SetDate(formated, dates, currentElement);
			}
		});
	});
}

function GetDate(currentElement) {
	var dateField = currentElement.siblings("input.selected-date");
	return dateField.val();
}

function SetDate(formated, dates, currentElement) {
	var dateField = currentElement.siblings("input.selected-date");
	dateField.val(formated);
	dateField.show();
	currentElement.siblings("span.tag-text").hide();
	currentElement.DatePickerHide();
}

// PRINT PAGE ==================================================================
function InitPrintPage(){
	$(".btn-print").click(function(){
		window.print();
		return false;
	});
}


var promoValidationTimer;

function InitPromoCodeAjax() {
	$("#PromoCode").keyup(function(e) {
		var element = $(this);
		if (element.val().length == 0) {
			$("#promo-code-validation").html("");
		}
		else {
			if($("#promo-code-validation").text() != "Waiting...")
				$("#promo-code-validation").html("<span class='progress-msg'><span></span>Waiting...</span>");
				
			clearTimeout(promoValidationTimer);
			promoValidationTimer = setTimeout(function() {
				var promoCode = element.val();
				//var enteredCode = promoCode;

				if (promoCode.length == 0) {
					$("#promo-code-validation").html("");
				}
				else {
					$("#promo-code-validation").html("<span class='progress-msg'><span></span>Checking...</span>");
					$.post("/Booking/CheckPromoCode/", { promoCode: promoCode }, function(response) {
						if ($("#PromoCode").val() == promoCode) // check we're showing the answer for the current input.
							$("#promo-code-validation").html(response);
					});
				}
			}, 800);
		}


	});
}