/* author: Don Kent, eShopHost Ltd */
/* Copyright (C) 2003, eShopHost Ltd, all rights reserved. */

/* HISTORY */
/* 1.0, 24/09/03 - Creation date:  */
/* 1.1, 06/10/03 - added 4. isNumeric function */
/* 1.2, 08/11/03 - added 5. emProtect function */
/* 1.3, 06/04/04 - added to 1. - email address valid? */
/* 1.4, 18/08/04 - added 6. submitEnquiry function */
/* 1.5, 03/11/04 - modified 6. to use currentStyle property */
/* 1.6, 14/12/04, Don Kent - added 7. DisplayMeta function. Add to 5. new mode: hidden. Add to 6. .check property */
/* 1.7, 15/12/04, Don Kent - added 8. ProcessTextLinks function */
/* 1.8, 16/12/04, Don Kent - added 9. ProcessImageLinks function */
/* 1.9, 10/01/05, Don Kent - changed 8 & 9 to make all tags 2 digits complying with selfupdate.pl */
/* 1.10 18/02/05 Don Kent - 9 removed any tags in webmaster's input; 8. ditto but trailing tag (such as <br>) */
/* 1.11 25/04/05 Don Kent - 1.2 for email - Regex changed to match mail.pl's check; check for 'phone' added. 6. Added PhoneResponse, Phone, Copy standard fields + logic */
/* 1.12 07/05/05 8,9. Changed TextArea from attributes to class for width & height */
/* 1.13 18/05/05 10 added */
/* 1.14 19/05/05 10 debug for ordinals */
/* 1.15 06/07/05 11 added & used through eshophj1.js */
/* 1.16 12/07/05 12 added & used in this & IndexToItem.js */

/* CONTENTS of eshophj1.js (General utility functions for eShopHost Web Solutions: */
	/* Public functions */
/* 1. Check (FieldId, CheckType) - Validates field is of specified type - true or false */
/* 2. FieldValue (FieldId) - returns the value of the field */
/* 3. MakeHiddenInput (FieldName, Value) - Returns HTML for hidden input field */
/* 4. isNumeric (TestNumber) - Parameter is STRING - returns true if only numerics */
/* 5. emProtect (several) - creates HTML for email address - hidden from robots */
/* 6. submitEnquiry (formObj) - enables any form fields to be formatted into an email via mail.pl */
/* 7. DisplayMeta (Option) - displays meta tag information as elements exist */
/* 8. ProcessTextLinks (Domain) - Takes webmaster's Link text and converts to HTML */
/* 9. ProcessImageLinks () - Takes webmaster's title words and adds them to the HTML */
/* 10 ShowDate(Format) - Displays current day & date. Not updated. */
/* 11 getObj(ObjId) - returns object reference given its id */
/* 12 getStyleProperty(obj,Property) - use instead of .currentStyle */

	/* Internal functions */
/* A. NumToText (Num, Length) - returns string of Num, with leading zeroes to Length */
/* B. ExtractText (Block, Start, End) - returns the characters between the strings Start & End from object Block */
/* C. ReplaceText (Block, Start, End, Replacement) - replaces the characters between the strings Start & End from object Block */

	/* Global Variables */
var LinksImageStart = 91; // PerlTag for Image Links - start
var LinksImageEnd = 93;
var LinksTextStart = 95; // PerlTag for Text Links - start
var LinksTextEnd = 98;

/* Public Functions */
function Check (FieldId, CheckType) { // 1.
	/*  Validates field is of specified type (numeric, email, phone) - true or false*/
	// 1.1. Retrieve Field Value
	var eMessage = "Please refresh the page and re-attempt. If no success, please do tell us! - see the 'contact us' page - and tell us which product you were trying to buy, which page you were on or what you were trying to do. Thanks!";
	var Field = getObj (FieldId);
	if (Field == undefined) {
		alert ("There is an error on the web page. Function call: 'Check(" + FieldId + ")' has an undefined element or your browser does not support the industry standard DOM. " + eMessage);
		return false;
	}
	var Value = Field.value;
	var Truth = false;
	var RegExTrue; // Regex matches if Check should pass (.search is not equal to -1)
	var RegExFalse; // Regex does NOT match if Check should pass (.search returns -1)

	// 1.2. Set Regex
	switch (CheckType) {
		case "numeric": {
			RegExFalse = /\D/;
			break;
		}
		case "email": {
			RegExTrue = /^[\w.-]+\@[\w-]+\.[\w.-]+$/; // e.g. a1@b.c or d.2-e@f_g.h.i
			break;
		}
		case "phone": {
			RegExTrue = /^\s*\+?[\d()\s]+$/; // e.g. +44 (0)1793 740303
			break;
		}
		default: {
			alert ("There is a problem with the web page. The requested check for an input field has not been understood. " + eMessage);
			return false;
		}
	}

	// 1.3. Test value
	if ( (RegExTrue != undefined) && (Value.search(RegExTrue) != -1 ) ) {
		Truth = true;
	}
	if ( (RegExFalse != undefined) && (Value.search(RegExFalse) == -1 ) ) {
		Truth = true;
	}

	// 1.4. Return
	return Truth;

}

