//<LINK name="author" HREF="http://www.holderness.eu">
//<LINK name="license" TYPE="free to nonprofit organisations; others make an offer - see:" HREF="http://www.poptel.org.uk/nuj/mike/js.htm">
//<META name="warning" content="I am actively looking for test cases to prosecute!">

/* generic */
var imgOn, imgOff, homeOn;
var version="veryplain";
var subversion="ok";
var isMac=false;
var ready=false;
var MenuInt=null;
var WaitInt=null;
var mX =		120;	/* size of #nav - er, empirically set */
var mY =		484;	
var wWidth =		800;	/* defaults - try odd behaviour on Macs instead of crapping out */
var wHeight = 		600;
var MsgWidth =		200;	/* see in .css */
var ContentWidth=	500;	/* empirical browser compromise - not used 27/06/05 */
var menuX=	 540;	
var mMargin=	  10;	

/* special to cell-tagging - left in, in case */
var highlightColor="yellow";
var visitedColor="#CCCC99";
var tagged="";

/* special to forms */
var daylen=86400000.00;
var formOK=true;
var infinite=Number.POSITIVE_INFINITY;
var showNumErr=infinite;
var showDatErr=infinite;
var showPhoErr=infinite;
var methuselah=90;
var norm="white";
var errr="yellow";
var stuf="aqua";
var unkn="silver";
var nonf="rgb(204,204,204)";
var resl="rgb(153,255,153)";
var OKbtn="submit";
var msgCount=0;
var maxMsg=4;
var msgs;
var errorMsg="";
var ErrHeader="<TITLE>Messages</TITLE>\n"
	+"<STYLE type=text/css>BODY {font-family:sans-serif; padding:0px; background:yellow} TD {font-size:10pt} TD.caption {background:rgb(192,192,192)} .msgHed {font-weight:bold}</STYLE>" /* minima for Op 5*/
	+"<LINK rel=\"stylesheet\" type=\"text/css\" href=\"error.css\">\n"
	+"<SCRIPT type=\"text/javascript\" language=\"JavaScript1.3\">\n"
	+"var xCaller;\n"
	+"function closeMsg(){window.close()}\n"
	+"function ignoreDate(){window.opener.document.state.ignoreDate.value=\"Y\";window.opener.document.thisForm.z_validate.value+=\" ! Member's computer clock is wrong - CHECK DATES\\n\";closeMsg()}\n"
	+"function postDate() {window.opener.document.state.postDated.value=\"Y\";window.opener.document.thisForm.z_validate.value+=\" ! Member says payment due before delivery\\n\";closeMsg()}\n"
	+"function scriptError(){window.opener.document.state.abortCheck.value=\"Y\";window.opener.document.thisForm.z_validate.value+=\" ! Member reports error in error message\\n\";closeMsg()}\n"
	+"</SCRIPT></HEAD>\n"
	+"<BODY class=\"Msg\">\n";
var MsgHeader="<TABLE id=\"sizer\" class=\"Msg\">\n";
var MsgFooter="\n</TD></TR></TABLE>";
var ErrFooter="</BODY></HTML>";
var checkStep=0;
var errorsShewn=false;
var waitShewn=false;
var sendShewn=false;
var doPopUp=false;
var messageWin=null;
var resultsWin=null;

var instruct="</TD></TR>\n<TR><TD class=\"caption\">[Oops...].";

var weekday= ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
var dD="/"; /* dateDelim */
var today=new Date();
var noDate=new Date(0,0,0);
var thisCent=20;
var errorM = new msgObject("");
var postPat = new RegExp("","")

function msgObject(val) {
	this.val=val;
};

function init() {
	GetVersion();
	window.defaultStatus="*";
	if (document.thisForm.elements["z_OK"]) {
		OKbtn="";
		with (document.thisForm.elements["z_OK"]) {
			OKend=value.indexOf("\ ");
			if (OKend==-1) {OKend=value.length} else {OKbtn="..."}
			OKbtn=value.substr(0,OKend)+OKbtn;
		}
	}
	instruct="</TD></TR>\n<TR><TD class=\"caption\"><B>If</B> the warnings above are <EM>all</EM> rubbish, <A HREF=javascript:scriptError()>click to ignore them</A> then click <SPAN class=butt>["+OKbtn+"]</SPAN> again. Otherwise click in the 'field' by each question &amp; type in the right answer. <B><EM>Thanks</EM></B>.";

	/* hide the "JS is off" warning 'cos it isn't */
	if (version=="ECMA") {
		document.getElementById("JSwarn").style.display="none";
		document.getElementById("JSwarn").style.visibility="hidden" /* fix for broken Opera display model*/
	}
	else if (version=="Nav4") {
		document.JSwarn.display="none";
		document.JSwarn.visibility="hide"; /* superstition */
	}
	else if (version=="IE5") {
		document.all.JSwarn.style.display="none"
	}
	if (version!="veryplain") { 
		if (typeof(homeOn)=="undefined") {
			homeOff= new Image(mX,mY);	homeOff.src= "gif/nuj.gif";
			homeOn=  new Image(mX,mY); 	homeOn.src=  "gif/nuj.gif";
		}
		RefrT=	120;

		if (MenuInt==null) {
			MenuInt = setInterval("MenuRefresh(false)",RefrT);
			window.onUnload=stopscript;
		}
	ready=true;
	msgCount=0;
	checkStep=0;
	postPat.compile("[A-PR-UWYZ][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA","")
//	postPat.compile("[A-PR-UWYZ]{1,2}[0-9]{1,2}[A-Z]? ?[0-9][ABDEFGHJLNPQRSTUWXYZ]{2}","")
	}/* !loaded home && !veryplain */
}; /*init() */

