// Contains the necessary JavaScript functions to operate the CABS website


/*
    Generic Functions
*/
function AddCssStyle(element, className) {
    if (!element) return;

    var regex = new RegExp('\\b ?' + className + '\\b');

    if (!regex.test(element.className))
        element.className += ' ' + className;
}
function RemoveCssStyle(element, className) {
    if (!element) return;

    var regex = new RegExp('\\b ?' + className + '\\b');
    element.className = element.className.replace(regex, ''); //remove css style name
}
function SwitchCssStyle(element, className1, className2, useOne) {
    if (!element) return;
    if (useOne) {
        RemoveCssStyle(element, className2);
        AddCssStyle(element, className1);
    }
    else {
        RemoveCssStyle(element, className1);
        AddCssStyle(element, className2);
    }
}
function SetVisible(element, visible) {
    if (typeof (element) == 'string') element = document.getElementById(element);
    if (element) element.style.visibility = (visible ? 'visible' : 'hidden');
}


function GetWindowScrollTop() {
    var scrollTop = 0;

    if (document.documentElement && document.documentElement.scrollTop) {
        scrollTop = document.documentElement.scrollTop;
    }
    else if (document.body && document.body.scrollTop) {
        scrollTop = document.body.scrollTop;
    }
    else if (window && window.pageYOffset) {
        scrollTop = window.pageYOffset;
    }

    return scrollTop;
}

function GetWindowWidth() {
    var windowWidth = 0;

    if (typeof (window.innerWidth) == 'number') {
        //Non-IE
        windowWidth = window.innerWidth;
    } else if (document.documentElement && document.documentElement.clientWidth) {
        //IE 6+ in 'standards compliant mode'
        windowWidth = document.documentElement.clientWidth;
    } else if (document.body && document.body.clientWidth) {
        //IE 4 compatible
        windowWidth = document.body.clientWidth;
    }

    return windowWidth;
}

function GetWindowHeight() {
    var windowHeight = 0;

    if (typeof (window.innerHeight) == 'number') {
        //Non-IE
        windowHeight = window.innerHeight;
    } else if (document.documentElement && document.documentElement.clientHeight) {
        //IE 6+ in 'standards compliant mode'
        windowHeight = document.documentElement.clientHeight;
    } else if (document.body && document.body.clientHeight) {
        //IE 4 compatible
        windowHeight = document.body.clientHeight;
    }

    return windowHeight;
}

// Left of string
function getPageCoords(element) {
    var coords = { x: 0, y: 0 };
    while (element) {
        coords.x += element.offsetLeft;
        coords.y += element.offsetTop;
        element = element.offsetParent;
    }
    return coords;
}


/*
    Functions used by Discovery pages
*/
//Swaps the Accom / Tours div
function ChangeIndustryGrouping( industry )
{
    var accomm = document.getElementById("divSearchBoxAccomm");
    var aet = document.getElementById("divSearchBoxAET");
    var groupingField = document.getElementById("categoryGrouping");

    if (groupingField != null) groupingField.value=industry;

    if (accomm != null && aet != null) {
	    if (industry == "aet" )
	    {
		    accomm.style.display = "none";
		    aet.style.display = "block";
	    }
	    else if ( industry == "accomm" )
	    {
		    aet.style.display = "none";
		    accomm.style.display = "block";
	    }
	}
}

//Fills out the Drop lists with the correct regions based on the State
function PopulateRegionDropList(stateValue, selectElement) {
    if (stateValue && selectElement && RegionValues && RegionValues[stateValue]) {
        selectElement.options.length = 0;
        var regions = RegionValues[stateValue];
        for (var region in regions) {
            selectElement.options[selectElement.options.length] = new Option(regions[region], region);
            if (regions[region] == PreselectRegion)
                selectElement.selectedIndex = selectElement.options.length - 1;
        }
    }
}

// changes the view on the discovery results page
function ChangeIndustryGroupingResults (industry)
{
    var nights = document.getElementById("tdNights");
    var classAccomm = document.getElementById("form_ddlClassificationAccom");
    var classAET = document.getElementById("form_ddlClassificationAET");
    //var spanTypeOf = document.getElementById("spanTypeOf");

    if (nights != null && classAccomm != null && classAET != null) {
        if (industry == "aet") {
            //nights.style.display = "none";      //hidden
            nights.style.visibility = 'hidden';
            classAccomm.style.display = "none"; //hidden
            classAET.style.display = "";        //visible
            //spanTypeOf.firstChild.nodeValue = "Tour/Activity";
        }
        else if (industry == "accomm") {
        //nights.style.display = "";          //visible
            nights.style.visibility = 'visible';
            classAccomm.style.display = "";     //visible
            classAET.style.display = "none";    //hidden
            //spanTypeOf.firstChild.nodeValue = "Accommodation";
        }
        
    }
}


function UpdateAdvancedOptionsVisibility() {
    var isVisible      = document.getElementById('valueUseAdvancedOptions').value.toLowerCase() == 'true',
        link           = document.getElementById('linkShowAdvancedOptions'),
        displayItemIds = new Array('extraOptions1', 'extraOptions2', 'extraOptions3'),
        table          = document.getElementById('search_form_box_table'),
        e;

    for (var index in displayItemIds) {
        e = document.getElementById(displayItemIds[index]);
        if (e) {
            if (isVisible) {
                e.style.display = '';
            } else {
                e.style.display = 'none';
            }
        }
    }

    if (isVisible != null) {
        if (isVisible) {
            AddCssStyle(table, "discovery_results_criteria_table_expanded");
            link.innerHTML = '- Advanced Search';
        } else {
            RemoveCssStyle(table, "discovery_results_criteria_table_expanded");
            link.innerHTML = '+ Advanced Search';
        }
    }
}

function InvertAdvancedOptions() {
    var element = document.getElementById('valueUseAdvancedOptions');
    if (element) {
        var visible = (element.value.toLowerCase() == 'true');
        visible = !visible;
        element.value = visible.toString();

        UpdateAdvancedOptionsVisibility();
    }
}

function DiscoveryPageResetRedirectHiddenInputs(prov, cal) {
    if (prov && cal) cal = null;
    
    var e = document.getElementById('NavigateToProvider');
    
    if (e) {
        if (prov) {
            e.value = prov;
        } else {
            e.value = '';
        }
    }
    
    e = document.getElementById('NavigateCalendarToDate');
    if (e) {
        if (cal) {
            e.value = cal;
        } else {
            e.value = '';
        }
    }
}

var isMaximised = false;

