/*	Holiday Extras JS calender control		An OO Calander control used to output dates in an easy to use GUI	WARNING THIS CALENDAR ONLY SUPPORTS DATES IN THE 1901-2099 RANGE	THIS IS BECAUSE I DIDN'T WANT TO WRITE LOADS OF CODE TO HANDLE	THE JULIAN CALENDAR AS WELL AS THE GREGORIAN CALENDAR AND I DIDN'T	WANT TO HAVE TO DEAL WITH THE 100 AND 400 YEAR LEAP YEAR RULES!*/// Globals for a day change (currently 2 or 3 days on the drop down )var gTd;var gCal;// Constructor for our calender objectfunction calendar( id, startDate, clickFunction, dateFormat, showMonth, showYear, aDates, aBlock, numDays ) {	this.id = id;	this.dateObject = startDate;	this.clickFunction = clickFunction;	this.dateFormat = dateFormat;	this.showMonth = showMonth;	this.showYear = showYear;	this.aAvailDates = aDates;	this.aBlockDates = aBlock;	this.aSelected = new Array();	this.write = writeCalendar;	this.length = getLength( startDate );	this.month = startDate.getMonth();	this.date = startDate.getDate();	this.day = startDate.getDay();	this.year = startDate.getFullYear();	this.getFormattedDate = getFormattedDate;	this.getChauntryDate = getChauntryDate;	this.getUnixDate = getUnixDate;	this.numDaysToSelect = numDays;	this.selectedUniqueCell = 0;	// Get the first day of the passed in month's day	startDate.setDate( 1 );	this.firstDay = startDate.getDay();	// Then reset the date object to the passed in date	startDate.setDate( this.date );}// Global arrays for storing the days and month strings ( Change this for multi-lingual support )var aDays = new Array( 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' );var aMonths = new Array( 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' );// Function that returns the date formated into a stringfunction getFormattedDate() {	return aDays[this.day] + ', ' + aMonths[this.month] + ' ' + this.date + ', ' + this.year;}// Function that returns the date formated into a Chauntry formatfunction getChauntryDate() {	var day = this.date + ""; // Add "" to convert to string	if ( day.length == 1 ) {		day = 0 + day;	}	var month = aMonths[this.month].toUpperCase();	month = month.substr( 0, 3 );	var year = this.year + ""; // Add "" to convert to string	year = year.substr( 2, 3 );		return day + month + year;}// Function that returns the date in a Unix TimeDate Stamp formatfunction getUnixDate() {	var dateNoTime = new Date( Date.UTC( this.year, this.month, this.date, 0, 0, 0 ) );	return dateNoTime.getTime() / 1000.0;}// Function that writes out the calender to a divfunction writeCalendar() {// Need a unique cell id for highlighting multiple days	var uniquCellID = "";	var calString = '<div id="calContainer_' + this.id + '">';	// Write month and year at top of table	calString += '<table id="cal' + this.id + '" cellspacing="0" style="border:1px black solid;">';	// Write the navigation and month row	calString += '<tr>';	if ( this.showYear ) {		calString += '<td class="nav" onClick="changeMonth(-12,\'' + this.id + '\')">&lt;&lt;</td>';	} else {		calString += '<td class="nav">&nbsp;</td>';	}	if ( this.showMonth ) {		calString += '<td class="nav" onClick="changeMonth(-1,\'' + this.id + '\')">&lt;</td>';	} else {		calString += '<td class="nav">&nbsp;</td>';	}	calString += '<td class="month" colspan="3">' + aMonths[this.month] + ' ' + ( this.year + "" ).substring( 2, 4 ) + '</td>';	if ( this.showMonth ) {		calString += '<td class="nav" onClick="changeMonth(1,\'' + this.id + '\')">&gt;</td>';	} else {		calString += '<td class="nav">&nbsp;</td>';	}	if ( this.showYear ) {		calString += '<td class="nav" onClick="changeMonth(12,\'' + this.id + '\')">&gt;&gt;</td>';	} else {		calString += '<td class="nav">&nbsp;</td>';	}	calString += '</tr>';	// Write a row containing days of the week	calString += '<tr>';	// Write the days of the week headings	for ( dow = 0; dow < aDays.length; dow++ ) {		calString += '<th class="dayHeader">' + aDays[dow].substring( 0, 3 ) + '</th>';	}		// Write the body of the calendar	calString += '<tr>';	// Create 6 rows so that the calendar doesn't resize	for ( displayDay = 0; displayDay < 42; displayDay++ ) {		var displayNum = ( displayDay - this.firstDay + 1 );		if ( displayDay < this.firstDay ) {			// Write the leading empty cells			calString += '<td class="empty">&nbsp;</td>';		} else if ( displayNum == this.date ) {			if ( this.showMonth || this.showYear ) {				// Unique cell identifier				uniqueCellID = this.id + "_" + displayNum;				// Write the selected date out with special style				calString += '<td id="' + uniqueCellID + '" class="date">' + displayNum + '</td>';			} else {				// Unique cell identifier				uniqueCellID = this.id + "_" + displayNum;				// Show the selected date as a regular day				calString += '<td id="' + uniqueCellID + '" class="days" onClick="javascript:changeDate(this,\'' + this.id + '\')">' + displayNum + '</td>';			}		} else if ( displayNum > this.length ) {			// Write the trailing empty cells			calString += '<td class="empty">&nbsp;</td>';		} else {			// Write the rest of the numbered cells			if ( this.aAvailDates == null ) {				// Unique cell identifier				uniqueCellID = this.id + "_" + displayNum;				calString += '<td id="' + uniqueCellID + '" class="days" onClick="javascript:changeDate(this,\'' + this.id + '\')">' + displayNum + '</td>';			} else {				uniqueCellID = this.id + "_" + displayNum;				testDate = displayNum + "";				if ( testDate.length == 1 ) {					testDate = "0" + displayNum + "";				}				testMonth = ( this.dateObject.getMonth() + 1 ) + "";				if ( testMonth.length == 1 ) {					testMonth = "0" + ( this.dateObject.getMonth() + 1 ) + "";				}				testDate = testDate + testMonth + this.year;				// If we passed an array of dates in, check against it.				if ( this.aAvailDates.inArray( testDate ) ) {					calString += '<td id="' + uniqueCellID + '" class="days" onClick="javascript:changeDate(this,\'' + this.id + '\')">' + displayNum + '</td>';				} else {					if ( 	this.aBlockDates == null ) {						calString += '<td id="' + uniqueCellID + '" class="offDays">' + displayNum + '</td>';					} else {						// Deal with non avilable days						if ( displayNum > this.aBlockDates[0] && displayNum < this.aBlockDates[1] ) {							calString += '<td id="" class="blockDays">' + displayNum + '</td>';						} else {							calString += '<td id="" class="offDays">' + displayNum + '</td>';						}					}				}				}		}		if ( displayDay % 7 == 6 ) {			calString += '</tr><tr>';		}	}	// Close the last number row	calString += '</tr>';	calString += '</table>';	calString += '</div>';	return calString;}// Fuction thats get the length of a monthfunction getLength( dateObj ) {	// Calculate the 30 and 31 one day months, plus calculate if February has 28 or 29 days in the current year	var daysCount;	switch( dateObj.getMonth() ) {		case 1:			if ( ( dateObj.getFullYear() % 4 == 0 && dateObj.getFullYear() % 100 != 0 ) || dateObj.getFullYear() % 400 == 0 ) {				daysCount = 29; // leap year			} else {				daysCount = 28;			}			break;		case 3:			daysCount = 30;			break;		case 5:			daysCount = 30;			break;		case 8:			daysCount = 30;			break;		case 10:			daysCount = 30;			break;		default:			daysCount = 31;	}	return daysCount;}// Function to unselect previously selected days.function unselectDays() {	// Loop round the number of calenders on display	for ( calCount = 0; calCount < 2; calCount++ ) {		cal = eval( aCalendarNames[currentCalendar + calCount] );		// Un hilite old days on the first calender		if( typeof( cal) != 'undefined') {            if ( cal.aSelected.length > 0) {                for ( cellNo = 0; cellNo < cal.aSelected.length; cellNo++ ) {                    cellUnselect = cal.id + '_' + cal.aSelected[cellNo];                    try {                        document.getElementById( cellUnselect ).className = "days";                    }                    catch( error) {                        // do nothing                    }                }                cal.aSelected = new Array();            }		}	}}/* function getNextDay() {} */// Function that changes the datefunction changeDate( td, cal) {	// Store td and cal in global vars for the days change	gTd = td;	gCal = cal;	// Change the cal argument to the existing calendar object	// This is why the first argument in the constructor must match the variable name	// The cal reference also allows for multiple calendars on a page	cal = eval( cal );	// Un hilite old days before selecting new ones	unselectDays();		// Now get our selected dates	aCellNameSplit = td.id.split('_');	cal.selectedUniqueCell = td.id;	document.getElementById( td.id ).className = "daySelected";	// Add day to the selected array	cal.aSelected[cal.aSelected.length] = aCellNameSplit[1];		// Var to track whether park will be closed during some of selected period	var noPark = false;		// Repeate for each additional day	for ( cellCount = 1; cellCount < cal.numDaysToSelect; cellCount++ ) {		// Get our new day number		otherCellNo = aCellNameSplit[1] - 0;		otherCellNo = otherCellNo + cellCount;		otherCellName = aCellNameSplit[0] + '_' + otherCellNo;		// Generate a string version of our second day		if ( ( otherCellNo + "" ).length == 1 ) {			searchDate = "0" + otherCellNo;		} else {			searchDate = "" + otherCellNo;		}		if ( cal.month < 9 ) {			searchDate = searchDate + "0" + ( cal.month + 1) + cal.year;		} else {			searchDate = searchDate + ( cal.month + 1) + cal.year;		}		// Check if our other day is in our available dates array		if ( findValueInArray( searchDate, cal.aAvailDates ) != -1 ) {			// Hilite the other day			document.getElementById( otherCellName ).className = "daySelected";			// Add day to the selected array			cal.aSelected[cal.aSelected.length] = otherCellNo;		} else {			// Days are outside the bounds of the list, we need to check if they are valid days or if they are next month			var testDate = new Date()			testDate.setFullYear( searchDate.substr( 4, 4 ), ( searchDate.substr( 2, 2 ) - 1 ), aCellNameSplit[1] - 0 );			realDate = new Date( testDate.getTime() + ( cellCount * 86400000 /*one day*/) );			// Compare the month on the testDate with the realDate			if ( testDate.getMonth() != realDate.getMonth() ) {				if ( cal.id == aCalendarNames[currentCalendar] ) {					// We are the left hand calender so we can select additional days					cal = eval( aCalendarNames[currentCalendar + 1] );					otherCellName = aCalendarNames[currentCalendar + 1] + "_" + realDate.getDate();					// Hilite the other day					try {    					document.getElementById( otherCellName ).className = "daySelected";    				}    				catch( error) {    				    // do nothing    				}					// Add day to the selected array					cal.aSelected[cal.aSelected.length] = realDate.getDate();					// RESET CAL as we may have changed it					cal = eval( aCalendarNames[currentCalendar] );				} else {					// We are the right hand calender so we need to move the calenders first					if ( ( currentCalendar + 2 ) < aCalendarNames.length ) {						// Move the calanders to display the correct months						scrollCalendars( 1 );						checkLinks();						// Now we need to hilite the days again						changeDate( gTd ,gCal );					}				}			} else {				noPark = true;			}		}	}		if( noPark) {		alert("Please be advised that LEGOLAND Windsor will be closed on one or more of the days you have selected. You may still book your tickets, but will be unable to take full advantage of the free day offer.");	}		// Set the calendar object to the new date ( we reset the calender obj to do a redraw )	cal.dateObject.setDate( td.firstChild.nodeValue );	cal = new calendar( cal.id, cal.dateObject, cal.clickFunction, cal.dateFormat, cal.aAvailDates );  	// Here is where we react to a date change - We call the function that was passed in.		if ( cal.dateFormat == "unix" ) {		var functionCallStr = cal.clickFunction + "( '" + cal.getUnixDate() + "' )";	} else if ( cal.dateFormat == "chauntry" ) {		var functionCallStr = cal.clickFunction + "( '" + cal.getChauntryDate() + "' )";	} else {		var functionCallStr = cal.clickFunction + "( '" + cal.getFormattedDate() + "' )";	}	eval( functionCallStr );}// Function that goes forward or back a monthfunction changeMonth( month, cal ) {	// The Date object is smart enough to know that it should roll over in December and January ( except on safari !!! )	cal = eval( cal );	// Set the calendar object to the new month ( we reset the calender obj to do a redraw )	cal.dateObject.setMonth( cal.dateObject.getMonth() + month );	cal = new calendar( cal.id, cal.dateObject, cal.clickFunction, cal.dateFormat, cal.showMonth, cal.showYear, cal.aAvailDates );	//cal.formattedDate = cal.getFormattedDate();	// Commented code out as I don't think it is required any more.	document.getElementById( 'calContainer_' + cal.id ).innerHTML = cal.write();}function onDateChange( selectedDate ) {		document.searchForm.ParkDate.value = selectedDate;	hotelArrivalDate();	dateSpecificEvents( frm.ParkDate.value);}function convertDate(dt) {	var temp = new Date(2006,1,1,0,0,0);		d = dt.substr(0,2);	m = dt.substr(2,2);	y = dt.substr(4,4);		temp.setFullYear(y,m-1,d);	//temp.setTime(0);	return temp;}function removeDates(aDates, today) {	// Need to remove days from current month if before today	// Rather, dont show days as available if the date has already passed		// Set the time to zero, midnight.	var i=0;	var tempDate = new Date();	tempDate.setFullYear(2006,0,1);	while((tempDate < today) && (aDates.length > i)) {		// do a substring to get days, months and years;		tempDate = convertDate(aDates[i]);		i++;	}	// We only want elements after and including i	var result = aDates.slice(i-1);		return result;}// Returns true if the passed value is found in the array.  Returns false if it is not.Array.prototype.inArray = function( testStr ) {	for ( index = 0; index < this.length; index++ ) {		// Matches identical (===), not just similar (==).		if ( this[index] === testStr ) {			return true;		}	}	return false;};// Returns the position of an array item (or -1 if not in array)function findValueInArray( searchVal, aSearch ) {	var count = 0;	var iMin = 0;	var iMax = aSearch.length - 1;	var bFound = false;	count = iMin - 1;	while ( ( count <= iMax ) && ( !( bFound ) ) ) {		count = count + 1;		currValue = aSearch[ count ];		bFound = ( searchVal == currValue );	}	if ( bFound ) {		return( count );	} else {		return( -1 );	}}