//<SCRIPT>

function ShowGridRef(sTarget, sLetters, sEast, sNorth, sZoom)
{
	var DEFAULTZOOM = "3";
	// validate and cleanup input
	// First trim all the data
	sTarget  = Trim(sTarget);
	sLetters = Trim(sLetters);
	sEast    = Trim(sEast);
	sNorth   = Trim(sNorth);
	sZoom    = Trim(sZoom);
	
	if(sTarget == "")
	{
		sTarget = "_self";
	}
	if(sZoom == "")
	{
		sZoom = DEFAULTZOOM;
	}
	else
	{
		if(ParseInteger(sZoom).isNan)
		{
			sZoom = DEFAULTZOOM;
		}
	}

	if(ParseGridRefNumbers(sEast, sNorth) == 0)
	{
		var x = 0;
		var y = 0;

		switch(sLetters)
		{
			case "HP":
				x = 4;
				y = 12;
				break;
			//////////
			case "HT":
				x = 3;
				y = 11;
				break;
			
			case "HU":
				x = 4;
				y = 11;
				break;
			//////////
			case "HW":
				x = 1;
				y = 10;
				break;
			
			case "HX":
				x = 2;
				y = 10;
				break;
			
			case "HY":
				x = 3;
				y = 10;
				break;
			
			case "HZ":
				x = 4;
				y = 10;
				break;
			//////////
			case "NA":
				x = 0;
				y = 9;
				break;
			
			case "NB":
				x = 1;
				y = 9;
				break;
			
			case "NC":
				x = 2;
				y = 9;
				break;
			
			case "ND":
				x = 3;
				y = 9;
				break;
			//////////
			case "NF":
				x = 0;
				y = 8;
				break;
			
			case "NG":
				x = 1;
				y = 8;
				break;
			
			case "NH":
				x = 2;
				y = 8;
				break;
			
			case "NJ":
				x = 3;
				y = 8;
				break;
			
			case "NK":
				x = 4;
				y = 8;
				break;
			//////////
			case "NL":
				x = 0;
				y = 7;
				break;
			
			case "NM":
				x = 1;
				y = 7;
				break;
			
			case "NN":
				x = 2;
				y = 7;
				break;
			
			case "NO":
				x = 3;
				y = 7;
				break;
			//////////
			case "NR":
				x = 1;
				y = 6;
				break;
			
			case "NS":
				x = 2;
				y = 6;
				break;
			
			case "NT":
				x = 3;
				y = 6;
				break;
			
			case "NU":
				x = 4;
				y = 6;
				break;
			//////////
			case "NW":
				x = 1;
				y = 5;
				break;
			
			case "NX":
				x = 2;
				y = 5;
				break;
			
			case "NY":
				x = 3;
				y = 5;
				break;
			
			case "NZ":
				x = 4;
				y = 5;
				break;
			//////////
			case "SC":
				x = 2;
				y = 4;
				break;
			
			case "SD":
				x = 3;
				y = 4;
				break;
			
			case "SE":
				x = 4;
				y = 4;
				break;
			
			case "TA":
				x = 5;
				y = 4;
				break;
			//////////
			case "SH":
				x = 2;
				y = 3;
				break;
			
			case "SJ":
				x = 3;
				y = 3;
				break;
			
			case "SK":
				x = 4;
				y = 3;
				break;
			
			case "TF":
				x = 5;
				y = 3;
				break;
			
			case "TG":
				x = 6;
				y = 3;
				break;
			//////////
			case "SM":
				x = 1;
				y = 2;
				break;
			
			case "SN":
				x = 2;
				y = 2;
				break;
			
			case "SO":
				x = 3;
				y = 2;
				break;
			
			case "SP":
				x = 4;
				y = 2;
				break;
			
			case "TL":
				x = 5;
				y = 2;
				break;
			
			case "TM":
				x = 6;
				y = 2;
				break;
			//////////
			case "SR":
				x = 1;
				y = 1;
				break;
			
			case "SS":
				x = 2;
				y = 1;
				break;
			
			case "ST":
				x = 3;
				y = 1;
				break;
			
			case "SU":
				x = 4;
				y = 1;
				break;
			
			case "TQ":
				x = 5;
				y = 1;
				break;
			
			case "TR":
				x = 6;
				y = 1;
				break;
			//////////
			case "SV":
				x = 0;
				y = 0;
				break;
			
			case "SW":
				x = 1;
				y = 0;
				break;
			
			case "SX":
				x = 2;
				y = 0;
				break;
			
			case "SY":
				x = 3;
				y = 0;
				break;
			
			case "SZ":
				x = 4;
				y = 0;
				break;
			
			case "TV":
				x = 5;
				y = 0;
				break;
				
			default:
				sLetters = "--";
				break;
		
		}
		if(sLetters == "--")
		{
			alert("The two letter 100km grid square must be specified.\nThe following letters are valid:\n" +
						"                HP         \n" +
						"            HT, HU         \n" +
						"    HW, HX, HY, HZ         \n" +
						"NA, NB, NC, ND             \n" +
						"NF, NG, NH, NJ, NK         \n" +
						"NL, NM, NN, NO             \n" +
						"    NR, NS, NT, NU         \n" +
						"    NW, NX, NY, NZ         \n" +
						"        SC, SD, SE, TA     \n" +
						"        SH, SJ, SK, TF, TG \n" +
						"    SM, SN, SO, SP, TL, TM \n" +
						"    SR, SS, ST, SU, TQ, TR \n" +
						"SV, SW, SX, SY, SZ, TV     ");
		}
		else
		{
			x *= 100000;
			y *= 100000;
			var nNumbMultiplier = Math.pow(10,(5 - (sEast.length)));
			x += ParseInteger(sEast)  * nNumbMultiplier;
			y += ParseInteger(sNorth) * nNumbMultiplier;
			
			var bStreetmapMode = false;
			if (bStreetmapMode)
			{
				// Special Streetmap parameter. If this is not set to the correct
				// value, which increments daily, then Streetmap will ignore
				// the zoom parameter.
				var dToday          = new Date();              // Create Date object with today's date.
				var dStreetmapStart = new Date();              // Create Date object with today's date.
				dStreetmapStart.setFullYear(2002,3,15);
				var sStreetmapDateVar = "&dn=" + Math.round((dToday.valueOf() - dStreetmapStart.valueOf()) / 1000 / 60 / 60 / 24);
				
				var sUrl = "http://www.streetmap.co.uk/newmap.srf?x=" + x + "&y=" + y + "&z=" + sZoom + sStreetmapDateVar;
			}
			else
			{
				switch(sZoom)
				{
					case "1":
						sZoom = "5000";
						break;
					
					case "2":
						sZoom = "10000";
						break;
					
					case "3":
						sZoom = "25000";
						break;

					case "4":
						sZoom = "50000";
						break;

					case "5":
						sZoom = "100000";
						break;

					default:
						sZoom = "25000";
						break;
				}
				
				var sUrl = "http://www.multimap.com/map/browse.cgi?pc+&GridE=" + x + "&GridN=" + y + "&scale=" + sZoom
			}
			var GridWindow = window.open(sUrl,sTarget);
			GridWindow.focus();
		}
	}
}