function ChangeMinimiseMaximiseSearchCriteriaBox( )
{
	if ( isMaximised == false )
	{
		if ( navigator.appName == "Microsoft Internet Explorer" )
		{
			document.getElementById("search_form_box_table").style.display = "block";
		}
		else
		{
			document.getElementById("search_form_box_table").style.display = "table";
		}
		
		document.getElementById("search_form_box_search_icon").firstChild.nodeValue = "-";
		isMaximised = true;
	}
	else
	{
		document.getElementById("search_form_box_table").style.display = "none";
		document.getElementById("search_form_box_search_icon").firstChild.nodeValue = "+";
		isMaximised = false;
	}
}

/*
    Functions used by Booking Pages
*/

// determine if the browser supports the DOM
if (document.getElementById && document.createTextNode && document.createElement){
	isDOMCapable=true;
}

function showHideRoomConfigurations(control) {
	if (isDOMCapable && document.getElementById(control)) {
		var configurationsControl = document.getElementById(control); // get the control that selects how different configurations to support
		var selectedConfigurations = configurationsControl.options[configurationsControl.selectedIndex].value; // get its value
		
		var room1 = document.getElementById("search_form_multiple_configurations_1");
		var room2 = document.getElementById("search_form_multiple_configurations_2");
		var room3 = document.getElementById("search_form_multiple_configurations_3");

		if (selectedConfigurations == '1') {
			room1.style.display = "block";
			room2.style.display = "none";
			room3.style.display = "none";
		}

		if (selectedConfigurations == '2') {
			room1.style.display = "block";
			room2.style.display = "block";
			room3.style.display = "none";
		}

		if (selectedConfigurations == '3') {
			room1.style.display = "block";
			room2.style.display = "block";
			room3.style.display = "block";
		}
	}	
}

function isValidString (control, minimumLength, maximumLength, alertMessage, ignoreIfEmpty) {
	if (isDOMCapable && document.getElementById(control)) {
		var formControl = document.getElementById(control);
		var value = formControl.value;

		if (value.length == 0 && ignoreIfEmpty != null && ignoreIfEmpty) 
			return true;

		if (value.length > maximumLength || value.length < minimumLength) {
			if (alertMessage.length != 0) {
				alert(alertMessage);
			}
			return false;
		}
	}	
	return true;
}

function isValidNameString(control, minimumLength, maximumLength, alertMessage, ignoreIfEmpty) {
	if (isDOMCapable && document.getElementById(control)) {
		var formControl = document.getElementById(control);
		var value = formControl.value;

		if (value.length == 0 && ignoreIfEmpty != null && ignoreIfEmpty) 
			return true;

		if (value.length > maximumLength || value.length < minimumLength) {
			if (alertMessage.length != 0) {
				alert(alertMessage);
			}
			return false;
		}

		var regex = /^[a-zA-Z -]+$/;
		var result = regex.exec(value);

		if (!result) {
			if (alertMessage.length != 0) {
				alert(alertMessage);
			}
			return false;
		}
	}	
	return true;
}

function isValidCheck (control) {
	if (isDOMCapable && document.getElementById(control)) {
		var formControl = document.getElementById(control);

		if (!formControl.checked) {
			return false;
		}
	}	
	return true;
}

function isValidSelect (control, alertMessage) {
	if (isDOMCapable && document.getElementById(control)) {
		var formControl = document.getElementById(control);

		if (formControl.selectedIndex == -1) {
			if (alertMessage.length != 0) {
				alert(alertMessage);
			}
			return false;
		}
		else {
			var value = formControl.options[formControl.selectedIndex].value;

			if (value.length == 0 || value == '-1' || value.substring(0, 1) == '-' || value.substring(0, 1) == '_') {
				if (alertMessage.length != 0) {
					alert(alertMessage);
				}
				return false;
			}
		}
	}	
	return true;
}

function isValidEmail (control, alertMessage, ignoreIfEmpty) {
	if (isDOMCapable && document.getElementById(control)) {
		var formControl = document.getElementById(control);
		var value = formControl.value;

		if (value.length == 0 && ignoreIfEmpty != null && ignoreIfEmpty) 
			return true;
		
		var regex = /^\s*[^\s]+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)\s*$/;
		var result = regex.exec(value);

		if (!result) {
			if (alertMessage.length != 0) {
				alert(alertMessage);
			}
			return false;
		}
	}	
	return true;
}

function isValidRadio (formControl, alertMessage) {
	var result = false;
	
	if (formControl.length == null) {
		// if there is only one element then there is no array
		if (formControl.checked == true) {
			result = true;
		}
	}
	else {
		// there must be more than one element so we can loop through
		for (i=0;i<formControl.length;i++){
			if (formControl[i].checked == true)
				result = true;
		}
	}

	if (!result) {
		if (alertMessage.length != 0) {
			alert(alertMessage);
		}
		return false;
	}
	return true;
}

function isValidPhoneNumber(control, alertMessage, ignoreIfOthersEmpty, ignoreIfEmpty) {
	if (isDOMCapable && document.getElementById(control)) {
		var formControlNumber = document.getElementById(control);
		var valueNumber = formControlNumber.value;

		if (valueNumber.length == 0 && ignoreIfEmpty != null && ignoreIfEmpty) 
			return true;

		var regexNumber = /^\+*[\d\s-]{4,}?$/;
		var resultNumber = regexNumber.exec(valueNumber);

		if (!resultNumber) {
			if (alertMessage.length != 0 && !(ignoreIfOthersEmpty && valueNumber.length == 0)) {
				alert(alertMessage);
			}
			return false;
		}
	}	
	return true;
}

function isValidMobileNumber(control1, control2, alertMessage, ignoreIfOthersEmpty, ignoreIfEmpty) {
	if (isDOMCapable && document.getElementById(control1) && document.getElementById(control2)) {
		var formControlCountry = document.getElementById(control1);
		var formControlNumber = document.getElementById(control2);
		var valueCountry = formControlCountry.value;
		var valueNumber = formControlNumber.value;

		if (valueCountry.length == 0 && valueNumber.length == 0 && ignoreIfEmpty != null && ignoreIfEmpty) 
			return true;

		var regexCountry = /^\s*\d{1,3}\s*$/;
		var regexNumber = /^\s*[\s0-9]{6,}\s*$/;
		var resultCountry = regexCountry.exec(valueCountry);
		var resultNumber = regexNumber.exec(valueNumber);

		if (!resultCountry || !resultNumber) {
			if (alertMessage.length != 0 && !(ignoreIfOthersEmpty && (valueCountry.length == 0 || valueNumber.length == 0))) {
				alert(alertMessage);
			}
			return false;
		}
	}	
	return true;
}