function GetVersion() {
var OperaVer="0";
	vernum=navigator.appVersion.charAt(0);
	isMac=navigator.appVersion.indexOf("Mac") > 1;
	OperaPos=navigator.userAgent.indexOf("Opera");
	if (OperaPos>=0) {OperaVer = navigator.userAgent.substr(OperaPos+6,4)}
	if (vernum >= "4") {
		if (navigator.appName == "Microsoft Internet Explorer") {
			if ((navigator.appVersion.indexOf("MSIE 4.5") > 1 && isMac)
			 || navigator.appVersion.indexOf("MSIE 5") > 1 
			 || navigator.appVersion.indexOf("MSIE 6") > 1) {
				version="IE5";
				if (navigator.appVersion.indexOf("MSIE 6")>1 && navigator.appVersion.indexOf("Windows")>1) {
					subversion="IE6grr"
				}
			}
			else {
				version="veryplain";
			}
		}
		else if (navigator.appName=="Netscape" && vernum=="4") {
			version="Nav4";
		} 
		else {
			version="ECMA";
		}
	}
	if (version=="ECMA") {
		if (OperaVer>"0" && OperaVer<"5.11") {
			version="veryplain";
		}
		else if (typeof(document.getElementById("nav").style)=="undefined") {
			version="veryplain";
		}
		else {
			window.onresize=resizer;
			if (OperaVer>"0" && OperaVer<"7") {
				subversion="oldOpera";
			}
		}
	}
	else if (version=="Nav4") {
		if (typeof(document.nav)=="undefined" || isMac || OperaVer!="0") {
			version="veryplain";
		}
		else {
			window.onresize=resizer;
		}
	}
	else if (version=="IE5") {
		if (typeof(document.all.nav.style)=="undefined" || OperaVer!="0") {
			version="veryplain"; 
		}
		else {
			self.window.onresize=resizer;
		}
	}
	GetWindowSize();  	/*also sets menuX! */
	doPopUp=(subversion=="oldOpera");
}; /* GetVersion()  */

function resizer() {
	GetWindowSize();
	MenuRefresh(true);
	if (document.ownerForm) {placeOwners()}
};

function stopscript() {
	clearInterval(MenuInt);
};

function GetWindowSize() { /*menu on right */
	if (version=="IE5") {
		if (subversion=="IE6grr") {
			Wwidth=document.documentElement.clientWidth;
			Wheight=document.documentElement.clientHeight;
		}
		else {
			Wwidth=document.body.clientWidth;
			Wheight=document.body.clientHeight;
		}
//		menuX=ContentWidth+(Wwidth-ContentWidth)/2-mX;
		menuX=Wwidth-2*mX;
	}
	else if (version=="Nav4" || version=="ECMA") {
		Wwidth=window.innerWidth;
		Wheight=window.innerHeight;
//		menuX=ContentWidth+(Wwidth-ContentWidth)/2-mX;
		menuX=Wwidth-2*mX;
	}
};

function MenuRefresh(forced) {
	if (version=="ECMA") {
		with (document.getElementById("nav").style) {
			left 	= menuX + window.pageXOffset;
			top 	= mMargin + window.pageYOffset;
			width	= MsgWidth;
		}
		with (document.getElementById("MsgBox").style) {
			left 	= Wwidth - MsgWidth - 2*mMargin;
			top 	= mMargin + pageYOffset;
			width	= MsgWidth;
		}
	}
	else if (version=="Nav4") {
		with (document.nav) {
			left	= menuX + pageXOffset;
			top	= mMargin + pageYOffset;
			width	= MsgWidth;
		}
		with (document.MsgBox) {
			left	= Wwidth - MsgWidth - mMargin;
			top	= mMargin + pageYOffset;
			width	= MsgWidth;
		}
	}
	else if (version=="IE5") {
		with (document.all.nav.style) {
			if (subversion=="IE6grr") {
				left = menuX + document.documentElement.scrollLeft;
				top = mMargin + document.documentElement.scrollTop;
				width	= MsgWidth;
			}
			else if (!isMac) {
				left = menuX + document.body.scrollLeft; 
				// ^ IE5 Mac: "L 251: invalid procedure or argument"
				top = mMargin + document.body.scrollTop;
				width	= MsgWidth;
			}
		} 
		if (!isMac) {
			with (document.all.MsgBox.style) {
				left	= Wwidth - MsgWidth - mMargin;
				top	= document.all.nav.style.top;
				width	= MsgWidth;
			}
		} 
	}
};

function showCurr(what) {
	for (var i=0; i<document.images.length; i++) {
		with (document.images[i]) {
			if (name=="curr") {
				src="gif/c_"+what+".gif";
				alt=what;
			}
		}
	}
};

function setCellBG(tag,what) {
	if (version=="ECMA") {
		document.getElementById(tag).style.background=what;
	}
	else if (version=="Nav4") { /* TO TEST! */
		document.tag.document.bgColor=what;
	}
	else if (version=="IE5") {
		document.all[tag].style.backgroundColor = what;
	}
};

function FlagTag(tag) {
	if (tagged > "") {
		setCellBG(tagged,visitedColor);
	}
	tag="z"+tag; /* broken IE5 restrictions - NB in HTML <TD id="zthing"><A NAME="thing">...! */
	setCellBG(tag,highlightColor);
	tagged=tag;
};

function FlagTarget() {
	tag=window.location.hash.slice(1);
	if (tag>"") {
		FlagTag(tag);
	}
};

function advance(thing) {
};

function retreat(thing) {
};

function a(thing) {
	advance(thing);
};

function r(thing) {
	retreat(thing);
};

