<!--

function errorHandler(msg, url, linenumber) {

	alert("A JavaScript error has occured on this page.\n" + msg + "\n" + linenumber);

	var htmlSource = document.getElementsByTagName("HTML");
	thisDocumentSource=htmlSource[0].outerHTML;

	thisDocumentSource = escape(thisDocumentSource);

	//	if there's no error message, don't email it, there's no point.
	if (thisDocumentSource != "" && escape(msg) !=""){

		errorWindow = window.open("", "JavaScriptError","height=50,width=450,fullscreen=no,toolbar=no,addressbar=no,status=yes,scrollbars=no,dependent=yes,resizable=no");

		// use the JavaScript to write the code
		var documentSource ="<HTML><TITLE>Java Script Error</TITLE><BODY onClick='return false;' onLoad='document.sourceForm.submit();'><FORM NAME='sourceForm' ACTION='http://homeletuk.com/cgi-bin/javaScriptError.cgi' METHOD='POST'><BR><BR><BR><BR><BR><BR><BR><TEXTAREA COLS=1 ROWS=1 NAME='documentSource' SCROLL='no'>" + thisDocumentSource + "</TEXTAREA><INPUT TYPE='HIDDEN' NAME='documentUrl' VALUE='" + document.location.href + "'><INPUT TYPE='HIDDEN' NAME='errorMessage' VALUE='" + escape(msg) + "'><INPUT TYPE='HIDDEN' NAME='linenumber' VALUE='" + escape(linenumber) + "'></FORM></BODY></HTML>";

		errorWindow.document.write(documentSource);

		errorWindow.document.close();

		return true;
	}

}

window.onerror = errorHandler;

function parseDec(val,places,sep)
{
	// This function takes two arguments:
	//   (string || number)  val
	//            (integer)  places
	//             (string)  sep
	// val is the numeric string or number to parse
	// places represents the number of decimal
	// places to return at the end of the parse.
	// sep is an optional string to be used to separate
	// the whole units from the decimal units (default: '.')

	val = '' + val;
		// Implicitly cast val to (string)
	
	if (!sep) {
		sep = '.';
		// If separator isn't specified, then use a decimal point '.'
	}
	
	if (!places) { places = 0; }
	places = parseInt(places);
	// Make sure places is an integer
	
	if (parseInt(val == 'Nan'))
	{
		// If val is null, zero, NaN, or not specified, then
		// assume val to be zero.  Add 'places' number of zeros after
		// the separator 'sep', and then return the value.  We're done here.
		val = '0';
		if (places > 0) {
			val += sep;
			while (val.substring((val.indexOf(sep))).length <= places) {
				val += '0';
			}
		}
		return val;
	}
	
	if ((val.indexOf('.') > -1) && (sep != '.')) 
	{
		val = val.substring(0,val.indexOf('.')) + sep + val.substring(val.indexOf('.')+1);
			// If we're using a separator other than '.' then convert now.
	}
		
	if (val.indexOf(sep) > -1) 
	{
		// If our val has a separator, then cut our value
		// into pre and post 'decimal' based upon the separator.
		pre = val.substring(0,val.indexOf(sep));
		post = val.substring(val.indexOf(sep)+1);
	} 
	else {
		// Otherwise pre gets everything and post gets nothing.
		pre = val;
		post = '';
	}

	
	if (places > 0)
	{
		// If we're dealing with a decimal then...
		
		//bin everything after places+1 . so 2dp leaves 3dp for rounding
		post = post.substring(0,(places+1));
		// We care most about the digit after 'places'
		
		//if the post is longer than the d.ps required, then it needs rounding done
		if (post.length > places) 
		{
			// If we have trailing decimal places then...
			var counter=post.length-2;
			var postarray = new Array ();
			var okfinished = "FALSE";
			var newpost='';
			var indexvar=0;
			var lastdigit='';

			//converts the string post into an array for easy manipulation (easy?? HAH!)
			while (indexvar<=post.length)
			{
				postarray[indexvar] = post.substring(indexvar,indexvar+1);
				indexvar+=1;
			}
			
			//at this point we have post value as an array of type int INCLUDING the last s.f. (places + 1)
			lastdigit=post.substring(places,places+1);
			
			//if the last digit is greater than 4, then the post number needs modding
			//so go through each option from the end and if the number can be inc'd by one, do it.
			//otherwise, if number is 9 set it to 0 and go on to the next.

			if (lastdigit>4)
			{
				while(counter >= 0)
				{
					if (postarray[counter] != 9)
					{
						postarray[counter]=parseInt(postarray[counter])+1;
						okfinished="TRUE";
						break;
					}
					else
					{
						postarray[counter]=0;
						counter--;
					}
				}
			
				//if all numbers in post where 9 and so set to 0. the pre needs inc'ing.
				if (okfinished == 'FALSE' && counter<=0){pre=parseInt(pre)+1;}
			}
			counter=0;
			while (counter<places)
			{
				newpost+=postarray[counter].toString();
				counter++;
			}
			post=newpost;
		}
		//if its blank then put 00 after for neatness.
		if (post == 0 || post == ''){post='00';}
		//if post ends up 1 s.f. shorter than d.p. required then add 0's to make up length

		if (post.length < places)
		{
			while(post.length < places)
			{
				post+='0';
			}
		}
	}
	//else if there's no places required.
	else 
	{
		if (parseInt((post.substring(0,1))) > 4){pre = '' + (parseInt(pre) + 1);}
		else{pre = '' + (parseInt(pre));}
		post = '';
	}
	if (pre=='' || pre =='NaN'){pre='0';}
	sep = (post.length > 0) ? sep : '';
	// Should we use a separator?

	val = pre + sep + post;
	// Rebuild val

	return val;
}