function FieldValue (FieldId) { // 2.
	/* Returns the value of the field */
	// 2.1. Get the Element's Object
	var FieldObject = getObj (FieldId);
	if (FieldObject == undefined) {
		alert ("There is an error on the web page. Function call: 'FieldValue(" + FieldId + ")' has undefined element. Please refresh the page and re-attempt. If no success, please do tell us! - see the 'contact us' page - and tell us which product you were trying to buy. Thanks!");
		return undefined;
	}

	// 2.2 Return value of object
	return FieldObject.value;
}

function MakeHiddenInput (FieldName, Value) { // 3.
	/* Returns HTML for hidden input field */
	var HiddenInput = '<input type="hidden" name="' + FieldName + '" value="' + Value + '">\n';
	return HiddenInput;
}

function isNumeric (TestNumber) { // 4.
	/* Parameter is STRING - returns true if only numerics */
	var RegExTrue = /\D/;
	if (TestNumber.search(RegExTrue) == -1 ) {
		return true;
	}
	return false;
}

function emProtect (mode, to, domain, subject, name) { //5.
	/* Creates HTML for email address - hidden from robot harvesting */
	/* mode =	inline - normal mailto: link displaying email address
				inlinetext - normal mailto: link but displaying text from parameter 'name'
				inlineimg - normal mailto: link but using an image
				formmailto - simple action on FORM
				formcgi - call to eshop standard form2mail (mail.pl)
				hidden - creates a hidden form field
				 */
	var em = to + '@' + domain; // to = 1st part of email address; domain = 2nd part
	var result;
	if (subject == "") { subject = "Enquiry from web site"; }
	var URL = 'mailto:' + em + "?subject=" + subject;
	var RegEx = /hidden/;
	if (mode.search(RegEx) > -1) { // mode = hidden
		result = '<input type="hidden" name="' + name + '" id="' + name + '" value="' + em + '">';
		document.write (result);
		return;
	}
	RegEx = /inline/;
	if (mode.search(RegEx) != -1) { // mode = inline or inlinetext or inlineimg
		result = '<a href="' + URL + '">' ; // Double quote around href
		RegEx = /text/;
		if (mode.search(RegEx) == -1) { // mode is not inlinetext, it may be just inline
			name = em;
		}
		RegEx = /img/;
		if (mode.search(RegEx) == -1) { // mode is not inlineimg
			result += name + "</a>"; // so add text and close tag
		}
		document.write (result);
	}
	else { // mode = formmailto  or formcgi
		var FormObject = getObj (name);
		RegEx = /mailto/;
		if (mode.search(RegEx) != -1) { // mode is formmailto
			FormObject.action = URL;
			FormObject.encoding = 'Text/Plain';
			FormObject.method = 'POST';
		}
		else { // mode is formcgi
			// form action is already set in NOF e.g. ../cgi-bin/mail.pl
			// form hidden fields to be set:
			FormObject.To.value = em;
			FormObject.Domain.value = domain;
		}
	}
}