function isCreditCardNumberValid(id, alertMessage) {
	if (isDOMCapable & document.getElementById(id)) {
		
		var cardNumber = document.getElementById(id).value;
    	    
		var len = cardNumber.length;

		var regex = /^\d{13,16}$/;

		if (!regex.exec(cardNumber)) {
			if (alertMessage.length != 0) {
				alert(alertMessage);
			}
			return false;
		}

		var no_digit = cardNumber.length;
		var oddoeven = no_digit & 1;
		var sum = 0;

		for (var count = 0; count < no_digit; count++) {
			var digit = Number(cardNumber.charAt(count));

			if (!((count & 1) ^ oddoeven)) {
				digit *= 2;
				if (digit > 9) {
					digit -= 9;
				}
			}

			sum += digit;
		}
		if (sum % 10 == 0) {
			return true;
		}
		else {
			if (alertMessage.length != 0) {
				alert(alertMessage);
			}
			return false;
		}
	}	
	return true;
}

function isCreditCardTypeValid(id, alertMessage) {
	if (isDOMCapable && document.getElementById(id)) {
	    var cardNumber = document.getElementById(id).value;

	    if (getCreditCardType(cardNumber) == '') {
			if (alertMessage.length != 0) {
				alert(alertMessage);
			}
			return false;
		}
	}	
	return true;
}

function getCreditCardType(cardNumber) {
	regexVisa = /^4(\d{12}|\d{15})$/;
	regexMC = /^5[1-5]\d{14}$/;
	regexAmex = /^[3][4|7]\d{13}$/;
	regexDiners = /^[3][0][0-5]|[6|8]\d{11,12}$/;

	if (regexVisa.exec(cardNumber))
		return 'Visa';
	if (regexMC.exec(cardNumber))
		return 'Mastercard';
	if (regexAmex.exec(cardNumber))
		return 'AmericanExpress';
	if (regexDiners.exec(cardNumber))
		return 'Diners';
	
	return '';
}
	
function isCreditCardExpiryValid(control, alertMessage) {
	if (isDOMCapable && document.getElementById(control)) {
		var formControl = document.getElementById(control);
		var cardExpiry = formControl.value;

		var regex = /^(0[1-9]|1[0-2])[01][0-9]$/;

		if (!regex.exec(cardExpiry)) {
			if (alertMessage.length != 0) {
				alert(alertMessage);
			}
			return false;
		}
		
		var month = Number(cardExpiry.substr(0,2));
		var year = Number(cardExpiry.substr(2,2));
		var today = new Date();
		var currentYear = Number(String(today.getFullYear()).substr(2,2));
		
		if (!((currentYear < year) || (currentYear == year && today.getMonth()+1 <= month))) {
			if (alertMessage.length != 0) {
				alert(alertMessage);
			}
			return false;
		}

	}	
	return true;
}

function isCreditCardExpiryValid2(ddlMonthId, ddlYearId, alertMessage) {
    if (isDOMCapable && document.getElementById(ddlMonthId) && document.getElementById(ddlYearId)) {
        var ddlMonth = document.getElementById(ddlMonthId);
        var ddlYear  = document.getElementById(ddlYearId);

        var month = parseInt(ddlMonth.value, 10);
        var year  = parseInt(ddlYear.value, 10);
        var today = new Date();
        var currentYear = today.getFullYear();
        var currentMonth = today.getMonth() + 1; //convert from month index to month number
        
        if (year == currentYear && month < currentMonth) {
            if (alertMessage && alertMessage.length != 0) {
                alert(alertMessage);
            }
            return false;
        }
    }
    return true;
}
function isCreditCardSecurityCodeValid(control, desiredType, alertMessage, ignoreIfBlank) {
	if (isDOMCapable && document.getElementById(control)) {
		var formControl = document.getElementById(control);
		var cardCode = formControl.value;
		
		if (ignoreIfBlank == true && cardCode == '') return true;
		
		var regex3Dig = /^\d{3}$/;
		var regex4Dig = /^\d{4}$/;
		
		if (desiredType == 'Visa' || desiredType == 'Mastercard') {
			if (!regex3Dig.exec(cardCode)) {
				if (alertMessage.length != 0) {
					alert(alertMessage);
				}
				return false;
			}
		}
		else if (desiredType == 'AmericanExpress') {
			if (!regex4Dig.exec(cardCode)) {
				if (alertMessage.length != 0) {
					alert(alertMessage);
				}
				return false;
			}
		}
	}	
	return true;
}

function isBlank(control){
    if(typeof(control) == 'string') control = document.getElementById(control);
    if(control && typeof(control.value) != 'undefined'){
        return control.value.length == 0;
    }
    else
        return true;
}

// ===================================================================
// Author: Matt Kruse <matt@mattkruse.com>
// WWW: http://www.mattkruse.com/
//
// NOTICE: You may use this code for any purpose, commercial or
// private, without any further permission from the author. You may
// remove this notice from your final code if you wish, however it is
// appreciated by the author if at least my web site address is kept.
//
// You may *NOT* re-distribute this code in any way except through its
// use. That means, you can include it in your product, or your web
// site, or any other form where the code is actually being used. You
// may not put the plain javascript up on your site for download or
// include it in your javascript libraries for download. 
// If you wish to share this code with others, please just point them
// to the URL instead.
// Please DO NOT link directly to my .js files from your site. Copy
// the files to your server and use them there. Thank you.
// ===================================================================

// HISTORY
// ------------------------------------------------------------------
// May 17, 2003: Fixed bug in parseDate() for dates <1970
// March 11, 2003: Added parseDate() function
// March 11, 2003: Added "NNN" formatting option. Doesn't match up
//                 perfectly with SimpleDateFormat formats, but 
//                 backwards-compatability was required.

