var nbsp = 160;    // non-breaking space char
var node_text = 3; // DOM text node-type
var emptyString = /^\s*$/
var glb_vfld;      // retain vfld for timer thread

function trim(str)
{
  return str.replace(/^\s+|\s+$/g, '')
};

function setFocusDelayed(vfld)
{
  glb_vfld.focus()
};

function setfocus(vfld)
{
  glb_vfld = vfld;
  setTimeout( 'setFocusDelayed()', 100 );
};

/**
*msg
*						fld id of element to display message in
*						msgtype class to give element ("warn" or "error")
*						message string to display
*
*/
function msg(fld, msgtype, message)
{
  // setting an empty string can give problems if later set to a 
  // non-empty string, so ensure a space present. (For Mozilla and Opera one could 
  // simply use a space, but IE demands something more, like a non-breaking space.)
  var dispmessage;
  if(emptyString.test(message)) 
    dispmessage = String.fromCharCode(nbsp);
  else
    dispmessage = message;

  var elem = document.getElementById(fld);
  elem.firstChild.nodeValue = dispmessage;
  
  elem.className = msgtype;// set the CSS class to adjust appearance of message
};

/**-----------------------------------------
*            commonCheck
* Common code for all validation routines to:
* (a) check for older / less-equipped browsers
* (b) check if empty fields are required
* Returns true (validation passed), 
*         false (validation failed) or 
*         proceed (don't know yet)
*
*vfld element to be validated
*ifld id of element to receive info/error msg
*reqd true if required
*/

var proceed = 2;  

function commonCheck (vfld, ifld, reqd)
{
  if(!document.getElementById) 
    return true;  // not available on this browser - leave validation to the server
  var elem = document.getElementById(ifld);
  if(!elem.firstChild)
    return true;  // not available on this browser 
  if(elem.firstChild.nodeType != node_text)
    return true;  // ifld is wrong type of node  

  if(emptyString.test(vfld.value))
	{
    if(reqd)
		{
      msg (ifld, "error", "ERROR: required");  
      setfocus(vfld);
      return false;
    }
    else
		{
      msg (ifld, "warn", "");   // OK
      return true;  
    }
  }
  return proceed;
};

/**
*validateCopies
*						vfld To be validated
*						ifld id of element to receive info/error msg
*						reqd true if required
*/
function validateCopies(vfld, ifld, reqd)
{
  var stat = commonCheck(vfld, ifld, reqd);
  if(stat != proceed)
		return stat;
	
 	if(vfld.value > 0)
	{
	 	msg(ifld, "warn", "");
		return true;
	}
	else
	{
	 	msg(ifld, "error", "ERROR: not a valid number of copies");
		return false;
	}
};

/**
*validateName
*						vfld To be validated
*						ifld id of element to receive info/error msg
*						reqd true if required
*/
function validateName(vfld, ifld, reqd)
{
  return commonCheck(vfld, ifld, reqd);
};

/**
*validateAddress
*						vfld To be validated
*						ifld id of element to receive info/error msg
*						reqd true if required
*/
function validateAddress(vfld, ifld, reqd)
{
  return commonCheck(vfld, ifld, reqd);
};

/**
*validateCity
*						vfld To be validated
*						ifld id of element to receive info/error msg
*						reqd true if required
*/
function validateCity(vfld, ifld, reqd)
{
  return commonCheck(vfld, ifld, reqd);
};

/**
*validatePostcode
*						vfld To be validated
*						ifld id of element to receive info/error msg
*						reqd true if required
*/
function validatePostcode(vfld, ifld, reqd)
{
  return commonCheck(vfld, ifld, reqd);
};

/**
*validateCountry
*						vfld To be validated
*						ifld id of element to receive info/error msg
*						reqd true if required
*/
function validateCountry(vfld, ifld, reqd)
{
  var stat = commonCheck(vfld, ifld, reqd);
  if(stat != proceed)
		return stat;
	
 	if(vfld.value == "australia" || vfld.value == "uk" || vfld.value == "germany" || vfld.value == "russia" || vfld.value == "nz")
	{
	 	msg(ifld, "warn", "");
		return true;
	}
	else
	{
	 	msg(ifld, "error", "ERROR: We don't post to " + vfld.value);
		return false;
	}
};

/**
*validateEmail
*						vfld To be validated
*						ifld id of element to receive info/error msg
*						reqd true if required
*/
function validateEmail(vfld, ifld, reqd)
{
  var stat = commonCheck (vfld, ifld, reqd);
  if (stat != proceed) return stat;

  var tfld = trim(vfld.value);  // value of field with whitespace trimmed off
  var email = /^[^@]+@[^@.]+\.[^@]*\w\w$/
  if(!email.test(tfld))
	{
    msg (ifld, "error", "ERROR: not a valid e-mail address");
    setfocus(vfld);
    return false;
  }
	
  msg (ifld, "warn", "");
  return true;
};

/**
*validateName
*						vfld To be validated
*						ifld id of element to receive info/error msg
*						reqd true if required
*/
function validateCreditCardNo(vfld, ifld, reqd)
{
  var stat = commonCheck (vfld, ifld, reqd);
  if (stat != proceed) return stat;

	var tfld = vfld.value;
	
  var stripped = tfld.replace(/[\(\)\.\-\ ]/g, '');
  //strip out acceptable non-numeric characters
  if (isNaN(parseInt(stripped)))
	{
    msg(ifld, "error", "ERROR: creditcard number contains non-numbers");
    setfocus(vfld);
    return false;
  }

  if(tfld.length > 16)
	{
    msg(ifld, "error", "ERROR: creditcard number too long");
    setfocus(vfld);
    return false;
  }
	
  msg (ifld, "warn", "");
  return true;
};

/**
*validateName
*						vfld To be validated
*						ifld id of element to receive info/error msg
*						reqd true if required
*/
function validateCreditCardType(vfld, ifld, reqd)
{
  return commonCheck(vfld, ifld, reqd);
};

/**
*validateName
*						vfld To be validated
*						ifld id of element to receive info/error msg
*						reqd true if required
*/
function validateCreditCardName(vfld, ifld, reqd)
{
  return commonCheck(vfld, ifld, reqd);
};

/**
*validateMonth
*						vfld To be validated
*						ifld id of element to receive info/error msg
*						reqd true if required
*/
function validateCreditCardMonth(vfld, ifld, reqd)
{
  return commonCheck(vfld, ifld, reqd);
};

/**
*validateYear
*						vfld To be validated
*						ifld id of element to receive info/error msg
*						reqd true if required
*/
function validateCreditCardYear(vfld, ifld, reqd)
{
  return commonCheck(vfld, ifld, reqd);
};