function ParseGridRefNumbers(sEast, sNorth)
{
	// Returns 0 on sucess
	// 1 on eastings error
	// 2 on nortings error

	// First trim all the data
	sEast    = Trim(sEast);
	sNorth   = Trim(sNorth);

	if((!IsNumbersOnly(sEast)) || sEast == "") 
	{
		alert("The eastings (the longitude or east-west co-ordinates) must be specified.");
		return 1;
	}
	else
	{
		if((!IsNumbersOnly(sNorth)) || sNorth == "")	
		{
			alert("The northings (the latitude or north-south co-ordinates) must be specified.");
			return 2;
		}
		else
		{
			if(sEast.length != sNorth.length)
			{
				alert("The eastings and the northings must have the same number of digits.");
				return 1;
			}
			else
			{
				if(sEast.length > 5)
				{
					alert("The eastings and the northings must have 1 to 5 digits.");
					return 1;
				}
				else
				{
					return 0;
				}
			}
		}
	}
}

function IsUKDate(sDateString)
{
/*==================================================================================
' Description:  Tests whether a given date is a valid UK date irrespective of 
'               machine locale settings
' Inputs:       sDateString : Date string to be tested
' Outputs:      returns true if the date is valid
' Assumptions:  None
'=================================================================================*/
	// First work out what separator the user has used (accept / \ - . and space)
	var sSeparator;
	if(sDateString.indexOf("/") > -1)
	{
		sSeparator = "/";
	}
	else
	{
		if(sDateString.indexOf("\\") > -1)
		{
			sSeparator = "\\";
		}
		else
		{
			if (sDateString.indexOf("-") > -1)
			{
				sSeparator = "-";
			}
			else
			{
				if (sDateString.indexOf(".") > -1)
				{
					sSeparator = ".";
				}
				else
				{
					if (sDateString.indexOf(" ") > -1)
					{
						sSeparator = " ";
					}
					else
					{
						// Invalid seperator return false
						return false;
					}
				}	
			}
		}
	}
	
	var sDateParts;
	sDateParts = sDateString.split(sSeparator);
	if (sDateParts.length != 3)
	{
		// Invalid number of date parts
		// return false
		return false;
	}
	else
	{
		if (isNaN(ParseInteger(sDateParts[0])))
		{
			// Invalid number for the day
			// return false
			return false;
		}
		else
		{
			if (isNaN(ParseInteger(sDateParts[1])))
			{
				// Invalid number for the month
				// return false
				return false;
			}
			else
			{
				if (isNaN(ParseInteger(sDateParts[2])))
				{
					// Invalid number for the year
					// return false
					return false;
				}
				else
				{
					// All the parts are valid numbers
					var nDay;
					var nMonth;
					var nYear;

					nDay   = ParseInteger(sDateParts[0]); 
					nMonth = ParseInteger(sDateParts[1]);
					nYear  = ParseInteger(sDateParts[2]);
						
					// Don't accept dates above 9999
					// if (nYear < 100 || nYear > 9999)
					if (nYear > 9999)
					{
						return false;
					}
					else
					{
						// Don't accept months outside 1 - 12
						if (nMonth < 1 || nMonth > 12)
						{
							return false;
						}
						else
						{
							// Don't accept days less than 1
							if (nDay < 1)
							{
								return false;
							}
							else
							{
								// Finally check that there are not too many days in the month
								                        //J, F, M, A, M, J, J, A, S, O, N, D
								var nDayArray = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
								if (IsLeapYear(nYear) && nMonth == 2)
								{
									if (nDay > 29)
									{
										return false;
									}
									else
									{
										return true;
									}
								}
								else
								{
									if (nDay > nDayArray[nMonth-1])
									{
										return false; 
									}
									else
									{
										return true;
									}
								}
							}
						}
					}
				}
			}
		}
	}
}