// ------------------------------------------------------------------
// These functions use the same 'format' strings as the 
// java.text.SimpleDateFormat class, with minor exceptions.
// The format string consists of the following abbreviations:
// 
// Field        | Full Form          | Short Form
// -------------+--------------------+-----------------------
// Year         | yyyy (4 digits)    | yy (2 digits), y (2 or 4 digits)
// Month        | MMM (name or abbr.)| MM (2 digits), M (1 or 2 digits)
//              | NNN (abbr.)        |
// Day of Month | dd (2 digits)      | d (1 or 2 digits)
// Day of Week  | EE (name)          | E (abbr)
// Hour (1-12)  | hh (2 digits)      | h (1 or 2 digits)
// Hour (0-23)  | HH (2 digits)      | H (1 or 2 digits)
// Hour (0-11)  | KK (2 digits)      | K (1 or 2 digits)
// Hour (1-24)  | kk (2 digits)      | k (1 or 2 digits)
// Minute       | mm (2 digits)      | m (1 or 2 digits)
// Second       | ss (2 digits)      | s (1 or 2 digits)
// AM/PM        | a                  |
//
// NOTE THE DIFFERENCE BETWEEN MM and mm! Month=MM, not mm!
// Examples:
//  "MMM d, y" matches: January 01, 2000
//                      Dec 1, 1900
//                      Nov 20, 00
//  "M/d/yy"   matches: 01/20/00
//                      9/2/00
//  "MMM dd, yyyy hh:mm:ssa" matches: "January 01, 2000 12:30:45AM"
// ------------------------------------------------------------------

var MONTH_NAMES=new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
var DAY_NAMES=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat');
function LZ(x) {return(x<0||x>9?"":"0")+x}

// ------------------------------------------------------------------
// isDate ( date_string, format_string )
// Returns true if date string matches format of format string and
// is a valid date. Else returns false.
// It is recommended that you trim whitespace around the value before
// passing it to this function, as whitespace is NOT ignored!
// ------------------------------------------------------------------
function isDate(val,format) {
	var date=getDateFromFormat(val,format);
	if (date==0) { return false; }
	return true;
	}

// -------------------------------------------------------------------
// compareDates(date1,date1format,date2,date2format)
//   Compare two date strings to see which is greater.
//   Returns:
//   1 if date1 is greater than date2
//   0 if date2 is greater than date1 of if they are the same
//  -1 if either of the dates is in an invalid format
// -------------------------------------------------------------------
function compareDates(date1,dateformat1,date2,dateformat2) {
	var d1=getDateFromFormat(date1,dateformat1);
	var d2=getDateFromFormat(date2,dateformat2);
	if (d1==0 || d2==0) {
		return -1;
		}
	else if (d1 > d2) {
		return 1;
		}
	return 0;
	}

// ------------------------------------------------------------------
// formatDate (date_object, format)
// Returns a date in the output format specified.
// The format string uses the same abbreviations as in getDateFromFormat()
// ------------------------------------------------------------------
function formatDate(date,format) {
	format=format+"";
	var result="";
	var i_format=0;
	var c="";
	var token="";
	var y=date.getYear()+"";
	var M=date.getMonth()+1;
	var d=date.getDate();
	var E=date.getDay();
	var H=date.getHours();
	var m=date.getMinutes();
	var s=date.getSeconds();
	var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;
	// Convert real date parts into formatted versions
	var value=new Object();
	if (y.length < 4) {y=""+(y-0+1900);}
	value["y"]=""+y;
	value["yyyy"]=y;
	value["yy"]=y.substring(2,4);
	value["M"]=M;
	value["MM"]=LZ(M);
	value["MMM"]=MONTH_NAMES[M-1];
	value["NNN"]=MONTH_NAMES[M+11];
	value["d"]=d;
	value["dd"]=LZ(d);
	value["E"]=DAY_NAMES[E+7];
	value["EE"]=DAY_NAMES[E];
	value["H"]=H;
	value["HH"]=LZ(H);
	if (H==0){value["h"]=12;}
	else if (H>12){value["h"]=H-12;}
	else {value["h"]=H;}
	value["hh"]=LZ(value["h"]);
	if (H>11){value["K"]=H-12;} else {value["K"]=H;}
	value["k"]=H+1;
	value["KK"]=LZ(value["K"]);
	value["kk"]=LZ(value["k"]);
	if (H > 11) { value["a"]="PM"; }
	else { value["a"]="AM"; }
	value["m"]=m;
	value["mm"]=LZ(m);
	value["s"]=s;
	value["ss"]=LZ(s);
	while (i_format < format.length) {
		c=format.charAt(i_format);
		token="";
		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
			token += format.charAt(i_format++);
			}
		if (value[token] != null) { result=result + value[token]; }
		else { result=result + token; }
		}
	return result;
	}
	
// ------------------------------------------------------------------
// Utility functions for parsing in getDateFromFormat()
// ------------------------------------------------------------------
function _isInteger(val) {
	var digits="1234567890";
	for (var i=0; i < val.length; i++) {
		if (digits.indexOf(val.charAt(i))==-1) { return false; }
		}
	return true;
	}
function _getInt(str,i,minlength,maxlength) {
	for (var x=maxlength; x>=minlength; x--) {
		var token=str.substring(i,i+x);
		if (token.length < minlength) { return null; }
		if (_isInteger(token)) { return token; }
		}
	return null;
	}
	