function trimStr(str) {
	if (str!=null) {
		while (str.charAt(0)==" " || str.charCodeAt(0)==13 || str.charCodeAt(0)==10) {
			str=str.slice(1);
		}
		while (str.charAt(str.length-1)==" " || str.charCodeAt(str.length-1)==13 || str.charCodeAt(str.length-1)==10) {
			str=str.slice(0,str.length-1);
		}
	}
	return str;
};

function setBG(thisfield,what) {
	if (version=="Nav4") {
		if (document.thisForm.elements[thisfield].background) {
			document.thisForm.elements[thisfield].background=what; /*does nowt? */
		}
	}
	else {
		if (version!="veryplain") {
			if (document.thisForm.elements[thisfield].style) {
				document.thisForm.elements[thisfield].style.background=what;
			}
		}
	}
};

function setBunchBG(thisbunch,what) {
	if (version=="ECMA" || version=="IE5") {
		for (var i = 0; i < document.thisForm.elements[thisbunch].length; i++) {
			document.thisForm.elements[thisbunch][i].style.backgroundColor=what;
		}
	}
};

function unMarkField(fld) {
	setBG(fld,norm);
};

function nonField(thisfld,len){
	setBG(thisfld,nonf);
	with(document.thisForm.elements[thisfld]){
		disabled=true;
		if (version=="ECMA" || version=="IE5") {
			with (style) {border="0px"; fontFamily="sans-serif"}
		}
		else if (version=="Nav4") {
			border="0px"
		}
	}
};

function addMsg(fld,msg) {
	if (fld!=null) {
		setBG(fld,errr);
	}
	if (msgCount<=maxMsg) {
		msgs[msgCount]="\n<LI>"+msg+"</LI>"
	}
	msgCount++;
};

function initCheck(what) {
	checkStep=0; 
	document.thisForm.elements["z_diagnose"].value= 
		"ver="+version+"/"+subversion+
		": '"+navigator.appName+
		"|"+navigator.appVersion+
		"|"+navigator.userAgent+"'"; 
	if (getValue("z_validate").charAt(0) != "*") {
		putValue("z_validate","*");
	}
	putValue("z_errorlst","?");
	formOK=true;
	showNumErr=infinite;
	showDatErr=infinite;
	showPhoErr=infinite;
	msgCount=0;
	today=new Date();
	thisCent=Math.floor(today.getFullYear()/99.999)*100;
	if ((document.state.abortCheck.value=="Y")
	 || doPopUp
	 || version=="veryplain"
	 || subversion=="oldOpera") { /* collect *all* errors */
		maxMsg=70;
	}
	else if (Wheight<=360) {
		maxMsg=3
	}
	else if (Wheight<=480) {
		maxMsg=4
	}
	else if (Wheight<=600) {
		maxMsg=6 
	}
	else {
		maxMsg=8
	}
	msgs=new Array(maxMsg+1);
	for (var i=0; i<=maxMsg; i++) {
		msgs[i]="<LI>Spurious message, line "+i+"</LI>";
	}
	errorMsg="<UL>";
	errorTop="<TR><TD class=\"caption\" align=\"right\"><IMG SRC=\"gif/invisibl.gif\" width=190 height=1 alt=\"\"><BR>[";
	if (subversion=="oldOpera") {
		errorTop+="<A HREF=javascript:closeMsg()>close this</A>"
	}
	else {
		errorTop+="If it's in the way, <A HREF=javascript:closeMsg()>hide this</A>"
	}
	errorTop+="]</TD></TR>\n<TD><P><SPAN class=msgHed>Ooops...</SPAN>\nWe don't seem to have the information in the form we need "+what+". Please clarify:</P>\n";
};

function getValue(thisfld) { /* call on SELECT, TEXT, TEXTAREA or *single* CHECKBOX */
var val="_NONE";
	showProgress();
	with (document.thisForm.elements[thisfld]) {
		if (type.substr(0,6)=="select") {
			for (var i = 0; i < length; i++) {
				with (options[i]) {
					if (selected && value!=null && value>"") {
						if (val=="_NONE") {
							val=value
						} 
						else {
							val=val+", "+value;
						} 
					}
				}
			}
		}
		else if (type=="text" || type=="textarea"  || type=="password" || type=="hidden") {
			value=trimStr(value);
			if (value != null && value.length>0) {
				val=value
			}
		}
		else if (type=="checkbox" || type=="radio") { /*yes, you can have a single radio button */
			if (checked) {
				val=value;
			}
		}
	}
	return val;
};

function putValue(thisfld,val,flag) {
var done=false;
	with (document.thisForm.elements[thisfld]) {
		if (type.substr(0,6)=="select") {
			for (var i = 0; i < length; i++) {
				with (options[i]) {
					if (value!=null && value==val) {
						selected=true;
						done=true;
						if (flag) {setBG(thisfld,stuf)}
					}
				}
			}
		}
		else if (type=="text" || type=="textarea" || type=="hidden") {
			value=val;
			done=true;
			if (flag && type!="hidden") {
				if (document.thisForm.elements[thisfld].readOnly) {
					if (val=="?") {
						setBG(thisfld,unkn)
					}
					else {
						setBG(thisfld,resl)
					}
				}
				else if (document.thisForm.elements[thisfld].disabled) {
					setBG(thisfld,unkn)
				}
				else {
					setBG(thisfld,stuf)
				}
			}
		}
		else if (type=="checkbox" || type=="radio") { /*yes, you can have a single radio button! */
			if (val==value) {
				checked=true;
				if (flag) {setBunchBG(thisfld,stuf)}
				done=true;
			}
		}
	}
	return done;
};

