function OpenBrWindow(theURL,winName,features, myWidth, myHeight, isCenter) {
  if(window.screen)if(isCenter)if(isCenter=="true"){
    var myLeft = (screen.width-myWidth)/2;
    var myTop = (screen.height-myHeight)/2;
    features+=(features!='')?',':'';
    features+=',left='+myLeft+',top='+myTop;
  }
  window.open(theURL,winName,features+((features!='')?',':'')+'width='+myWidth+',height='+myHeight);
}


// ----------------------------------------------------------------------
// Javascript form validation routines.
// Author: Stephen Poley
//
// Simple routines to quickly pick up obvious typos.
// All validation routines return true if executed by an older browser:
// in this case validation must be left to the server.
//
// Update Jun 2005: discovered that reason IE wasn't setting focus was
// due to an IE timing bug. Added 0.1 sec delay to fix.
//
// Update Oct 2005: minor tidy-up: unused parameter removed
//
// Update Jun 2006: minor improvements to variable names and layout
// ----------------------------------------------------------------------

var nbsp = 160;		// non-breaking space char
var node_text = 3;	// DOM text node-type
var emptyString = /^\s*$/ ;
var global_valfield;	// retain valfield for timer thread

// --------------------------------------------
//                  trim
// Trim leading/trailing whitespace off string
// --------------------------------------------

function trim(str)
{
  return str.replace(/^\s+|\s+$/g, '');
}

/*
// --------------------------------------------
//                  setfocus
// Delayed focus setting to get around IE bug
// --------------------------------------------

function setFocusDelayed()
{
  global_valfield.focus();
}

function setfocus(valfield)
{
  // save valfield in global variable so value retained when routine exits
  global_valfield = valfield;
  setTimeout( 'setFocusDelayed()', 100 );
}
*/

// --------------------------------------------
//                  msg
// Display warn/error message in HTML element.
// commonCheck routine must have previously been called
// --------------------------------------------