// ------------------------------------------------------------------
// getDateFromFormat( date_string , format_string )
//
// This function takes a date string and a format string. It matches
// If the date string matches the format string, it returns the 
// getTime() of the date. If it does not match, it returns 0.
// ------------------------------------------------------------------
function getDateFromFormat(val,format) {
	val=val+"";
	format=format+"";
	var i_val=0;
	var i_format=0;
	var c="";
	var token="";
	var token2="";
	var x,y;
	var now=new Date();
	var year=now.getYear();
	var month=now.getMonth()+1;
	var date=1;
	var hh=now.getHours();
	var mm=now.getMinutes();
	var ss=now.getSeconds();
	var ampm="";
	
	while (i_format < format.length) {
		// Get next token from format string
		c=format.charAt(i_format);
		token="";
		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
			token += format.charAt(i_format++);
			}
		// Extract contents of value based on format token
		if (token=="yyyy" || token=="yy" || token=="y") {
			if (token=="yyyy") { x=4;y=4; }
			if (token=="yy")   { x=2;y=2; }
			if (token=="y")    { x=2;y=4; }
			year=_getInt(val,i_val,x,y);
			if (year==null) { return 0; }
			i_val += year.length;
			if (year.length==2) {
				if (year > 70) { year=1900+(year-0); }
				else { year=2000+(year-0); }
				}
			}
		else if (token=="MMM"||token=="NNN"){
			month=0;
			for (var i=0; i<MONTH_NAMES.length; i++) {
				var month_name=MONTH_NAMES[i];
				if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {
					if (token=="MMM"||(token=="NNN"&&i>11)) {
						month=i+1;
						if (month>12) { month -= 12; }
						i_val += month_name.length;
						break;
						}
					}
				}
			if ((month < 1)||(month>12)){return 0;}
			}
		else if (token=="EE"||token=="E"){
			for (var i=0; i<DAY_NAMES.length; i++) {
				var day_name=DAY_NAMES[i];
				if (val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()) {
					i_val += day_name.length;
					break;
					}
				}
			}
		else if (token=="MM"||token=="M") {
			month=_getInt(val,i_val,token.length,2);
			if(month==null||(month<1)||(month>12)){return 0;}
			i_val+=month.length;}
		else if (token=="dd"||token=="d") {
			date=_getInt(val,i_val,token.length,2);
			if(date==null||(date<1)||(date>31)){return 0;}
			i_val+=date.length;}
		else if (token=="hh"||token=="h") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<1)||(hh>12)){return 0;}
			i_val+=hh.length;}
		else if (token=="HH"||token=="H") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<0)||(hh>23)){return 0;}
			i_val+=hh.length;}
		else if (token=="KK"||token=="K") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<0)||(hh>11)){return 0;}
			i_val+=hh.length;}
		else if (token=="kk"||token=="k") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<1)||(hh>24)){return 0;}
			i_val+=hh.length;hh--;}
		else if (token=="mm"||token=="m") {
			mm=_getInt(val,i_val,token.length,2);
			if(mm==null||(mm<0)||(mm>59)){return 0;}
			i_val+=mm.length;}
		else if (token=="ss"||token=="s") {
			ss=_getInt(val,i_val,token.length,2);
			if(ss==null||(ss<0)||(ss>59)){return 0;}
			i_val+=ss.length;}
		else if (token=="a") {
			if (val.substring(i_val,i_val+2).toLowerCase()=="am") {ampm="AM";}
			else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {ampm="PM";}
			else {return 0;}
			i_val+=2;}
		else {
			if (val.substring(i_val,i_val+token.length)!=token) {return 0;}
			else {i_val+=token.length;}
			}
		}
	// If there are any trailing characters left in the value, it doesn't match
	if (i_val != val.length) { return 0; }
	// Is date valid for month?
	if (month==2) {
		// Check for leap year
		if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year
			if (date > 29){ return 0; }
			}
		else { if (date > 28) { return 0; } }
		}
	if ((month==4)||(month==6)||(month==9)||(month==11)) {
		if (date > 30) { return 0; }
		}
	// Correct hours value
	if (hh<12 && ampm=="PM") { hh=hh-0+12; }
	else if (hh>11 && ampm=="AM") { hh-=12; }
	var newdate=new Date(year,month-1,date,hh,mm,ss);
	return newdate.getTime();
	}