function submitEnquiry (formObj) {// 6.
	// Checks standard fields and puts other into a message body
	// Form action: ../cgi-bin/mail.pl" id='ContactUs' onsubmit="return submitEnquiry(this)
	// Phone response requested?
	if (formObj.PhoneResponse && formObj.PhoneResponse.checked) { // Yes
		if (!Check('Phone', 'phone')) { // Must have valid phone number
			alert('Sorry, you need to enter a valid phone number.');
			return false;
		}
		// if there is an entry for Email, it must be valid
		if (formObj.Email.value.length > 0) {
			if (!Check('Email', 'email')) {
				alert('Sorry, your email address is incorrect.');
				return false;
			}
		} else { // No email
			if (formObj.Copy) {
				formObj.Copy.checked = false; // So cannot request an email copy
			}
			formObj.Email.value = "noaddressentered@" + formObj.Domain.value; // Use dummy value
		}
	} else { // Not requesting phone response
		// Check email field is valid
		if (!Check('Email', 'email')) {
			alert('Sorry, your email address is incorrect.');
			return false;
		}
		// If Phone exists, it must be valid
		if (formObj.Phone && formObj.Phone.value.length > 0) {
			if (!Check('Phone', 'phone')) {
				alert('Sorry, you do not need to enter a phone number, but if you do it must be valid.');
				return false;
			}
		}
	}
	// Get all form elements
	var Body = "\n";
	var Checked = "";
	// Standard fields: Email (of user), Subject, Text (email body), Message (to display to user after mail successfully sent), Copy, To, Domain (Last 2 fields populated by emProtect())
	var RegEx = /Email|Subject|Text|Message|To|Domain|Submit|Copy/;
	for (i=0; i<formObj.elements.length; i++) {
		if ((formObj.elements[i].name.search(RegEx) == -1) // Not a standard field
		&& (getStyleProperty(formObj.elements[i], "visibility") != "hidden" )) { // & not hidden explicitly
			// (formObj.elements[i].currentStyle.visibility != "hidden" )
			// Construct output string from field name & value
			// alert ("Element " + i + " is not a standard field; Name " + formObj.elements[i].name + "; Visibility " + formObj.elements[i].currentStyle.visibility);// Debug
			if (formObj.elements[i].checked) { // Property valid for all input elements
				Checked = " - CHECKED";
			} else {
				Checked = "";
			} 
			Body += formObj.elements[i].name + ": " + formObj.elements[i].value + Checked + "\n";
		}
	}
	formObj.Text.value = Body + "\r\rMessage:\r" + formObj.Text.value;
	return true;
}

function DisplayMeta(Option) {// 7.
	// Displays Meta Tag Information in form fields (if existing)
	// Expected form field ids: metaTitle, metaKeywords, metaDescription
	// Call this function after page & form has loaded. E.g. when radio button selected

	// 7.0 Hide if Option = Keywords
	var objF = getObj("DisplayMetaForm");
	if (Option == "Keywords") {
		if (objF) {
			objF.style.display = "none";
		}
		return;
	}
	// 7.1 Meta Objects on the page
	var objMT	= getObj("title");
	if (objMT == undefined) {objMT = document.all.tags("title")[0];}
	if (objMT == undefined) {objMT = document.getElementsByTagName("title")[0];}
	var objMKW	= getObj("keywords");
	var objMD	= getObj("description");
	// 7.2 Form Objects
	var objFT	= getObj("metaTitle");
	var objFKW	= getObj("metaKeywords");
	var objFD	= getObj("metaDescription");
	// 7.3 Display Title
	if (objFT) {
		if (objMT) {
			objFT.value = objMT.text;
		}
		else {
			objFT.value = "No TITLE tag found.";
		}
	}
	// 7.4 Display Keywords
	if (objFKW) {
		if (objMKW) {
			objFKW.value = objMKW.content;
		}
		else {
			objFKW.value = "No meta tag found for KEYWORDS.";
		}
	}
	// 7.5 Display Description
	if (objFD) {
		if (objMD) {
			objFD.value = objMD.content;
		}
		else {
			objFD.value = "No meta tag found for DESCRIPTION.";
		}
	}
	// 7.6 Show Meta Tags Display Form
	if (objF) {
		objF.style.display = "block";
	}
}

function ProcessTextLinks (Domain) { // 8.
	// Takes webmaster's Link text and converts to HTML.
	// Standard LINKS page. For each Link text found in between tags (PerlTagStart95 to 98):
	// - overwrites with the HTML in a text area
	// - plugs the HTML into the adjacent area (with suffix a e.g. PerlTagStart95a)
	var objForm200 = getObj ("Form200");
	if (objForm200 == undefined) {return;} // Can't do anything!
	var Form200 = objForm200.innerHTML;
	var i, From, To, LT, HTML, TextArea;
	for (i = LinksTextStart; i < LinksTextEnd; i++) { // several text links allowed for
		From = "<!--PerlTagStart" + NumToText(i, 2) + "-->";
		To = "<!--PerlTagEnd" + NumToText(i, 2) + "-->";
		LT = ExtractText(Form200, From, To); // Link text from Webmaster
		if (LT != "") {
			LT = LT.replace ( /<[^>]*>$/, ""); // get rid of any trailing html tags (selfupdate.pl may insert)
			HTML = '<a href="http://www.' + Domain + '">' + LT + '</a>';
			TextArea = '<textarea class="HtmlLinks">' + HTML + '</textarea>';
			Form200 = ReplaceText(Form200, From, To, TextArea);
			// alert ("Loop: " + i + ". TextArea: " + TextArea + ". Form200 after replacement: " + Form200);
			From = "<!--PerlTagStart" + NumToText(i, 2) + "a-->";
			To = "<!--PerlTagEnd" + NumToText(i, 2) + "a-->";
			Form200 = ReplaceText(Form200, From, To, "<p>" + HTML + "</p>");
		}
	}
	objForm200.innerHTML = Form200;
}