function whichSelected(thisbunch) { /* call on RADIO or *multiple* CHECKBOX */
var val="_NONE";
	showProgress();
	for (var i = 0; i < document.thisForm.elements[thisbunch].length; i++) {
		with (document.thisForm.elements[thisbunch][i]) {
			if (checked && value!=null) {
				if (val=="_NONE") {
					val=value
				} 
				else {
					val=val+", "+value
				}
			}
		}
	}
	return val;
};

function putSelect(thisbunch,val,flag) { /* Oh bugger. Only works on Radio */
var done=false;
	for (var i = 0; i < document.thisForm.elements[thisbunch].length; i++) {
		with (document.thisForm.elements[thisbunch][i]) {
			if (value!=null && value==val) {
				checked=true;
				done=true;
			}
		}
	}
	if (flag) {setBunchBG(thisbunch,stuf)} /* why fails even when errr works? */
	return done;
};

function putSelect2(thisbunch,val,flag) { /* This one works on Select */
var done=false;
	for (var i = 0; i < document.thisForm.elements[thisbunch].length; i++) {
		with (document.thisForm.elements[thisbunch][i]) {
			if (value!=null && value==val) {
				selected=true;
				done=true;
			}
		}
	}
	if (flag && done) {setBunchBG(thisbunch,stuf)}
	return done;
};

function checkFilled(thisfld,msg,min) {
var fieldOK=true;
//	alert('Please click OK - geek testing going on\nfield='+thisfld+'\nmin='+min);
	setBG(thisfld,norm);
	test=getValue(thisfld);
	if (min) { // added 2004-04-16
		if (test.length < min || test=="_NONE") {
			fieldOK=false;
			addMsg(thisfld,msg+" - at least "+min+" characters required");
		}
	}
	else if (test=="_NONE") {
		fieldOK=false;
		addMsg(thisfld,msg);
	}
	formOK=formOK && fieldOK;
	return fieldOK;
};

function showNum(num,decp){
var i;var digl=20;var digi=new Array(digl);var negn=false;var trail2="500000000";var oddigi="13579";
	nstr=num.toString();
	if(isNaN(num)){
		outp="NOT_A_NUM"
	}
	else if (nstr.indexOf("e")>=0){
		outp="OUT_OF_RANGE"
	}
	else{
		if(decp>6){decp=6}
		if(nstr.length>12){nstr=nstr.substr(0,12)}dpos=nstr.indexOf(".");
		if(dpos==-1&&isNaN(decp)){
			outp=nstr
		}
		else{
			if(isNaN(decp)){
				decp=2
			}
			if(dpos==-1){
				dpos=nstr.length
			}
			lasd=dpos+decp;
			nexd=lasd+1;
			digi[0]=0;
			for(i=0;i<dpos&&i<digl;i++){digi[i+1]=nstr.substr(i,1)}
			for(i=(dpos+1);(i<nstr.length&&i<digl);i++){digi[i]=nstr.substr(i,1)}
			for(i;i<=nexd&&i<digl;i++){digi[i]=0}
			negn=(digi[1]=="-");
			if(negn){
				digi[1]=0
			}
			trail1=nstr.substring(nexd,nstr.length);
			if((digi[nexd]=="5")&&(trail1==trail2.substr(0,trail1.length))){
				if(oddigi.indexOf(digi[lasd])>-1){
					digi[lasd]++
				}
			}
			else{
				if(digi[nexd]>=5){
					digi[lasd]++
				}
			}
			for(i=lasd;i>0;i--){
				if(digi[i]==10){
					digi[i]=0;
					digi[i-1]++
				}
			}
			if(negn){
				outp="-"
			}
			else{
				outp=""
			}
			i=0;
			while(digi[i]==0&&i<dpos){
				i++
			}
			while(i<=lasd){
				outp+=digi[i];
				if(i==dpos&&decp>0){
					outp+="."
				}
				i++
			}
		}
	}
	return outp
};

function addNote(whatErr,msg,refr) {
	if (whatErr==infinite) {
		msg.val+=" (see note <B>"+refr+"</B>)";
		if (msgCount<(maxMsg-1)) {maxMsg--}
	}
	if (whatErr>msgCount) {
		whatErr=msgCount
	}
	return whatErr;
};

function checkAmount(thisfld,mandatory,decp,msg) { /* demands +ve numbers! */
var fieldOK=true;
var i=0;
var zeroMsg=". If it is 0 (zero), please say so";
var num=NaN;
	errorM.val="";
	if (msg!="_NO_MSG") {
		setBG(thisfld,norm)
	}
	st1=getValue(thisfld); /*n.b. trims it */
	st2="";
	if (st1 == "_NONE") {
		if (mandatory && msg!="_NO_MSG") {
			addMsg(thisfld,"the "+msg+zeroMsg);
			fieldOK=false;
		}
	}
	else {
		while (fieldOK && i<st1.length) {
			ch=st1.charAt(i);
			fieldOK = ((ch>="0" && ch<="9") || ch==".");
 			i++;
		}
		if (fieldOK) {
			num=parseFloat(st1);
			if (num<0) {
				num=NaN;
			} 
			st2=showNum(parseFloat(st1),decp);
			fieldOK=(parseFloat(st2) == num); /* Now... should it round & alert? */
		}
		if (fieldOK) {
			document.thisForm.elements[thisfld].value=st2
		}
		else if (msg!="_NO_MSG") {
			errorM.val="the "+msg+" should be a simple number";
			showNumErr=addNote(showNumErr,errorM,"N");
			if (mandatory) {
				errorM.val+=zeroMsg;
			}
			addMsg(thisfld,errorM.val);
		}
	}
	formOK=formOK && fieldOK;
	return num; /* NaN if error */
}; /*checkAmount */