// ------------------------------------------------------------------
// parseDate( date_string [, prefer_euro_format] )
//
// This function takes a date string and tries to match it to a
// number of possible date formats to get the value. It will try to
// match against the following international formats, in this order:
// y-M-d   MMM d, y   MMM d,y   y-MMM-d   d-MMM-y  MMM d
// M/d/y   M-d-y      M.d.y     MMM-d     M/d      M-d
// d/M/y   d-M-y      d.M.y     d-MMM     d/M      d-M
// A second argument may be passed to instruct the method to search
// for formats like d/M/y (european format) before M/d/y (American).
// Returns a Date object or null if no patterns match.
// ------------------------------------------------------------------
function parseDate(val) {
	var preferEuro=(arguments.length==2)?arguments[1]:false;
	generalFormats=new Array('y-M-d','MMM d, y','MMM d,y','y-MMM-d','d-MMM-y','MMM d');
	monthFirst=new Array('M/d/y','M-d-y','M.d.y','MMM-d','M/d','M-d');
	dateFirst =new Array('d/M/y','d-M-y','d.M.y','d-MMM','d/M','d-M');
	var checkList=new Array('generalFormats',preferEuro?'dateFirst':'monthFirst',preferEuro?'monthFirst':'dateFirst');
	var d=null;
	for (var i=0; i<checkList.length; i++) {
		var l=window[checkList[i]];
		for (var j=0; j<l.length; j++) {
			d=getDateFromFormat(val,l[j]);
			if (d!=0) { return new Date(d); }
			}
		}
	return null;
	}


	function makeDoubleDelegate(function1, function2) { return function() { if (function1) function1(); if (function2) function2(); } }


	function getViewportDimensions() {
	    var intH = 0, intW = 0;

	    if (self.innerHeight) {
	        intH = window.innerHeight;
	        intW = window.innerWidth;
	    }
	    else {
	        if (document.documentElement && document.documentElement.clientHeight) {
	            intH = document.documentElement.clientHeight;
	            intW = document.documentElement.clientWidth;
	        }
	        else {
	            if (document.body) {
	                intH = document.body.clientHeight;
	                intW = document.body.clientWidth;
	            }
	        }
	    }

	    return {
	        height: parseInt(intH, 10),
	        width: parseInt(intW, 10)
	    };
	}

	function centerElement(elem, includeScrollOffsets) {
	    if (elem) {
	        var viewport = getViewportDimensions();
	        var left = (viewport.width == 0) ? 50 : parseInt((viewport.width - elem.offsetWidth) / 2, 10);
	        var top = (viewport.height == 0) ? 50 : parseInt((viewport.height - elem.offsetHeight) / 2, 10);
	        
	        if (includeScrollOffsets) {
	            var scrollTop = document.body.scrollTop;
	            if (scrollTop == 0) {
	                if (window.pageYOffset) { scrollTop = window.pageYOffset; }
	                else { scrollTop = (document.body.parentElement) ? document.body.parentElement.scrollTop : 0; }
	            }
	            top += scrollTop;

	            var scrollLeft = document.body.scrollLeft;
	            if (scrollLeft == 0) {
	                if (window.pageXOffset) { scrollLeft= window.pageXOffset; }
	                else { scrollLeft = (document.body.parentElement) ? document.body.parentElement.scrollLeft : 0; }
	            }
	            left += scrollLeft;
	        }

	        //left = left - (elem.clientWidth / 2);
	        //left = left - (document.body.childNodes[0].offsetLeft);
	        elem.style.left = left + 'px';
	        elem.style.top = top + 'px';
	    }
	}
	function getScrollXY() {
	    var scrOfX = 0, scrOfY = 0;
	    if (typeof (window.pageYOffset) == 'number') {
	        //Netscape compliant
	        scrOfY = window.pageYOffset;
	        scrOfX = window.pageXOffset;
	    } else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
	        //DOM compliant
	        scrOfY = document.body.scrollTop;
	        scrOfX = document.body.scrollLeft;
	    } else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
	        //IE6 standards compliant mode
	        scrOfY = document.documentElement.scrollTop;
	        scrOfX = document.documentElement.scrollLeft;
	    }
	    return {X: scrOfX, Y: scrOfY};
	}

	var _CurrentPopup, _previousScrollPosition;

	function showPopup(ctrlName, callerId, optionalShowBackground) {
	    var ctrl = document.getElementById(ctrlName);
	    var caller = document.getElementById(callerId);	    
	    
	    if (ctrl != null && _CurrentPopup != ctrl) {
            
	        if (ctrl.attributes["autohide"] && ctrl.attributes["autohide"].value == 'true') {
	            if (caller && caller.onmouseout == null) {
	                caller.onmouseout = hidePopup; 
	            }
	        }
	        
	        if (optionalShowBackground && document.getElementById('modalBackground')) {
	            document.getElementById('modalBackground').style.display = '';
	        }


	        hidePopup();
	        ctrl.style.display = "";
	        _CurrentPopup = ctrl;

	        if (ctrl.attributes["autoposition"] && ctrl.attributes["autoposition"].value) {
	            var autoposition = ctrl.attributes["autoposition"].value;
	            
	            if (autoposition == 'keepvisible') /*Doesn't work in Firefox */
	            {
	                if (caller) {
	                    var coords = getPageCoords(caller);
	                } else {
	                    var coords = getPageCoords(ctrl);
	                }

	                var windowWidth = GetWindowWidth();
	                var windowHeight = GetWindowHeight();

	                // need to make the div appear offscreen so the size is set
	                ctrl.style.top = coords.y;
	                ctrl.style.display = "block";
	                ctrl.style.position = "absolute";

	                var top = coords.y;

	                if ((windowHeight + GetWindowScrollTop()) < (top + ctrl.clientHeight)) {
	                    top = windowHeight + GetWindowScrollTop() - ctrl.clientHeight - 10;
	                }

	                // now set the left and top to the correct values
	                //ctrl.style.left = coords.x + 50;
	                ctrl.style.top = top;
	            }
	            else if (autoposition == 'centered') /* Works in FF3 and IE7 */
	            {
	                if (ctrl.parentNode != document.body) {
	                    document.body.appendChild(ctrl);
	                }
	                centerElement(ctrl, true);
	            }
	        }
	    }
	}

	function hidePopup() {
	    if (_CurrentPopup == undefined || _CurrentPopup == null) return;
	    _CurrentPopup.style.display = "none";

	    if (document.getElementById('modalBackground')) {
	        document.getElementById('modalBackground').style.display = 'none';
	    }
        /*
	    if (_previousScrollPosition && _CurrentPopup.attributes["autoscroll"] && _CurrentPopup.attributes["autoscroll"].value == 'true') {
	        scrollTo(_previousScrollPosition.X, _previousScrollPosition.Y);
	        _previousScrollPosition = null;
	    }*/
	    
	    _CurrentPopup = null;
	}

	function isMatchingFields(controlId1, controlId2, ignoreIfEmpty, isCaseSensitive) {
	    var c1 = document.getElementById(controlId1);
	    var c2 = document.getElementById(controlId2);

	    if (c1 == null || c2 == null) return true;
	    else {

	        if (ignoreIfEmpty == true && c2.value == "") return true;
	            
	        
	        if (isCaseSensitive == true) return (c1.value == c2.value);
	        else return (c1.value.toUpperCase() == c2.value.toUpperCase());
	    }
	}

	function setErrorMessage(hideErrorMessage, message, elementId) {
	    var e = document.getElementById(elementId);
	    if (e != null) {
	        if (hideErrorMessage) {
	            e.innerHTML = '';
	        }
	        else {
	            e.innerHTML = message;
	        }


            try {
                var marker;
                var children;
                if (e.tagName.toLowerCase() == 'td') {
                    if (e.parentNode.nextSibling.nodeType == 1)
                        children = e.parentNode.nextSibling.firstChild.childNodes;
                    else
                        children = e.parentNode.nextSibling.nextSibling.firstChild.nextSibling.childNodes;
                }
                else if (e.tagName.toLowerCase() == 'span') {
                    if (e.parentNode.parentNode.firstChild.childNodes.length != 0) {
                        children = e.parentNode.parentNode.firstChild.childNodes;
                    }
                    else {
                        children = e.parentNode.parentNode.firstChild.nextSibling.childNodes;
                    }
                }

	            if (!children) return;
	            for (var i = 0; i < children.length; i++) { if (children[i] && children[i].className && children[i].className.indexOf('customer_details_required_field_marker') == 0) { marker = children[i]; break; } }
                if (!marker) return;

                if ((hideErrorMessage & true) == true) {
                    AddCssStyle(marker, 'mandatory_field_completed');
                    return true;
                } else {
                    RemoveCssStyle(marker, 'mandatory_field_completed');
                    return false;
                }
	            
	        }
	        catch (ex) { }
	    }
	}

	function setPhoneNumberErrorMessage(phone, phoneError, phoneMarker, mobile, mobileError, mobileMarker, popuplateMarker) {

	    var phoneValid = false, phoneBlank = isBlank(phone);

	    if (!phoneBlank) {
	        phoneValid = isValidPhoneNumber(phone, '', false, false);
	        if (phoneValid) { //valid, don't show error message
	            document.getElementById(phoneError).innerHTML = '';
	        } else { //invalid, show error message
	            document.getElementById(phoneError).innerHTML = 'Telephone number must be valid.  Eg, 08 9111 1111.';
	        }
	    }
	    else { //blank, don't show error message
	        document.getElementById(phoneError).innerHTML = '';
	    }

	    var mobileValid = false, mobileBlank = isBlank(mobile);

	    if (!mobileBlank) {
	        mobileValid = isValidPhoneNumber(mobile, '', false, false);
	        if (mobileValid) { //valid, don't show error message
	            document.getElementById(mobileError).innerHTML = '';
	        } else { //invalid, show error message
	            document.getElementById(mobileError).innerHTML = 'Mobile phone number must be valid.  Eg, 0400 000 000.';
	        }
	    }
	    else { //blank, don't show error message
	        document.getElementById(mobileError).innerHTML = '';
	    }

	    if (phoneValid) { //phone valid, show as completed
	        SetVisible(phoneMarker, true);
	        AddCssStyle(document.getElementById(phoneMarker), 'mandatory_field_completed');
	    } else { //phone blank or invalid, don't show as completed
	        RemoveCssStyle(document.getElementById(phoneMarker), 'mandatory_field_completed');
	    }

	    if (mobileValid) { //mobile valid, show as completed
	        SetVisible(mobileMarker, true);
	        AddCssStyle(document.getElementById(mobileMarker), 'mandatory_field_completed');
	    } else { //mobile blank or invalid, don't show as completed
	        RemoveCssStyle(document.getElementById(mobileMarker), 'mandatory_field_completed');
	    }

        //if one input is valid
	    if (phoneValid || mobileValid) {
	        //requirement fulfilled, show contact number as completed
	        AddCssStyle(document.getElementById(popuplateMarker), 'mandatory_field_completed');
	        if (phoneValid && mobileBlank) {
	            SetVisible(mobileMarker, false); //mobile is no longer a requirement
	        } else if (phoneBlank && mobileValid) {
	            SetVisible(phoneMarker, false);  //phone is no longer a requirement
	        }
	    } else { //neither are valid, requirement marker visible, contact number is not completed
	        SetVisible(phoneMarker, true);
	        SetVisible(mobileMarker, true);
	        RemoveCssStyle(document.getElementById(popuplateMarker), 'mandatory_field_completed');
	    }
	    
	}

	function showTermsAndConditions(url) {
	    var eSessionId = document.getElementById("SessionId");
	    var sessionId;
	    if (eSessionId != null && eSessionId.value != null) {
	        sessionId = eSessionId.value;
	    } else {
	        sessionId = "";
	    }

	    window.open(url, 'termsandconditions' + sessionId, 'scrollbars=yes, toolbar = no, directories = no, status = no, menubar = no, width=800, height=250, resizable=yes, ').focus();
	}

	var v3_google_maps = new Object();
	//addGoogleMap(string controlId, decimal Latitude, decimal Longitude, int? ZoomLevel)
	//addGoogleMap(string controlId, string Address  , int? zoomLevel)
    function addGoogleMap(controlId, x, y, z, u) {
        var e;

        if (controlId && x && (e = document.getElementById(controlId))) {

            //check whether GoogleMaps javascript is included, if not the maps is impossible!
            if (!GBrowserIsCompatible) { //check method doesnt EXIST, not to invoke it.
                e.style.display = 'none'; //hide the map canvas as we cannot load google maps
                return;
            }

            var zoomLevel, uiOptions;
            
            if (v3_google_maps[controlId] != null) { //if map already in our array then no need to store the setup info again

                if (v3_google_maps[controlId].Map) return; //if already has a rendered map then drop out now

            } else if (typeof (x) == 'number') {    //use GPS co-ordinates
            
                v3_google_maps[controlId] = { ControlId: controlId, Control: e, Lat: x, Long: y, Map: null };
                zoomLevel = z;
                uiOptions = u;

            } else if (typeof (x) == 'string') { //use address
            
                v3_google_maps[controlId] = { ControlId: controlId, Control: e, Address: x, Map: null };
                zoomLevel = y;
                uiOptions = z;
                
            } else {                             //failed to receive enough data to add map
                return;
            }


            if (uiOptions && typeof(uiOptions) == 'object') {
                v3_google_maps[controlId].UIOptions = uiOptions;
            }
            
            if (zoomLevel && isFinite(zoomLevel) && zoomLevel > 0 && zoomLevel < 18) {
                v3_google_maps[controlId].ZoomLevel = zoomLevel;
            }
            
            //if Google Maps is ready then load this map straight away
            if (google_maps_ready) {
                initialiseGoogleMap(v3_google_maps[controlId]);
            }
        }
    }

    var google_geocoder, google_maps_ready = false, google_maps_gps_limits = null;
	function initialiseGoogleMaps() {
	    if (typeof (GBrowserIsCompatible) != 'undefined') {
	        if (GBrowserIsCompatible() && v3_google_maps) {
	            //add any maps pending to be rendered
	            var setupInfo;
	            for (var controlId in v3_google_maps) {
	                setupInfo = v3_google_maps[controlId];
	                if (!setupInfo || !setupInfo.Control) continue; //silently skip item

	                initialiseGoogleMap(setupInfo);
	            }
	            google_maps_ready = true;
	        }
	    }
	}

	function initialiseGoogleMap(setupInfo) {
	    if(setupInfo.Lat && setupInfo.Long) { //use LatLng
            renderGoogleMap(setupInfo, new GLatLng(setupInfo.Lat, setupInfo.Long));
        } else if (setupInfo.Address) {       //use Geocoder to get LatLng
            if (!google_geocoder) google_geocoder = new GClientGeocoder(); //make sure we have a geocoder instantiated
            google_geocoder.getLatLng(setupInfo.Address, function(point) { geocoderResponse(setupInfo, point); });
        }
    }

    function geocoderResponse(setupInfo, latlng) {
        if (latlng) { //successfully got the latlng from address
            setTimeout(function() { renderGoogleMap(setupInfo, latlng); }, 200);
        } else { //failed to get latlng, remove from map array
            var e = document.getElementById(setupInfo.ControlId);
            if (e) e.style.display = 'none';
            delete v3_google_maps[setupInfo.ControlId];
        }
    }

    function setGpsLimits(latitudeMin, latitudeMax, longitudeMin, longitudeMax) {
            google_maps_gps_limits = { latMin: latitudeMin,
                                       latMax: latitudeMax,
                                       lngMin: longitudeMin,
                                       lngMax: longitudeMax
                                     };
    }
    
    //setup and render map now
    function renderGoogleMap(setupInfo, latlng) {
        
        //if we have limitations on the GPS coordinates then check latlng
        if (google_maps_gps_limits && 
            google_maps_gps_limits.latMin && google_maps_gps_limits.latMax &&
            google_maps_gps_limits.lngMin && google_maps_gps_limits.lngMax) 
        {   //validate latlng
            if (latlng.lat() < google_maps_gps_limits.latMin || latlng.lat() > google_maps_gps_limits.latMax ||
               latlng.lng()  < google_maps_gps_limits.lngMin || latlng.lng() > google_maps_gps_limits.lngMax) 
            {
                var e = document.getElementById(setupInfo.ControlId);
                if (e) {
                    e.style.display = 'none';
                    e.innerHTML = "&lt;!-- No map because the coordinates were out of bounds. {lat: " + latlng.lat() + ", lng: " + latlng.lng() + "} Bounds: upper left {" + google_maps_gps_limits.latMin + ", " + google_maps_gps_limits.lngMin + "} lower right: {" + google_maps_gps_limits.latMax + ", " + google_maps_gps_limits.lngMax + "} --&gt;";
                }
                delete v3_google_maps[setupInfo.ControlId];
                return;
            }
        }

        var map = new GMap2(setupInfo.Control);
        
        if (setupInfo.ZoomLevel != undefined && isFinite(setupInfo.ZoomLevel) && setupInfo.ZoomLevel > 0 && setupInfo.ZoomLevel < 18) {
            map.setCenter(latlng, setupInfo.ZoomLevel);
        } else {
            map.setCenter(latlng, 10);
        }

        var ui = map.getDefaultUI();
        if (setupInfo.UIOptions) {
            var v = true;
            if (setupInfo.UIOptions.DisallowScrollWheel) v = false;
            ui.zoom.scrollwheel = v;

            v = true;
            if (setupInfo.UIOptions.DisallowDoubleClick) v = false;
            ui.zoom.doubleclick = v;
            
            v = true;
            if (setupInfo.UIOptions.DisallowKeyboard) v = false;
            ui.keyboard = v;

            v = true;
            if (setupInfo.UIOptions.DisallowMapTypeSelection) v = false;
            ui.controls.maptypecontrol = v;
            ui.controls.menumaptypecontrol = v;

            v = true;
            if (setupInfo.UIOptions.DisallowMapNormal) v = false;
            ui.maptypes.normal = v;
            
            v = true;
            if (setupInfo.UIOptions.DisallowMapSatellite) v = false;
            ui.maptypes.satellite = v;
            
            v = true;
            if (setupInfo.UIOptions.DisallowMapHybrid) v = false;
            ui.maptypes.hybrid = v; 
            
            v = true;
            if (setupInfo.UIOptions.DisallowMapPhysical) v = false;
            ui.maptypes.physical = v;

            map.setUI(ui);            
            
            if (setupInfo.UIOptions.MapType == G_NORMAL_MAP || setupInfo.UIOptions.MapType == G_HYBRID_MAP || setupInfo.UIOptions.MapType == G_PHYSICAL_MAP || setupInfo.UIOptions.MapType == G_SATELLITE_MAP)
                map.setMapType(setupInfo.UIOptions.MapType);
            else
                map.setMapType(G_NORMAL_MAP);

            if (setupInfo.UIOptions.ShowOverlayControl) {
                var overview = new GOverviewMapControl(new GSize(200, 150));
                map.addControl(overview);
                //setTimeout(function() { overview.getOverviewMap().addOverlay(new GMarker(latlng)); }, 10000);
            }
                
        } else {
            ui.zoom.scrollwheel = false;
            ui.controls.maptypecontrol = false;
            ui.controls.menumaptypecontrol = false;
            /*ui.maptypes.hybrid = false;
            ui.maptypes.physical = false;
            ui.maptypes.satellite = false;*/
            map.setUI(ui);
            map.setMapType(G_NORMAL_MAP);
        }
        
        
        
        /*
        var baseIcon = new GIcon(G_DEFAULT_ICON);
        baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
        baseIcon.iconSize = new GSize(34, 50); //baseIcon.iconSize = new GSize(20, 34);
        baseIcon.shadowSize = new GSize(37, 34);
        baseIcon.iconAnchor = new GPoint(11, 49); //baseIcon.iconAnchor = new GPoint(9, 34);
        baseIcon.infoWindowAnchor = new GPoint(9, 2);
        
        var customIcon = new GIcon(baseIcon);
        customIcon.image = '../../branding/default/images/map_sign20.gif'; // '../../branding/default/images/map_sign2.gif'
        // Set up our GMarkerOptions object
        var markerOptions = { icon: customIcon };
        map.addOverlay(new GMarker(latlng, markerOptions));
        */
        map.addOverlay(new GMarker(latlng)); //DEFAULT MARKER
        
        
        
        
        //store Map
        setupInfo.Map = map;
        //store LatLng object
        setupInfo.LatLng = latlng;

    }
    
	function setImageOnClickIfNecessecary(e, naturalWidth, naturalHeight, msg, cssName) {
	    //if img exists AND there is no onclick AND (total image area has been shrunk by more than 65%)
	    if (e && e.onclick == null && ((e.width * e.height) < (naturalWidth * naturalHeight * 0.35)))
	    {
	        var html = "<html><head><title>" + e.alt + "</title></head><body><img src=\"" + e.src + "\" alt=\"" + e.alt + "\" /></body></html>";
	        e.onclick = function() { var w = window.open('', 'v3_fullsized_image'); w.document.close(); w.document.open(); w.document.write(html); };
	        //e.onclick = function() { window.open(e.src, 'fullsized_image'); };
	        
	        if (msg) e.alt = msg;
	        else     e.alt = 'Click to see full size image';
	        
	        if (cssName) AddCssStyle(e, cssName);
	        else         AddCssStyle(e, 'image_links_to_fullsize_popup');
	    }
	}

	function linkToFullsizeImage(e, msg, cssName) {
	    if (!e) return;
	    
	    if (typeof (e) == 'string') { e = document.getElementById(e); }

	    if (e && e.tagName.toUpperCase() == 'IMG' && e.onclick == null) {
	        setTimeout(function() {
	            var img = new Image();
	            img.src = e.src;
	            setTimeout(function() { setImageOnClickIfNecessecary(e, img.width, img.height, msg, cssName); }, 2000); //do this 2 seconds after the image has been given a small chance to load
	        }, 10); //do this outside of the document load
	    }
	}