function ProcessImageLinks (Domain) {// 9.
	// Takes webmaster's title words and adds them to the HTML
	// Standard LINKS page. For each image Title text found in between tags (PerlTagStart101 to 99):
	// - adds the Title HTML attribute to the generated HTML image/ link & puts into a textarea tag in the adjacent area (with suffix a e.g. PerlTagStart101a)
	// - adds the HTML into the original area (e.g. PerlTagStart101)
	var objForm100 = getObj ("Form100");
	if (objForm100 == undefined) {return;} // Can't do anything!
	var Form100 = objForm100.innerHTML;
	var i, From, To, TT, HTML, TextArea;
	for (i = LinksImageStart; i < LinksImageEnd; i++) { // several image links allowed for
		From = "<!--PerlTagStart" + NumToText(i, 2) + "-->";
		To = "<!--PerlTagEnd" + NumToText(i, 2) + "-->";
		TT = ExtractText(Form100, From, To); // Title attribute's text from Webmaster
		if (TT != "") {
			TT = TT.replace ( /<[^>]*>/g, ""); // get rid of any html tags (selfupdate.pl may insert some)
			HTML = '<a href="http://www.' + Domain + '" title="' + TT + '" alt="' + TT + '"><img src="http://www.' + Domain + '/assets/images/photolinks' + NumToText(i, 2) + '.gif" border="0"></a>';
			TextArea = '<textarea class="HtmlLinks">' + HTML + '</textarea>';
			Form100 = ReplaceText(Form100, From, To, '<p>' + TT + '</p>' + HTML);
			// alert ("Loop: " + i + ". TextArea: " + TextArea + ". Form100 after replacement: " + Form100);
			From = "<!--PerlTagStart" + NumToText(i, 2) + "a-->";
			To = "<!--PerlTagEnd" + NumToText(i, 2) + "a-->";
			Form100 = ReplaceText(Form100, From, To, TextArea);
		}
	}
	objForm100.innerHTML = Form100;
}


function ShowDate(Format) { // 10.
	/* Displays current day & date. Not updated. */
	/* Format e.g. "sday, d mmm yyyy" - not currently used*/
	var mydate=new Date();
	var year=mydate.getFullYear();
	var day=mydate.getDay();
	var month=mydate.getMonth();
	var daym=mydate.getDate();
	var superscript="th"
	if (daym==1 || daym==21 || daym==31) {superscript="st"}
	if (daym==2 || daym==22) {superscript="nd"}
	if (daym==3 || daym==23) {superscript="rd"}
	superscript = "<sup>" + superscript + "</sup>";
	var dayarray=new Array("Sun","Mon","Tues","Wed","Thur","Fri","Sat");
	var montharray=new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
	document.write("<p class='date'>"+dayarray[day]+", "+daym+superscript+" "+montharray[month]+" "+year+"</p>");
}


function getObj(ObjId) { // 11.
	// returns object reference given its id. Avoids rare problems with DOM
	if (document.getElementById) {
		return document.getElementById(ObjId);
	}
	return document.all[ObjId];
}


function getStyleProperty(obj, Property){ // 12.
	// use instead of .currentStyle
	if (obj.currentStyle) { // IE model
		return eval("obj.currentStyle." + Property);
	} else { // W3C DOM model
		var vw = document.defaultView;
		var currStyle = vw.getComputedStyle(obj, "");
		return currStyle.getPropertyValue(Property);
	}
}


function NumToText (Num, Length) { // A. returns string of Num, with leading zeroes to Length
	var a = Num.toString();
	var j;
	for (j = a.length; j < Length; j++) {
		a = "0" + a;
	}
	return a;
}

function ExtractText (Block, Start, End) {
	// B. returns the characters between the strings Start & End from object Block
	var a = "";
	var s = Block.indexOf(Start);
	if (s == -1) { return a;} // Start not found
	var f = Block.indexOf(End);
	if (f == -1) { return a;} // End not found
	a = Block.substring(s + Start.length, f);
	return a;
}

function ReplaceText (Block, Start, End, Replacement) {
	// C. replaces the characters between the strings Start & End from object Block
	var s = Block.indexOf(Start);
	if (s == -1) { return a;} // Start not found
	var f = Block.indexOf(End);
	if (f == -1) { return a;} // End not found
	return Block.slice(0, s + Start.length) + Replacement + Block.slice(f);
}
