/*

VALIDATIONS.JS
 - written by Tyler Waters
 - designed for validation of required form fields.

Copyright 2008, Province of British Columbia, all rights reserved.
This material is owned by the Ministry of Forests and Range and
the Government of British Columbia and is protected by copyright
law. It may not be reproduced or redistributed without the prior
written permission of the Province of British Columbia.

THIS FILE IS CURRENTLY LINKED FROM:

	icw/hva/scs/accessrequest.htm
	icw/hva/scs/maintenence.htm
	icw/hva/fcs/maintenence.htm
	icw/hva/client/accessrequest.htm
	gww/hva/gbs/accessrequest.htm

IMPORTANT NOTE:
  this is not a replacement for server-side validation
  there is of no recourse for users without javascript

BENEFITS:

	- users with javascript are prompted for required fields
	- correct formats for fields are maintained
	- no alerts -- error-messages SPANs are attached to DOM

USEAGE:

	- make a reference to "validations_final.js"

	- make calls to validate(_name, _element, _type, _optional) in the MailForm_OnSubmit function

		_name -- not used at the moment, previously used for alerts -- replaced with DOM-SPAN-messages.
		_element -- ID (or in case of radios, the NAME) of element
		_type -- one of the following:

			text
			radio
			numeric
			client_number
			location_code
			combo
			acct_bceid
			acct_idir
			acct_both
			phone
			email

		_optional
		-- TRUE  -- if field is blank, will return true (otherwise validated based on _type)
        -- FALSE / UNDEFINED -- validates as normal.
*/

var DEBUG = 0;

var errors = Array();
var errorsIndex = Array();

function validate( _name, _element, _type, _optional ) {
	var e;
	var theType = _type.toLowerCase();

	// get element -- thes ID is _element, OR in case of radios, the NAME
	// radios handled right away and returned to avoid further processing.

	switch( theType ) {
		case "radio":
			e = document.getElementsByName(_element);
		break;

		case "bceid":
		case "idir":
		case "account":
		case "client_number":
		case "location_code":
		case "text":
		case "combo":
		case "numeric":
		case "phone":
		case "email":
			e = document.getElementById(_element);
		break;
		default:
			DEBUG && alert("ERROR:\n\n INVALID FIELD TYPE:" + theType + " PASSED!!");
			return false;
	}

	if( !e ) DEBUG && alert("Error:\n\nElement "+ _name +" of type " + _type + " not found:\n" + _element );
	if( theType != "combo" && theType != "radio" ) e.value = e.value.trim().normalize_space().toUpperCase()

	// process element

	switch( theType ) {

		// radios are special, only element that's really an array of elements
		// checks each one, if a checked one is found, return unthrow; else, return thrower

		case "radio":
			for(x=0;x<e.length;x++) if( e[x].checked == true ) return unthrow( e[0] );
			if( _optional ) { return unthrow( e[0] ); }
			else { return thrower("Select one", e[0]);  }
		break;

		case "email":
		case "phone":
		case "combo":
		case "text":
		case "numeric":
		case "client_number":
		case "location_code":

			// all inputs are checked for blanks.
			// if optional, return true.

			if( theType == "combo" ) {

				//alert(e.options[ e.selectedIndex ].text=="");

				if( e.value == "" || e.options[ e.selectedIndex ].text == "" ) {
					if( _optional ) { return true; }
					else { return thrower( "Must be entered", e );  }
				}
			}


			if( e.value == "" ) {
				if( _optional ) { return true; }
				else { return thrower( "Must be entered", e );  }
			}

			// PHONE
			// removes spaces, periods, paraenthesis and dashes,
			// checks length is 10, makes format (012) 345-6789

			if( theType == "phone" ) {
				if( !e.value.replace(/\(|\)|\s|\-|\./gi, "").match(/^[0-9]{10}$/, "gi")) {
					return thrower( "Must have 10 numeric digits", e);
				}
				else {
					// remove parenthesis, dashes, spaces & periods. & re-insert in correct places
					e.value = e.value.replace(/\(|\)|\s|\-|\./gi, "")
					e.value = "("+ e.value.substring(0,3) +") "+ e.value.substring(3,6) +"-"+e.value.substring(6,10)+""
				}
			}

			// EMAIL
			// run through this rediculous regular expression that determines a valid email.

			if( theType == "email") {
				if( !e.value.match( /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/,"gi" ) ) {

					return thrower( "Invalid Email", e);
				}
			}

			// NUMERIC
			// check that is numeric. client number = len(8), location code = len(2), all others no len() restriction.

			if( theType == "numeric" || theType == "client_number" || theType == "location_code" ) {
				var magicNumber =  theType == "numeric" ? -1 :  theType == "client_number" ? 8 :  theType == "location_code" ? 2 :  "";
				if( magicNumber == "") { DEBUG && alert("coding error -- fix it"); break; }
				if( magicNumber == -1) {
					if( e.value.match(/^[0-9]{1,}$/) ) { break; }
					else { return thrower("Must be numeric", e); }
				}
				else {
					if( eval(" e.value.match(/^[0-9]{"+magicNumber+"}$/)") ) { break; }
					else {
						if( eval("!e.value.match(/^[0-9]{1,"+magicNumber+"}$/)") ) {
							return thrower( "Failed Validation", e );
						} else {
							while( e.value.length < magicNumber ) e.value = "0" + e.value
							return true;
						}
					}
				}
			}
		break;

        /*
          ACCOUNT - ensures account includes IDIR\ or BCEID\ with some text
          when reg exps are quoted, need to escape everything. plus "\" is the escape character.
          so yes, i am escaping the escaped escape character.... "^\\\\$" => ^\\$ => \
        */

        case "bceid":   
        case "idir":    
        case "account": 
        var v="", error="";
        if( theType=="bceid"){ v = "(BCEID)"; error = "must include BCEID\\";  }
        else if(theType=="idir"){ v = "(IDIR)"; error = "must include IDIR\\";}
        else if(theType=="account"){ v = "(BCEID|IDIR)"; error = "must include  either BCEID\\ or IDIR\\";}

        if( !e.value.match("^"+ v +"\\\\", "gi") ) { return thrower( _name + " " + error, e ); }
        if( !e.value.match("^"+ v +"\\\\.+", "gi") ) { return thrower( _name + " failed blank validation", e); }
        break;
	}

	return unthrow( e );

}