function expiryYearChanged(yearControl, monthControlId) {
    var monthControl = document.getElementById(monthControlId);
    if (!yearControl || !monthControl) return;

    var year = yearControl.value;
    var minMonth = 1;
    var today = new Date();
    if (year == today.getFullYear()) minMonth = today.getMonth() + 1; //we don't want to use index

    var currentMonthValue = parseInt(monthControl.value, 10);
    if (currentMonthValue > 0 && currentMonthValue < minMonth) currentMonthValue = minMonth;

    monthControl.options.length = 0;
    monthControl.options[monthControl.options.length] = new Option('', 0);
    
    for (var i = minMonth; i <= 12; i++) {
        if (i < 10)
            monthControl.options[monthControl.options.length]
              = new Option('0' + i + ' - ' + MONTH_NAMES[i + 11], '0' + i);
        else
            monthControl.options[monthControl.options.length]
              = new Option(i + ' - ' + MONTH_NAMES[i + 11], i);
        
        if (i == currentMonthValue) {
            monthControl.selectedIndex = monthControl.options.length - 1;
        }
    }
}

//this needs to be AFTER the function declaration, otherwise it isn't set... :(
//real - untested
setGpsLimits(-45.5, -8, 110, 180); //AU & NZ
//test
//setGpsLimits(-45.5, -8, 120, 180); //AU & NZ