function tidyDigits(str,pass,accept,delim) {
var st2="";
var ch="";
var stOK=true;
	for (var i=0; i<str.length; i++) {
		ch=str.charAt(i);
		if (pass.indexOf(ch)>-1) {
			st2+=ch;
		}
		else if (accept.indexOf(ch)>-1) {
			if (st2.length>0 && st2.charAt(st2.length-1)!=delim) {/*? Behaviour for delim IN pass... */
				st2+=delim;
			}
		}
		else stOK=false; 
	}
	if (stOK) {return st2} else {return "_ERROR"}
};


function checkPhoneN(thisfld,mandatory,msg) {
var fieldOK=false;
var st2="";
	function flagPhoErr() {
		showPhoErr=addNote(showPhoErr,errorM,"P");
		addMsg(thisfld,errorM.val)
	};

	errorM.val=msg;
	setBG(thisfld,norm);
	st1=getValue(thisfld); /*n.b. trims it */
	if (st1=="_NONE") {
		if (mandatory) {addMsg(thisfld,msg)}
		else {fieldOK=true}
	}
	else {
		st2=tidyDigits(st1,"+0123456789()"," /-.,:;"," "); 
		if (st2=="_ERROR") {
			flagPhoErr()
		}
		else if (st2.charAt(0)=="0") {
			if (st2.length>=9) {fieldOK=true} else {flagPhoErr()}
		}
		else if (st2.charAt(0)=="+") {
			if (st2.length>=4) {fieldOK=true} else {flagPhoErr()}
		}
		else {
			flagPhoErr()
		}
	}
	formOK=formOK && fieldOK;
	if (fieldOK) {
		document.thisForm.elements[thisfld].value=st2
	}
	return fieldOK;
};

function checkPoCode(pocofld,counfld,mandatory,msg) {
	setBG(pocofld,norm);
	fieldOK=!mandatory;
	poco=getValue(pocofld).toUpperCase();
	coun=whichSelected(counfld);
	if (poco=="_NONE" && mandatory) {
		if (coun=="IE") {
			fieldOK=true
		}
		else {
			addMsg(pocofld,msg)
		}
	}
	else if (coun=="UK") {
		if (poco.search(postPat)==-1) {
			addMsg(pocofld,"what you entered for "+msg+" is not a UK postcode")
			fieldOK=false;
		}
		else {
			putValue(pocofld,poco,false);
			fieldOK=true;
		}
	}
	else if (coun=="IE") {
		if ((poco.search("[^0-9]")>=0) || (poco.length>2)) {
			addMsg(pocofld,"what you entered for "+msg+" is not an Irish postcode")
			fieldOK=false;
		}
	}
	formOK=formOK && fieldOK;
}

function padDate(dat) {
var da2,da3;
	if (dat.charAt(1)==dD) {
		da2="0"+dat;
	}
	else {
		da2=dat;
	}
	if (da2.charAt(4)==dD) {
		da3=da2.substr(0,3)+"0"+da2.substr(3);
	}
	else {
		da3=da2;
	}
	return da3;
};

function showDate(thatDate) {
var mon;
	if (thatDate==noDate) {
		return "NOT_A_DATE"
	}
	else {
		mon=thatDate.getMonth()+1;
		return padDate(thatDate.getDate().toString()+dD+mon.toString()+dD+thatDate.getFullYear().toString());
	}
};

function makeDate(st1,thisfld,report,msg) {
var st2="";
arr = new Array(3);
var da=0; /*indexes into split date array */
var mo=1;
var yr=2;
var testDate = noDate;

	st2=tidyDigits(st1,"0123456789"," :_/\\-.,;",dD);
	if (st2=="_ERROR") {
		if (report) {
			addMsg(thisfld,msg+" should be in the unambiguous form <I>dd/mm/yyyy</I>, e.g. "+showDate(today));
		}
	}
	else { /* Proper date checking! */
		arr=st2.split(dD);
/****
		x1=parseInt(arr[yr],10)+thisCent;
		x2=x1-today.getFullYear();
		if (Math.abs(x2)<11) {	// decade-guessing, this century  
			arr[yr]=x1.toString()
		}
		else if (Math.abs(x2-100)<11) { // end of last century 
			x1=x1-100;
			arr[yr]=x1.toString()
		}
		else if (Math.abs(x2+100)<11) { // beginning of next century 
			x1=x1+100;
			arr[yr]=x1.toString()
		}
****/
		testDate=new Date(parseInt(arr[yr],10),parseInt(arr[mo]-1,10),parseInt(arr[da],10)); 
		if (parseInt(arr[yr],10)   != testDate.getFullYear()
		 || parseInt(arr[mo]-1,10) != testDate.getMonth()
		 || parseInt(arr[da],10)   != testDate.getDate()) { 
			if (report) {
				addMsg(thisfld,msg+" - not a valid date");
			}
			testDate=noDate;
		}
	}
//	window.alert(testDate+" --- "+msg);
	return testDate;
}; /* makeDate */

function fetchDate(thisfld) {
	return makeDate(getValue(thisfld),thisfld,false,"");
};

function checkDate(thisfld,mandatory,msg) { 
var fieldOK=true;
var st1="";
var testDate = noDate;
	setBG(thisfld,norm);
	st1=getValue(thisfld); /*n.b. trims it */
	if (st1=="_NONE") {
		if (mandatory) {
			addMsg(thisfld,msg);
			fieldOK=false;
		}
	}
	else {
		testDate=makeDate(st1,thisfld,true,msg);
		if (testDate==noDate) {
			fieldOK=!mandatory;
		}
		else {
			document.thisForm.elements[thisfld].value=showDate(testDate);
			if (today.getUTCFullYear()-testDate.getUTCFullYear()>methuselah
			&& document.state.ignoreDate.value!="Y") {
				fieldOK=false;
				errorM.val="you give "+showDate(testDate)+" for "+msg+". Don't believe you...";
				showDatErr=addNote(showDatErr,errorM,"D");
				addMsg(thisfld,errorM.val);
			}
		}
	}
	formOK=formOK && fieldOK;
	return testDate;
};