function ParseUKDate(sDateString)
{
/*==================================================================================
' Description:  Parses a date string in UK format (dd/mm/yyyy) (various other 
'               separators are also accepted) and returns a date variant This works
'               irrespective of machine locale settings
' Inputs:       sDateString : Date string to be parsed
' Outputs:      returns the date
' Assumptions:  The date is a valid date string as tested by IsUKDate
'=================================================================================*/
	// Create a default invalid date to return if there is aproblem
	var dInvalidDate = new Date(1900, 1, 1);
	
	// Next work out what separator the user has used (accept / \ - . and space)
	var sSeparator;
	
	if(sDateString.indexOf("/") > -1)
	{
		sSeparator = "/";
	}
	else
	{
		if(sDateString.indexOf("\\") > -1)
		{
			sSeparator = "\\";
		}
		else
		{
			if (sDateString.indexOf("-") > -1)
			{
				sSeparator = "-";
			}
			else
			{
				if (sDateString.indexOf(".") > -1)
				{
					sSeparator = ".";
				}
				else
				{
					if (sDateString.indexOf(" ") > -1)
					{
						sSeparator = " ";
					}
					else
					{
						// Invalid seperator return a dummy date
						// this should not occur is the date has already
						// been tested to ensure it is acceptable
						return dInvalidDate;
					}
				}	
			}
		}
	}

	var sDateParts;
	try
	{
		// Assuming that the date has been tested (see assumptions) 
		// this should all run without error, so if any errors occur
		//  then just return the invalid date
		sDateParts = sDateString.split(sSeparator);
	
		var nDay;
		var nMonth;
		var nYear;
		
		nDay   = ParseInteger(sDateParts[0]); 
		nMonth = ParseInteger(sDateParts[1]);
		nYear  = ParseInteger(sDateParts[2]);
		
		//Allow the user to enter 2 digit year.  Assume < year 2000 when 2 digit.
		if(nYear < 100)
		{
			nYear = nYear + 2000;
		}	
		// return the parsed date
		var dValidDate = new Date(nYear, nMonth - 1, nDay);
		return dValidDate;
	}
	catch (err)
	{
		// There was an error so return the dummy date
		return dInvalidDate;
	}
}