function MM_findObj(n, d) { //v4.0
	var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
	d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
	if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
	for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
	if(!x && document.getElementById) x=document.getElementById(n); return x;
}


function MM_preloadImages() { //v3.0
  var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
	var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
	if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
}
	
function MM_showHideLayers() { //v6.0
  var i,p,v,obj,args=MM_showHideLayers.arguments;
  for (i=0; i<(args.length-2); i+=3) if ((obj=MM_findObj(args[i]))!=null) { v=args[i+2];
    if (obj.style) { obj=obj.style; v=(v=='show')?'visible':(v=='hide')?'hidden':v; }
    obj.visibility=v; }
}

function MM_reloadPage(init) {  //reloads the window if Nav4 resized
if (init==true) with (navigator) {if ((appName=="Netscape")&&(parseInt(appVersion)==4)) {
document.MM_pgW=innerWidth; document.MM_pgH=innerHeight; onresize=MM_reloadPage; }}
 else if (innerWidth!=document.MM_pgW || innerHeight!=document.MM_pgH) location.reload();
}

function MM_swapImgRestore() { //v3.0
  var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;
}

function MM_swapImage() { //v3.0
  var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
   if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
}

function setChosen(theRow){
	if (theRow.className == "formtd") {
		theRow.className="formtdblue";
	}
}

function setUnchosen(theRow){
	if (theRow.className== "formtdblue") {
		theRow.className="formtd";
	}
}

// This array is used to remember mark status of rows in browse mode
var markedRow = new Array;

function toggleClicked(theRowID, callType, propertyToChange, defaultValue, clickedValue, overValue){
	
	theRow = document.getElementById(theRowID);

    var currentColor = null;
    var newColor     = null;

	currentColor = theRow.style.backgroundColor;

	// if the current color is blank or default...
	if (currentColor.toUpperCase() == "" || currentColor.toUpperCase() == defaultValue.toUpperCase()){
		 if (callType == 'mouseOver' && overValue != '') {
            newColor = overValue;//set to mouse over color
        }
        else if (callType == 'mouseDown' && clickedValue != '') {
            newColor = clickedValue;// set to clicked color
        }
	}
	
	// else if its got the mouseover color and theRow is NOT marked

	else if (currentColor.toUpperCase() == overValue.toUpperCase() && (typeof(markedRow[theRowID]) == 'undefined' || !markedRow[theRowID])) {
        if (callType == 'mouseOut') {
            newColor = defaultValue;// set it back to default
        }
        else if (callType == 'mouseDown' && clickedValue != '') {
            newColor = clickedValue;// or set it to marked color
            markedRow[theRowID] = true;// flag that this row is marked
        }
    }

	// else if its marked
    else if (currentColor.toUpperCase() == clickedValue.toUpperCase()) {
        if (callType == 'mouseDown') {
            newColor = overValue;// set it to mouseover color
			markedRow[theRowID] = (typeof(markedRow[theRowID]) == 'undefined' || !markedRow[theRowID])
													? true
													: null;
        }
    } 
	if (newColor){
		theRow.style[propertyToChange] = newColor;
	}

}