function showWeekday (thisfield,thatfield) {
	thisdate=fetchDate(thatfield);
	if (thisdate==noDate) {
		putValue(thisfield,"Not a day!",false)
	} 
	else {
		putValue(thisfield,weekday[thisdate.getDay()],false)
	}
};

function checkSequen(fld1,msg1,fld2,msg2) { /* both fields should be passed & cleaned up... */
var fieldOK=true;
var da1=new Date();
var da2=new Date();
	da1=fetchDate(fld1,false,false,"");
	da2=fetchDate(fld2,false,false,"");
	if (da1==noDate || da2==noDate) {
		/* exit silently */
	}
	else {
		if (da1<da2) { /* fld1 is later than fld2, and shouldn't be */
			fieldOK=false;
			addMsg(fld1,msg1+" <B>before</B> "+msg2);		
		}
		formOK=formOK && fieldOK;
	}	
	return fieldOK;
};

function checkFuture(thisfld,strict,msg) { /* both fields should be passed & cleaned up... */
var fieldOK=true;
var dat;
	errorM.val="you say you"+msg;
	dat=fetchDate(thisfld,false,false,"");
	if (dat==noDate) {
		/* exit silently */
	}
	else {
		if (dat>today && (document.state.ignoreDate.value!="Y")) {	/* thisfld is later than today...  */
			if (strict || (document.state.postDated.value!="Y")) {	/*...and shouldn't be */
				fieldOK=false;
				showDatErr=addNote(showDatErr,errorM,"D");
				if (!strict) {errorM.val+=". If that really is the case, <A HREF=javascript:postDate()>click here</A>"}
				addMsg(thisfld,errorM.val)
			}
		}
		formOK=formOK && fieldOK;
	}	
	return fieldOK;
};

function checkEmail(fld) {
var fieldOK=true;
	if (checkFilled(fld,'your email address')) { /*n.b. trims it */
		with (document.thisForm.elements[fld]) {
			if (value.indexOf("@")<0 
			 || value.lastIndexOf(".")<value.indexOf("@") 
			 || value.lastIndexOf(".")>=value.length-1
			 || value.indexOf(",")>=0
			 || value.indexOf(" ")>=0) {
				addMsg(fld,"A <EM>valid</EM> internet email address. It <EM>must</EM> contain one '@' character, at least one dot after that, and <EM>no</EM> spaces or commas: e.g. <CODE>jo@home.org.uk</CODE>");
				fieldOK=false;
			}
		}
	}
	formOK=formOK && fieldOK;
	return fieldOK;
};

function checkWhethr(thisbunch,msg) {
var fieldOK=true;
	setBunchBG(thisbunch,"transparent");
	if (whichSelected(thisbunch)=="_NONE") {
		fieldOK=false;
		setBunchBG(thisbunch,errr);
		addMsg(null,msg);
	}
	formOK=formOK && fieldOK;
	return fieldOK;
};

function checkImplic(fld1,msg1,val1,fld2,msg2) { /* one-of-multiple AND no-value */
var fieldOK=true;
	if ((whichSelected(fld1).indexOf(val1)>-1) && (getValue(fld2) == "_NONE")) {
		fieldOK=false;
		addMsg(fld2,"you said "+msg1+" <B>"+val1+"</B>, but not "+msg2);
	}
	formOK=formOK && fieldOK;
	return fieldOK;
};

function checkImpli2(fld1,msg1,val1,fld2,msg2) { /* given-value AND no-value */
var fieldOK=true;
	if ((getValue(fld1)==val1) && (getValue(fld2) == "_NONE")) {
		fieldOK=false;
		if (val1=="_NONE") {
			addMsg(fld2,"you have not said "+msg1+" <B>nor</B> "+msg2);
		}
		else {
			addMsg(fld2,"you said "+msg1+" <B>"+val1+"</B>, but not "+msg2);
		}
	}
	formOK=formOK && fieldOK;
	return fieldOK;
};

function checkImpli3(fld1,msg1,val1,fld2,msg2) { /* NOT given-value AND no-value */
var fieldOK=true;
	if ((getValue(fld1)!= val1) && (getValue(fld1)!= "_NONE") && (getValue(fld2) == "_NONE")) {
		fieldOK=false;
		addMsg(fld2,"you said "+msg1+", but not "+msg2);
		formOK=formOK && fieldOK;
	}
	return fieldOK;
};

function checkImpli4(fld1,msg1,fld2,msg2) { /* Any-of-multiple AND none-of-multiple */
var fieldOK=true;
	thing=whichSelected(fld1);
	if (thing!="_NONE") {
		fieldOK=checkWhethr(fld2,"you say "+msg1+thing+", <EM>but not</EM> "+msg2)
	}
	formOK=formOK && fieldOK;
	return fieldOK
};

function checkContra(fld1,msg1,val1,fld2,msg2) { /* one-of-multiple AND anything */
var fieldOK=true;
	if ((whichSelected(fld1).indexOf(val1)>-1) && (getValue(fld2) != "_NONE")) {
		fieldOK=false;
		addMsg(fld2,"you said "+msg1+" <B>"+val1+"</B>, <I>but also</I> "+msg2);
	}
	formOK=formOK && fieldOK;
	return fieldOK;
};