function ParseInteger(sIntegerString)
/*==================================================================================
' Description:  Parses an interger by removing leadingzeros and then using parseInt.
'               If leading zeros are not removed then the number is treated as octal.
' Inputs:       sIntegerString : Number string to be parsed
' Outputs:      returns number
' Assumptions:  None
'=================================================================================*/
{
	// Tidyup the input
	var sTemp = Trim(sIntegerString);
	// Remove leading zeros
	while (sTemp.charAt(0) == '0' && sTemp.length > 1)
		sTemp = sTemp.substring(1, sTemp.length);
	// Now use parseInt;
	return parseInt(sTemp);	
}

function FormatUKDateTime(dDateTime)
/*==================================================================================
' Description:  Renders a date time variable in a UK date format irrespective of any
'               other factors such as the locale of the user currently logged in to
'               the server console.
' Inputs:       dDateTime : Date time to be rendered
' Outputs:      returns a date as a string in a UK format
' Assumptions:  dDateTime is a variant of type date. If a string is passed in the 
'               results may depend on the current system locale.
'=================================================================================*/
{
	var sDateString;
	var nDatePart;
	nDatePart   =  dDateTime.getDate();
	sDateString =  ((nDatePart < 10)?"0":"") + nDatePart.toString();
	sDateString += "/";
	nDatePart   =  dDateTime.getMonth() + 1;
	sDateString += ((nDatePart < 10)?"0":"") + nDatePart.toString();
	sDateString += "/";
	sDateString += dDateTime.getFullYear().toString();
	return sDateString;
}


function IsLeapYear(nYear)
/*==================================================================================
' Description:  Test whether a given year is a leap year.
' Inputs:       nYear: year to be tested
' Outputs:      returns true if the year is a leap year otherwise returns false
' Assumptions:  None
'=================================================================================*/
{
	if ((nYear % 400) == 0)
	{
		return true;
	}
	else
	{
		if ((nYear % 100) == 0)
		{
			return false;
		}
		else
		{
			if ((nYear % 4) == 0)
			{
				return true;
			}
			else
			{
				return false;
			}
		}
	}
}

function Trim(sSource)
/*==================================================================================
' Description:  Trims whitespace from the begining and end of a string
' Inputs:       sSource: string to be trimmed
' Outputs:      returns the trimmed string
' Assumptions:  None
'=================================================================================*/
{
	var sTemp = "" + sSource + "";
	return sTemp.replace(/^\s*|\s*$/g, "");
}

function LTrim(sSource)
/*==================================================================================
' Description:  Trims whitespace from the begining of a string
' Inputs:       sSource: string to be trimmed
' Outputs:      returns the trimmed string
' Assumptions:  None
'=================================================================================*/
{
	var sTemp = "" + sSource + "";
	return sTemp.replace(/^\s*/g, "");
}

function RTrim(sSource)
/*==================================================================================
' Description:  Trims whitespace from the end of a string
' Inputs:       sSource: string to be trimmed
' Outputs:      returns the trimmed string
' Assumptions:  None
'=================================================================================*/
{
	var sTemp = "" + sSource + "";
	return sTemp.replace(/\s*$/g, "");
}

function IsLettersOnly(sSource)
/*==================================================================================
' Description:  Return whether
' Inputs:       sSource: string to be tested
' Outputs:      returns true if the string only contains letters a-z, otherwise it
'               returns false
' Assumptions:  None
'=================================================================================*/
{
	var reLetters = new RegExp("[^a-z]+");
	return !reLetters.test(sSource);
}
function IsNumbersOnly(sSource)
/*==================================================================================
' Description:  Return whether
' Inputs:       sSource: string to be tested
' Outputs:      returns true if the string only contains numbers, otherwise it
'               returns false
' Assumptions:  None
'=================================================================================*/
{
	var reNumbers = new RegExp("[^0-9]+");
	return !reNumbers.test(sSource);
}