function msg(fld,     // id of element to display message in
             msgtype, // class to give element ("warn" or "error")
             message) // string to display
{ 
  // 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)
// --------------------------------------------

var proceed = 2;  

function commonCheck    (valfield,   // element to be validated
                         infofield,  // id of element to receive info/error msg
                         required)   // true if required
{
  if (!document.getElementById) 
    return true;  // not available on this browser - leave validation to the server
  var elem = document.getElementById(infofield);
  if (!elem.firstChild) return true;  // not available on this browser 
  if (elem.firstChild.nodeType != node_text) return true;  // infofield is wrong type of node  

	var tagtype=valfield.nodeName;
	
	switch (tagtype) {
		case 'SELECT':
			var val=valfield.options[valfield.selectedIndex].value;
			break;
		default:
			var val=valfield.value;
			break;
		}
  if (emptyString.test(val)) {
    if (required) {
      msg (infofield, "valid_error", "ERROR: Required");  
      //setfocus(valfield);
      return false;
    }
    else {
      //msg (infofield, "valid_warn", "");   // OK
      msg (infofield, "valid_ok", "");   // OK
      return true;  
    }
  }
  return proceed;
}

// --------------------------------------------
//            validatePresent
// Validate if something has been entered
// Returns true if so 
// --------------------------------------------

function validatePresent(valfield,   // element to be validated
                         infofield ) // id of element to receive info/error msg
{
  
  var stat = commonCheck (valfield, infofield, true);
  if (stat != proceed) return stat;

  msg (infofield, "valid_ok", "");  
  return true;
}

	
	  // Validator Object
    var regex = new Object();
    var error = new Object();

    // REGEX Elements
		
		// alphanumeric
		regex.alphanumeric=/^[a-zA-Z0-9]+$/;
		error.alphanumeric=' field. Numbers/letters only.';
		
		//numeric
		regex.numeric=/^[0-9]+$/;
		error.numeric=' field. Numeric only.';
		
    // matches zip codes
    regex.zipCode = /\d{5}(-\d{4})?/;

    // matches australian postcode
    regex.ozPostcode = /^(((2|8|9)\d{2})|((02|08|09)\d{2})|([1-9]\d{3}))$/;
    error.ozPostcode = 'postcode';
    
    // matches $17.23 or $14,281,545.45 or ...
    //valid.currency = /\$\d{1,3}(,\d{3})*\.\d{2}/;
    regex.currency =/^\$?(\d{1,3},?(\d{3},?)*\d{3}(\.\d{0,2})?|\d{1,3}(\.\d{0,2})?|\.\d{1,2}?)$/;
    error.currency = 'currency amount';

    // matches 5:04 or 12:34 but not 75:83
    regex.Time = /^([1-9]|1[0-2]):[0-5]\d$/;

    //matches email
    regex.emailAddress = /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?)$/;
		error.emailAddress = 'email adress';
		
    // matches phone ###-###-####
    regex.phoneNumber = /^\(?\d{3}\)?\s|-\d{3}-\d{4}$/;

		//matches australia phone number
		regex.ozPhone = /^\({0,1}((0|\+61)(\ |-){0,1}(2|4|3|7|8)){0,1}\){0,1}(\ |-){0,1}[0-9]{2}(\ |-){0,1}[0-9]{2}(\ |-){0,1}[0-9]{1}(\ |-){0,1}[0-9]{3}$/;
    error.ozPhone='phone number';
    
    // International Phone Number
    regex.phoneNumberInternational = /^\d(\d|-){7,20}/;

    // IP Address
    regex.ipAddress = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;

    // Date xx/xx/xxxx
    regex.Date = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{4}$/;
    
    // Date DD/MM/YYYY or DD/MM/YY or DD-MM-YYYY or DD-MM-YY, MM: 1-12, DD:1-30 or 1-31
		regex.ozDate=/^(((0[0-9])|([12])([0-9]?)|(3[01]?))(-|\/)(0?[13578]|10|12)(-|\/)((\d{4})|(\d{2}))|((0[0-9])|([12])([0-9]?)|(3[0]?))(-|\/)(0?[2469]|11)(-|\/)((\d{4}|\d{2})))$/;
		error.ozDate='date';

    // State Abbreviation
    regex.State = /^(AK|AL|AR|AZ|CA|CO|CT|DC|DE|FL|GA|HI|IA|ID|IL|IN|KS|KY|LA|MA|MD|ME|MI|MN|MO|MS|MT|NB|NC|ND|NH|NJ|NM|NV|NY|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VA|VT|WA|WI|WV|WY)$/i;

    // Social Security Number
    regex.SSN = /^\d{3}\-\d{2}\-\d{4}$/;
    
    //credit card validator for AMEX, VISA, MasterCard, Diners. Allows spaces, dashes, or no separator between digit groups according to the layout (4-6-5 for AMEX, 4-4-4-4 for Visa and Mastercard)
		//Visa (length 16, prefix 4); Mastercard (length 16, prefix 51-55); Diners Club/(length 14, prefix 36, 38, or 300-305);  AMEX (length 15, prefix 34 or 37).
    regex.creditCard= /^(((4\d{3})|(5[1-5]\d{2}))-?\d{4}-?\d{4}-?\d{4})|(3[4,6-8]\d{2}-?\d{6}-?((\d{5})|(\d{4})))$/;
		error.creditCard='credit card number';
		
		regex.MCVisa=/^(((4\d{3})|(5[1-5]\d{2}))([ -]?)\d{4}([ -]?)\d{4}([ -]?)\d{4})$/;
		error.MCVisa=' Visa/Mastercard number';

		regex.MCVisaAmex=/^(((4\d{3})|(5[1-5]\d{2}))([ -]?)\d{4}([ -]?)\d{4}([ -]?)\d{4})|((3[4,7]\d{2})[ -]?\d{6}[ -]?\d{5})$/;		
		//regex.MCVisaAmex=/^((4\d{3})|(5[1-5]\d{2}))[ -]?(\d{4}[ -]?){3}$|^(3[4,7]\d{2})[ -]?\d{6}[ -]?\d{5}$/;
		error.MCVisaAmex=' Visa/Mastercard/Amex';
		
		//Prime Access account numbers - of form 2 or 3 letters than any number of numerals
		//regex.accountNumber=/^[a-zA-Z]{2,3}\d+$/
		//error.accountNumber=' account number';

		regex.accountNumber=/^(AA|CD|SF|SAL|CH|CJ|ML|AL|SL|MS|CAH|VDS|AG|PJ|WH)\d+$/i;
		error.accountNumber=' account number';    
 
		//iterates retrogradely through all the form elements
		//validating each one, and placing focus in the highest element up the page with an error
    function validateForm(formName,submit) {
				
        if (!formName) formName=0;
        var elems = document.forms[formName].elements; 
				var valid = true;
				var j;
				var errs=0;
				
        for(var i = elems.length-1; i >=0 ; i--) {
									if(!validateElement (elems[i])){
											 j=i;
											 errs++;
											 valid=false;
											
											}
        }
				if (!valid) { //put the focus in the final field found to be invalid (higher up the page)
                 if (errs>1)  alert('There are fields which need correction before submitting');
      					 if (errs==1) alert('There is a field which needs correction before submitting');
      					 elems[j].select();
                 elems[j].focus();
				}
				if (submit&&valid) document.forms[formName].submit();
        return valid;
      }
      
    //validates elements by looking for an attribute called 'validator'
    //campares the value of the element with a regex indicated by the contents of the attribute 'validator'
    //if validator is followed by '|notRequired' then it can either fit the regex, or be blank 
    //if the value of validator is not in the regex list, it simply checks whether it is present
    //if invalid, it looks for an element with the id that is the same as the name of the element with "val_" before it
    // eg. if hte field is called "title" it looks for  an element with the id "val_title"
    // changes its class to "val_error" and inserts the error message into the innerHTML
    
    function validateElement (elem)
      {
      				var validator = elem.getAttribute("validator");
							var valid=true;
														
              if(validator) {
              		//trim leading and trailing spaces
									elem.value=trim(elem.value);
              		
              		var validRequired=true;
									var validArray = new Array();
									validArray  = validator.split('|');
									if (validArray[1]=='notRequired') validRequired=false;
									var validType=validArray[0];
									
		              var infofield=document.getElementById('val_'+elem.getAttribute("name"));
									var pattern = regex[validType];

									if (!pattern) {
										if (validRequired) {
										 if(!validatePresent(elem,  infofield.id)) {
										 	elem.className='valid_data_error';
										 	valid=false;
											}
										}	
									}
									else {														
				             if(!pattern.exec(elem.value)) {
				             			if ((validRequired)||(!validRequired&&elem.value)) {
					                	if (infofield) msg (infofield.id, 'valid_error', 'ERROR: Invalid '+error[validType]);
					                	elem.className='valid_data_error';
					                	valid=false;		
				              		} 
		            			}
		          		}
		          		if (valid) {
		          			if (infofield) msg (infofield.id, 'valid_ok', '');
		          			elem.className='';
		          		}
		          }
		          
	            return valid;
      }
      