function checkContr2(fld1,msg1,val1,fld2,val2,msg2) { /* one-of-multiple AND given-value */
var fieldOK=true;
	if ((whichSelected(fld1).indexOf(val1)>-1) && (getValue(fld2).indexOf(val2) >-1)) {
		fieldOK=false;
		addMsg(fld2,"you said "+msg1+" <B>"+val1+"</B>, <I>but also</I> that it was <B>"+val2+"</B>: "+msg2);
	}
	formOK=formOK && fieldOK;
	return fieldOK;
};

function checkContr3(fld1,msg1,val1,fld2,msg2,fld3) { /* given-value AND anything bar 0; where else */
var fieldOK=true;
	if ((getValue(fld1).indexOf(val1)>-1) 
	&& (getValue(fld2)!="_NONE") 
	&& (getValue(fld2)!="0")
	&& (getValue(fld2)!="0.00")) {
		fieldOK=false;
		addMsg(fld2,"you said "+msg1+" <B>"+val1+"</B>, <I>but also</I> that "+msg2);
		if (fld3>"") {
			setBG(fld3,errr);
		}
	}
	formOK=formOK && fieldOK;
	return fieldOK;
};

function checkout(mailing) {
var more_msgs=0;
var lim=0; 

	function showNote(what,ntxt) {
		if (what<maxMsg || (what==maxMsg && more_msgs==0)) {
			errorMsg+="\n<P class=note><B>["+ntxt+".</P>"
		}
	};
	msgCount--; /*addMsg always increments; put it back */
	if (formOK) {
		document.thisForm.z_validate.value+="Passed by Mike's program ";
		document.thisForm.z_errorlst.value="*Everything seems consistent";
		closeWait(false);
		showSend(mailing,"");
	}
	else {
		lim=Math.min(msgCount,maxMsg-1);
		for (var i=0; i<=lim; i++) {
			errorMsg+=msgs[i];
		}
		if (msgCount==maxMsg) {
			errorMsg+=msgs[msgCount];
		} 
		else if (msgCount>maxMsg) { /* msg[maxMsg]="more" */
			more_msgs=msgCount-maxMsg+1;
			errorMsg+="\n<LI><EM>"+more_msgs.toString()+" more messages</EM>; deal with the above to see more.</LI>";
		}
		errorMsg=errorMsg+"\n</UL>";
		showNote(showDatErr,"D]</B> Your computer believes today is "+weekday[today.getDay()]+", "+showDate(today)+". If it is wrong, <A HREF=javascript:ignoreDate()>click here</A> and we will stop checking dates - so take care");
		showNote(showNumErr,"N]</B> Numbers should have no currency sign and no spaces, commas or minus signs; only whole pennies or cents please");
		showNote(showPhoErr,"P]</B> Phone numbers should start with <B>0</B> (area code) and have at least 9 digits, or with a <B>+</B> (international prefix); after that just digits &amp; spaces, please.");
		if (document.state.abortCheck.value=="Y" || version=="veryplain") {
			document.thisForm.z_validate.value+="\nERRORS FOUND: see below\n";
			document.thisForm.z_errorlst.value="The system asked you to clarify:\n"+errorMsg+"\n";
			formOK=true;	/* it's a lie - to send email... */
			closeWait(false);
			showSend(mailing,"...with a list of queries</P><P>");
		}
		else {
			closeWait(false);
			showMsg(MsgHeader+errorTop+errorMsg+instruct+MsgFooter);
			errorsShewn=true;
			if (msgCount==0) {
				window.defaultStatus="There is one thing to clarify..."
			}
			else {
				window.defaultStatus="There are "+showNum(msgCount+1,0)+" things to clarify..."
			}
			window.status="";
		}
	}
	return formOK;
}; /*checkout(mailing) */

function showDiv(content,Thing) {
	if (doPopUp) {
		messageWin=popUp("message",200,ErrHeader+content+ErrFooter)
	}
	else if (version=="ECMA") {
		with (document.getElementById(Thing)) {
			style.visibility="visible";
			style.display="block";
			style.top = mMargin + pageYOffset;
			if (content!="_STET") {innerHTML = content}
		}
		document.getElementById("nav").style.visibility="hidden";
	}
	else if (version=="Nav4") {
		with (document.Thing) {
			visibility="show";
			display="block";
			top = mMargin + pageYOffset;
			if (content!="_STET") {
				document.open();
				document.clear();
				document.write(content);
				document.close()
			}
		}
		document.nav.visibility="hide";
	}
	else if (version=="IE5") {
		with (document.all[Thing]) {
			style.visibility="visible";
			style.display="block";
			if (content!="_STET") {innerHTML = content}
			if (!isMac) {style.top = document.all.nav.style.top}; // ELSE show under submit button
		}
		document.all.nav.style.visibility="hidden";
	}
};

function showMsg(content) {
	showDiv(content,"MsgBox");
}

function closeDiv(Thing) {
	if (doPopUp) {
		messageWin=popDown(messageWin);
	}
	else if (version=="ECMA") {
		with (document.getElementById(Thing).style) {
			visibility="hidden";
			display="none";
		}
		document.getElementById("nav").style.visibility="visible";
	}
	else if (version=="Nav4") {
		with (document.Thing) {
			visibility="hide";
			display="none";
			height=1;
		}
		document.nav.visibility="show";
	}
	else if (version=="IE5") {
		with (document.all[Thing].style) {
			visibility="hidden";
			display="none";
		}
		document.all.nav.style.visibility="visible";
	}
	GetWindowSize();  	/*also sets menuX & height */
	MenuRefresh();
	window.defaultStatus="*";
};

function closeMsg() {
	closeDiv("MsgBox");
}