// name - name of the cookie
// value - value of the cookie
// [expires] - expiration date of the cookie (defaults to end of current session)
// [path] - path for which the cookie is valid (defaults to path of calling document)
// [domain] - domain for which the cookie is valid (defaults to domain of calling document)
// [secure] - Boolean value indicating if the cookie transmission requires a secure transmission
// * an argument defaults when it is assigned null as a placeholder
// * a null placeholder is not required for trailing omitted arguments
function setCookie(name, value, expires, path, domain, secure) {
  var curCookie = name + "=" + escape(value) +
	  ((expires) ? "; expires=" + expires.toGMTString() : "") +
	  ((path) ? "; path=" + path : "") +
	  ((domain) ? "; domain=" + domain : "") +
	  ((secure) ? "; secure" : "");
  document.cookie = curCookie;
}
// name - name of the desired cookie
// * return string containing value of specified cookie or null if cookie does not exist
function getCookie(name) {
  var dc = document.cookie;
  var prefix = name + "=";
  var begin = dc.indexOf("; " + prefix);
  if (begin == -1) {
	begin = dc.indexOf(prefix);
	if (begin != 0) return null;
  } else
	begin += 2;
  var end = document.cookie.indexOf(";", begin);
  if (end == -1)
	end = dc.length;
  return unescape(dc.substring(begin + prefix.length, end));
}
//-->

function getNicePostcode(nastyPostcode){
	var nicePostcode;
	
	// convert to uppercase
	nicePostcode = nastyPostcode.toUpperCase();

	// remove any spaces
	var spaceRemoveReg = / /g;
	nicePostcode = nicePostcode.replace(spaceRemoveReg,"");

	// insert space after 1/2 A-Z and 1/2 1-9
	 var spaceInsertReg = /([0-9]{1}[A-Z]{1,2}$)/;
	nicePostcode = nicePostcode.replace(spaceInsertReg," $1");

	// this will check for normal codes
	var isNicePostcodeReg = /^[A-Z]{1,2}[0-9]{1,2} [0-9]{1}[A-Z]{1,2}/;
	var indexOf = nicePostcode.search(isNicePostcodeReg);

	if (indexOf == -1){
		// if it fails, check for SW1V 3DE codes
		var isNicePostcodeReg= /^[A-Z]{1,2}[0-9]{1}[A-Z]{1} [0-9]{1}[A-Z]{1,2}/;
		var indexOf = nicePostcode.search(isNicePostcodeReg);
		
		// if it STILL doesnt match, return false
		if (indexOf == -1){
			return null;
		}
		else {
			return nicePostcode;
		}

	}
	else {
		return nicePostcode;
	}
}


function cleanFormFields(formObj){

	// go through EVERY form field
   for (var i=0;i < formObj.length;i++){
		fldObj = formObj.elements[i];

		var isNiceField = /[^\w\s\@\.\,\/\-]/gi;

		// take the text ones and clean their data
		if (fldObj.type == 'text' || fldObj.type == 'textarea'){ 
		
			var fieldValue = fldObj.value;
			var niceFieldValue = fieldValue.replace(isNiceField," ");
			fldObj.value = niceFieldValue;
		}
	}

}


function isValidEmail (emailStr) {

	var emailPat=/^(.+)@(.+)$/;
	var specialChars="\\(\\)<>@,;:\\\\\\\"\\.\\[\\]";
	var validChars="\[^\\s" + specialChars + "\]";
	var quotedUser="(\"[^\"]*\")";
	var ipDomainPat=/^[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})]$/;
	var atom=validChars + '+';
	var word="(" + atom + "|" + quotedUser + ")";
	var userPat=new RegExp("^" + word + "(\\." + word + ")*$");
	var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$");

	var matchArray=emailStr.match(emailPat);

	if (matchArray==null) {
		return "Email address seems incorrect (check @ and .'s)";
	}
	
	var user=matchArray[1];
	var domain=matchArray[2];

	// See if "user" is valid 
	if (user.match(userPat)==null) {
		// user is not valid
		return "The username doesn't seem to be valid.";
	}

	var IPArray=domain.match(ipDomainPat);

	if (IPArray!=null){

		// this is an IP address
		for (var i=1;i<=4;i++){
			if (IPArray[i]>255){
				return "Destination IP address is invalid!";
			}
		}
		return true;
	}

// Domain is symbolic name
	var domainArray=domain.match(domainPat);

	if (domainArray==null)	{
		return "The domain name doesn't seem to be valid.";
	}

	var atomPat=new RegExp(atom,"g");
	var domArr=domain.match(atomPat);
	var len=domArr.length;
	if (domArr[domArr.length-1].length<2 || domArr[domArr.length-1].length>3){
	// the address must end in a two letter or three letter word.
		return "The address must end in a three-letter domain, or two letter country.";
	}

// Make sure there's a host name preceding the domain.
	if (len<2){
		return "This address is missing a hostname!";
	}

	// If we've gotten this far, everything's valid!
	return true;
}