// create an error span with the image.

var errorSpan = document.createElement("SPAN");
errorSpan.style.cssText = "padding:5px 0 0 5px; font-weight:bold; color:#FF0000;";

var errorIMG = document.createElement("IMG");
errorIMG.name = "errorIMG";
errorIMG.id = "errorIMG";
errorIMG.src="/images/portal/icon_error.gif"
errorIMG.style.cssText = "border:0; margin-top:5px;"
errorSpan.appendChild(errorIMG);

var errorContainer = document.createElement("DIV");
errorContainer.appendChild( errorIMG );
errorContainer.appendChild( errorSpan );

// clears all the errors -- called when form reset.

function clearErrors() {
	for(x=errorsIndex.length-1;x>=0;x--) unthrow(document.getElementById(errorsIndex[x]));
}

// remove the error SPAN element from form... clear the normal array... return true.
// called after an element passes validation.

function unthrow(_e) {
	if( errors[_e.id] ) {
		_e.parentNode.removeChild( errors[_e.id] );
		for(x=0;x<errorsIndex.length;x++) {
			if( errorsIndex[x] == _e.id ) {
				errorsIndex.splice(x,1);
				errors[_e.id] = null;
				break;
			}
		}
	}
	return true;
}

// creates an error SPAN element (appends to form, stores in an associative array for easy removing)
// Id of element is stored in normal array for easier processing
// called after an element fails validation

function thrower( _m, _e ) {
	if( errors[_e.id] ) unthrow( _e );
	if( !errors[_e.id] ) {
		errorsIndex[errorsIndex.length] = _e.id;
		errors[_e.id] = errorContainer.cloneNode(true);
		errors[_e.id].getElementsByTagName('SPAN')[0].appendChild( document.createTextNode( _m ) )
		_e.parentNode.appendChild( errors[_e.id] );
	}
	try{ if( _e.focus) _e.focus();} catch(e) {}
	return false;
}


// TRIM = Strip leading and trailing white-space
// NORMALIZE_SPACE = Replace repeated spaces, newlines and tabs with a single space

String.prototype.trim = function() { return this.replace(/^\s*|\s*$/g, ""); }
String.prototype.normalize_space = function() { return this.replace(/^\s*|\s(?=\s)|\s*$/g, ""); }



function setDate( dateTimeInput ){
	var dd = new Date(); if( typeof dateTimeInput == "string") dateTimeInput = document.getElementById(dateTimeInput);
	dateTimeInput.value = dd.getFullYear() + "-" + padZero( dd.getMonth()+1, 2) + "-" + padZero( dd.getDate(), 2 ) + " " + padZero( dd.getHours(), 2) + ":" + padZero( dd.getMinutes(), 2) + ":" + padZero( dd.getSeconds(), 2);
}

function padZero(strString, intZeros) {
  var num = strString.toString(); while (num.length<intZeros)num="0"+num; return num;
}

function addEvent(obj,evType,fn,useCapture){  if(obj.addEventListener){obj.addEventListener(evType,fn,useCapture);return true;}  else if(obj.attachEvent){var r=obj.attachEvent("on"+evType,fn);return r;}  else {obj['on'+evType]=fn;return false;}}
function removeEvent(obj,evType,fn,useCapture){  if(obj.removeEventListener){obj.removeEventListener(evType,fn,useCapture);return true;}  else if(obj.detachEvent){var r=obj.detachEvent("on"+evType,fn);return r;}  else {obj['on'+evType]=null;return false;}}