var barsHeight=15;
var barsWidth=25; /* another empirically set thingy 25/05/2003 */

function popUp(target,width,content) {
var timerID1,timerID2; 
var dfltHeight=400; /*100 when sizePopUp works...*/
var whatWin=null;
/* Opera 7 complains about reading protected variable... probably in here */
	if (version=="veryplain" || version=="Nav4") {dfltHeight=400}
	width=width+barsWidth;
	if (version=="Nav4") {
		window.alert("Sorry...\n Haven't worked out how to make Netscape 4 display the details properly.")
	}
	else {
		whatWin=window.open("about:blank",target,"resizable=yes, width="+width+", height="+dfltHeight+", screenX=10, screenY=2, scrollbars=yes, location=no");
		if (whatWin!=null) {
			whatWin.document.open("text/HTML","replace");
			whatWin.document.write("<HTML><HEAD><SCRIPT>var defaultWidth="+width+"</SCRIPT>"+content);
			whatWin.document.close();
		}
		if (version=="ECMA" || version=="IE5") {
			timerID2=setTimeout("sizePopUp()",500)
		} 
	}
	return whatWin;
};

function popDown(whatWin) {
	if (whatWin!=null && !whatWin.closed) {
 		whatWin.close()
	}
	return null;
};

function sizeNum(str) {
	return parseInt(str.substr(0,str.indexOf("px")))
};

function sizePopUp() {};

function showProgress() {
	if (checkStep>0) {window.status="Processing: step "+checkStep+"; queries "+Math.max(0,msgCount)}
	checkStep++;
};

function showSend(mailing,xtra) {
	if (mailing) {
		showMsg(MsgHeader+"<TR><TD width=\"100%\"><H1>sending...</H1><P>"+xtra+"It's not sleeping, it's resting its eyes! When the server's busy this can take a minute.</P>"+MsgFooter);
		sendShewn=true;
	}
};

function showWait() {
	closeMsg();
	resultsWin=popDown(resultsWin);
	if (!sendShewn && document.state.abortCheck.value!="Y") {
		if (doPopUp) {
			messageWin=popDown(messageWin)
		}
		showMsg(MsgHeader+"<TR><TD width=\"100%\"><H1>pondering...</H1><P>When you click <SPAN class=butt>["+OKbtn+"]</SPAN>, the system checks the information you entered to be sure it's complete.</P>"+MsgFooter);
			waitShewn=true;
	}
	errorsShewn=false;
};

function closeWait(frombutton) {
	if (waitShewn && !errorsShewn && !sendShewn) {
		closeMsg();
		waitShewn=false;
		if (frombutton) {
			showMsg(MsgHeader+"<TR><TD width=\"100%\"><H1>not sending...</H1><P>Your computer thinks you changed your mind about clicking <SPAN class=butt>["+OKbtn+"]</SPAN>. <SPAN class=JSnote>[<A HREF=javascript:closeMsg()>hide this</A>]</SPAN></P>"+MsgFooter);
		}
	}	
};

/* control functions called from floating DIV. See also errorHeader for popUp  */

function ignoreDate() {
	document.state.ignoreDate.value="Y";
	document.thisForm.z_validate.value+="Member's computer clock is wrong - CHECK DATES\n";
	closeMsg();
};

function postDate() {
	document.state.postDated.value="Y";
	document.thisForm.z_validate.value+="Member says payment due before delivery\n";
	closeMsg();
};

function scriptError() {
	document.state.abortCheck.value="Y";
	document.thisForm.z_validate.value+="Member reports error in error message\n";
	closeMsg();
};

function addUp(target) {
var total=0;
	for (var i=1; i<arguments.length; i++) {
		temp=checkAmount(arguments[i],false,2,"_NO_MSG"); 
		if (!isNaN(temp)) {
			total+=parseFloat(temp);
		}
	}
	putValue(target,showNum(total,2),true);
	return total;
};

function getQuery(thisq) {
var thisval="_NONE";
var thisend=0;
	thisq=thisq+"=";
	thistmp=window.location.search;
	if (thistmp.indexOf(thisq)>-1) {
		thisval=thistmp.slice(thistmp.indexOf(thisq)+thisq.length);
		thisend=thisval.indexOf("&"); //deal with ";" too?
		if (thisend==-1) {thisend=thisval.length};
		thisval=trimStr(unescape(thisval.slice(0,thisend))); 
	}
	return thisval;
};

function initValue(whatq,whatf) {
	foo=getQuery(whatq);
	if (foo!='_NONE' && foo!='') {putValue(whatf,foo,true)};
	
}

function initSelect(whatq,whatf) {
	foo=getQuery(whatq);
	if (foo!='_NONE') {
		foo2=foo.split(', ');
		for (var i=foo2.length-1; i>-1; i--) {
			putSelect(whatf,foo2[i],true);
		}
	}
}

function initSelect2(whatq,whatf) { /* This one works on Select - does multiple */
	foo=getQuery(whatq);
	if (foo!='_NONE') {
		foo2=foo.split(', ');
		for (var i=foo2.length-1; i>-1; i--) {
			putSelect2(whatf,foo2[i],true);
		}
	}
}

/* init() not called before this: used by {maillist}/!subscribe.html */

function fixLinkup(skill) {
	if (document.getElementById("linkLinkup")) {
		with (document.getElementById("linkLinkup")) {
			href="http://www.londonfreelance.org/linkup.php";
			href+="?email="+document.info.email.value;
			href+="&name="+document.info.fullname.value;
			if (skill!="_NONE") {
				href+="&skill="+skill
			}
		}
	}
}

//end of main forms script: see also lpcd.js + embedded scripts in headers...