
//Stores our tiny fields
var tinyElements = new Array();

function tinyOninit(){
	/*
	var tinylist = tinyMCE.getParam('elements');
	tinylist = tinylist.split(',');
	tinyElements.push(tinylist);
	*/
}

var DocumentEvents = Object();
var EventHandler = {
	attachEvent : function(id, EHonEvent, EHmyFunc){
		if (!EventHandler.hasEvent(id,EHonEvent)){
			DocumentEvents[id+EHonEvent] = new Array();
		}
		var params = new Array();
		if (arguments.length > 3){
			for (var i = 3; i < arguments.length; i++){
				params.push(arguments[i]);
			}
		}
		DocumentEvents[id+EHonEvent].push({onEvent : EHonEvent, myFunc : EHmyFunc, myParams : params});
	},
	hasEvent : function (id, EHonEvent){
		//Check if this id has an event
		var test = DocumentEvents[id+EHonEvent];
		if (test){
			return true;
		} else {
			return false;
		}
	},
	idEvents : function (id,EHonEvent ){		
		return (DocumentEvents[id+EHonEvent]);
	},
	loadEvents : function (){
		for (var et in DocumentEvents){
			var idAndEvent = EventHandler.getIdAndEvent(et);		
			if (idAndEvent){
				var eventList = DocumentEvents[et];				
				EventHandler.run(idAndEvent[0], idAndEvent[1], eventList);	
			}
		}
		//Now clear the EventsArray
		DocumentEvents = new Object();
	},
	getIdAndEvent: function (myString){
		
		var reg = new RegExp("([A-Za-z0-9_]+)(onchange|onblur|onkeyup|onclick)");
		try {
			var matches  = myString.match(reg);
			return ([matches[1],matches[2]]);	
		}
		catch (e) {
			return false;	
		}
	},
	run: function (id, myEvent, eventList){
		var element = idE(id);		
		if (element){
			var myFunc = EventHandler.generateRunFunc(eventList);
			element[myEvent] = myFunc; 	
		}
	}, 
	/**
	 * @return function
	 */
	generateRunFunc: function(eventList){
		return(function(){
			var self = this;
			for (var i=0; i < eventList.length; i++){
				//Generate Arg String if we have Params
				var eventObj = eventList[i];
				var funcReturn = EventHandler.callFunc.call(self,eventObj.myFunc,eventObj.myParams);
			}
			return funcReturn;
		});
	},
	/**
	 * Calls a user function with arguments.
	 */
	callFunc : function (funcName, params){
		
		var paramString = '';	
		if (params.length > 0){
			for (var y = 0; y < params.length;y++){
				paramString += ',params['+y+']';	
			}
		}
		var self = this;
		try {
			eval("var myCall = " +funcName+".call(self"+paramString+")");			
		} catch (e){
			//alert(e);
			return false;
		}
		
		if (typeof(myCall) == 'function'){
			myCall();
		} else if (typeof(myCall) == 'boolean'){
			return myCall;
		}
		return 1;
	}
}

/*** String functions ***/
//Option is to add these methods as prototypes of String. 
var stringTools = {	
	trim: function(str){
		return str.replace(/^\s+/, '').replace(/\s+$/, '');		
	},
	/**
	checks and validates string type. 
	eg. to check for a numeric string of max length 4 = str, numeric, 0,4
	eg. to check a string of length 5 chars = str, string, 5,5
	returns boolean
	*/ 
	check: function(str, type, params)
	{
		str = stringTools.trim(str);	
		min = Number(params[0]) || 1;
		max = Number(params[1]) || '';		
		
		//Check if there are more than 2 params. If there are, the extra ones are values this str cannot equal
		if (params.length > 2){
			for (var i = 2; i < params.length; i++){
				if (str == params[i]) return false;
			}
		}		
		//Simple string checks.
		if (type == 'string' && (min >  0 &&  (max == '' || max == 0))){
			return str.length >= min ? true : false;			
		}
		//check if both are the same
		exactMatch = min == max ? true : false;
		if (exactMatch){
			repetitionExp = '{'+min+'}';
		} else {
			repetitionExp = '{'+min+','+max+'}';			
		}
		switch (type) {
			case "string" :exp = "[\\w\\W]";break;
			case "alpha" :exp = "[a-z]";break;
			case "numeric" :exp = "[0-9 ]";break;
		}
		regEx = new RegExp("^"+exp+repetitionExp+"$","im");
		return  str.search(regEx) != -1 ;
	},
	/**
	checks and validates amount of words
	eg. to check for a numeric string of max word length 4 = str, numeric, 0,4
	returns boolean or number of words
	*/ 
	checkWords: function(str, params)
	{
		str = stringTools.trim(str);
		str = str.replace(/\s+/gi, ' ');	
		min = Number(params[0]) || 1;
		max = Number(params[1]) || '';		
		words = str.split(' ');	
		wordCount = words.length; 

		if(str == '' && min > 0) {
			return false;
		}

		//Simple string checks.
		if (min >  0 &&  (max == '' || max == 0)){
			return wordCount >= min ? true : false;			
		} else if (min >  0 &&  (max > 0) && (max != '')){
			return (wordCount >= min) && (wordCount <= max) ? true : false;
		} 
	}
}

/** This adds an onsubmit to the form in FormValidator  ***/
function validateOnSubmit(formValidator, ajaxOptions){	
	var myForm = idE(formValidator.myForm);
	var myFunc = submitForm(formValidator, ajaxOptions);
	myForm.onsubmit = myFunc;
}
/**
 * Returns the function that is called by the form onsubmit
 * @param {Object} formValidator
 * @param {Object} ajaxOptions
 */
var submitForm = function (formValidator, ajaxOptions){	
	return (function(){
		try {
			// try saving 3.2.1.1
			tinyMCE.activeEditor.save();
		} catch(e) {
			try {
				// try saving 2.0.8
				tinyMCE.selectedInstance.triggerSave();
			} catch(e) {
				
				// we might not have tinyMCE available
			}
		}
		
		var valid =  formValidator.initSubmitValidation();	
		if (formValidator.options.callback && valid) {			
			eval('var callbackValid = '+formValidator.options.callback+'();');
			if (!callbackValid) valid = false;
		}
		if (ajaxOptions){
			if(valid){
				AjaxLoader.formSubmit(formValidator.myForm, ajaxOptions);	
			}
			return false;
		} else {
			return valid;	
		}});
}

/************** FORM VALIDATOR OBJECT *******************/
var FormValidator = function(formId, options){
	this.options = options || {};
	this.myForm = formId;
	this.validationRules = [];
	// detect if there's an error printed by php and jump to it!
	var $error = $$('.formErrorMessage');
	if($error.length > 0) {
		var id = $error[0].getParent().getParent().get('id');
		if(id != '' && id != null) {
			window.location.hash = '#'+id;
		}
	}
}

FormValidator.prototype = {
	//Define validation for element
	findElement: function(element) {
		var that = this.validationRules;
		for(var i = 0; i < that.length; i++) {
			if(that[i].divId == element) {
				return that[i];
			}
		}
		return false;
	},
	defineValidation : function (elementArg, type, validationArgs){
		
		//Set some vars for the validationRule object.
		var vR = new ValidationRule(elementArg, validationArgs, this);	
		vR.formName = this.myForm;
		var myForm = idE(this.myForm);
		
		vR.asset = this.asset;
		//check if its a date check. This element won't exist so get the day element.
		if (type == 'date' || type == 'datetime'){
			var elementName = elementArg+'[Day]';
		} else {
			var elementName = elementArg;
		}
		
		//Set the vR element name
		vR.element = elementName;		
		var element = myForm.elements[elementName];
		
		var p  = new RegExp("\\w+\\[(\\d)\\]\\[\\w+\\]");
		//Set type if it isn't a date check
		if (type != 'date'){
			try {
				//get the type
				type = element.type.toLowerCase();
				type = type == 'hidden' ? 'text' : type;
				//Get the asset number of this field. eg ASSET[INT][FIELD] etc. this sets the INT
				/*var matches  = element.name.match(p);
				if (matches){
					vR.assetNumber = matches[1];	 
				}*/
				
			} catch (e){			
				//Check box type
				if (type == 'checkbox'){
					vR.element = elementName + '[]';
					try {
						element = myForm.elements[vR.element];
						if (!element.length) {
							element = [element];
						}
						type = element[0].type.toLowerCase();	
					} catch (e) {
						element = myForm.elements[vR.element];
						type = element.type.toLowerCase();
					}
					
				} else if (type == 'select'){
					vR.element = elementName + '[]';
					element = myForm.elements[vR.element];
					type = element.type.toLowerCase();	
				}
			}
		}
		vR.type = type;
		vR.myForm = this.myForm;
		
		//Add this into the validation rules list
		this.validationRules.push(vR);
		
		//Also append the event to the element we are checking		
		addValidationEvent.create(vR,element);

		return vR;
	},

	/**
	 * Removes an element from teh validation array
	 */
	removeValidation: function(elementArg) {

		var validationArray = this.validationRules;
		this.validationRules.each(function(vR, index) {
			if(vR.divId.contains(elementArg)) {
				validationArray.erase(vR);
			}
		});
		addValidationEvent.remove($$('input[name*='+elementArg+']'));
		this.validationRules = new Array();
		this.validationRules = validationArray;


	},

	listRules : function (){
		for (var i=0; i < this.validationRules.length; i++) {
			vR = this.validationRules[i];
		}
	},
	
	listRules : function (){	
		for (var i=0; i < this.validationRules.length; i++) {
			vR = this.validationRules[i];
		}
	},	
	//This iterates through all our rules and checks em
	//Also sets focus to the first incorrect field
	initSubmitValidation : function (){
		//error counter
		error = 0;
		for (var ii =0 ; ii < this.validationRules.length ; ii++){
			vRule = this.validationRules[ii];
			valid = vRule.validate();
			
			//if its valid do nothing, else increment
			if (!valid){
				if (error == 0){

						// it could be a tiny mce field, we'll try to focus the iframe instead
						var formType = $$('input[name=assetClass]').get('value')[0];
						var fieldName = vRule.element.substr(vRule.element.lastIndexOf('[') + 1);
						fieldName = fieldName.substr(0, fieldName.length - 1);
						
						$iframe = $(formType+'_0__'+fieldName+'__ifr');
						if($iframe) {
							$iframe.focus();
						} else {
							try {
								var e = document.forms[this.myForm].elements[vRule.element];
								//console.log(e);
								e.focus();
							} catch (e) {
								//Silent

							}
						}
					
				}
				error++;
			}
		}
		//If error is > 0 we have errors so return false
		if (error > 0){		
			return false;
		} else {
			return true;	
		}
		return false;	
	}
}

/*************** Validation Rule Object ********************/
var ValidationRule = function(element, validationArgs, vF){	
	this.divId = validationArgs.divId || element;		
	this.errorMessage = validationArgs.eMsg || 0;
	this.validationFunc = validationArgs.vFunc || 0;
	this.params = validationArgs.args ||  [];
	this.vF = vF;
	this.value = '';
	//While we create the rule, hide the error message divs if they exist.
}

//Validate prototype function for ValidationRule
ValidationRule.prototype = {
	onValidate: null,
	onValidated: null,
	onValidateSuccess: null,
	onValidateFail: null,
	validate : function(){
		try {
			if (timechooser) {
				syncEndDate();
			}
		} catch(e) {
		}
		if (arguments.length > 0){
			var obj = arguments[0];			
			if(typeof obj == 'object'){
				var obj = document.forms[this.myForm].elements[this.element];
				if (this.type == 'checkbox') {
					if (!obj.length) {
						obj = [obj];
					}
				}
				if(typeof obj != 'object') {
					obj = document.forms[this.myForm].elements[this.element + '[]'];
				}
			}
		} else {			
			//Need to define obj as the element. This is called from the onsubmit check function
			var obj = document.forms[this.myForm].elements[this.element];
			if(typeof obj != 'object') {
				obj = document.forms[this.myForm].elements[this.element + '[]'];
			}
		}
		
		
		//return false;
		if(typeof obj != 'object') {			
			// object is not available for validation
			return true;
		}

		try {
			var tr = $$(obj).getParent('tr');		
			if(tr) {
				var disp = tr.getStyle('display');
				if(disp == 'none' || disp == 'hidden' || (obj.name && obj.name == '')) {
					return true;
				}
			} else if($$(obj)) {
				if($$(obj).get('validate') == 'false') {
					
					return true;
				}
			}
		} catch(e) {			
			if($$(obj)) {			
				if($$(obj).get('validate') == 'false') {
					return true;
				}
			}
		}
	
		this.value = obj.value;
		
		if(typeof this.onValidate == 'function') {
			this.onValidate();
		}
		
		if(typeof this.params.enabled == 'undefined' || this.params.enabled) {
			
			if (this.type == 'datetime' || this.type == 'date'){				
				isValid = validateRule.isDateTime(this.myForm, this.divId);
			} else {				
				//Check if any arguments were passed. First arg is the element - onblur, onchange etc. 
	
				
				if (this.validationFunc == 'fieldDependency' || this.validationFunc == 'matchElementValue'){				
					var p  = new RegExp("(\\w+)\\[(\\d)\\]\\[\\w+\\]");
					var matches = this.element.match(p);
					
					var dName = matches[1]+'['+matches[2]+']'+'['+this.params[0]+']';
					var myForm = idE(this.myForm);	
					var isValid = validateRule[this.validationFunc](obj,myForm.elements[dName], this.params, this.type);
					
				} else if (this.validationFunc == 'thisOrThat'){
					var p  = new RegExp("(\\w+)\\[(\\d)\\]\\[\\w+\\]");
					var matches = this.element.match(p);
					var dName = matches[1]+'['+matches[2]+']'+'['+this.params[0]+']';
					var myForm = idE(this.myForm);			
					var isValid = validateRule[this.validationFunc](obj,myForm.elements[dName], this.params, this.type);
						
				} else {
					try { //Catch errors
						var isValid = validateRule[this.validationFunc](obj, this.params, this.type);	
					} catch (e){
					}
				}
			}
		} else {			
			isValid = true
		}
		
		if(this.type == 'textarea' && this.validationFunc == 'isWords') {
			
			var str = stringTools.trim(this.value);
			str = str.replace(/\s+/gi, ' ');
			
			if(str == '') {
				tmpWordLength = 0
			} else {
				tmpWordLength = str.split(' ');	
				tmpWordLength = tmpWordLength.length;
			}
			
			var tmpMinLength = this.params[0];
			var tmpMaxLength = this.params[1];
			var extraWordInfo = '';
			
			if(tmpMinLength > 0) {
				extraWordInfo = ' (minimum '+tmpMinLength+')';
			}
			
			var counterId = this.divId.replace('[', '_');
			counterId = counterId.replace(']', '_');
			counterId = counterId.replace('[', '_');
			counterId = counterId.replace(']', '_');
			
			var wordCounter = $(counterId+'-counter');
			if(!wordCounter) {
				var wordCounter = new Element('div');
				wordCounter.id = counterId+'-counter';
				wordCounter.className = 'textarea-counter';
				wordCounter.setStyles({'width' : parseInt($(counterId).getStyle('width'))+'px'});
				wordCounter.inject($(counterId).getParent(), 'bottom');
			}

			//wordCounter.innerHTML = tmpWordLength+'/'+tmpMaxLength+extraWordInfo;
		}

		if (!isValid){			
			if(typeof this.onValidateFail == 'function') {
				this.onValidateFail();
			}
			if (this.type == 'datetime' || this.type == 'date'){
				var element = document.forms[this.myForm].elements[this.divId+'[Year]'];	
			} else {
				var element = document.forms[this.myForm].elements[this.element];
				if (this.type == 'checkbox') {
					if (!element.length) {
						element = [element];
					}
				}
				if(typeof element != 'object') {
					element = document.forms[this.myForm].elements[this.element + '[]'];
				}
			}
			displayMessage.buildId(element, this.errorMessage, this.type);
		} else {			
			if (typeof this.onValidateSuccess == 'function') {
				this.onValidateSuccess();
			}
			if (this.validationFunc == 'browseableHasValue') {
				var errDiv = this.element + '[]';
				errDiv = errDiv.replace(/\]/gi, '_');
				errDiv = errDiv.replace(/\[/gi, '_');
			} else if (this.type == 'checkbox' || this.type == 'select-multiple'){
				var errDiv = this.element;
			} else {
				var errDiv = this.type == 'date' ? this.divId+'[Day]' : this.divId;	
			}

			// The following code is add for date and datetime type field
			// To remove the error message when validation is pass.
			if (this.type == 'datetime' || this.type == 'date'){
				var element = document.forms[this.myForm].elements[this.divId+'[Year]'];
				displayMessage.flush(element.get('id')+'_msg', element.get('id'));
			} 
	 		displayMessage.flush(errDiv+'_msg', errDiv);
		}
		if(typeof this.onValidated == 'function') {
			this.onValidated();
		}
		/*if(!isValid) {
			alert(this.element);
		}*/
		return isValid;
	}
}

/****************** Validation Event ***********************/
var addValidationEvent = {		
	getValidateFunc: function (vR, validKey){
		//Check if we need a valid key function
		validKey = validKey || false;
		if (validKey){
			return (function (event){if (validateRule.isValidKeyStroke(event)) vR.validate(this);});
		} else {
			return (function (){vR.validate(this);});
		}
	},		
	create: function (vR, element){
		var type = vR.type;		
		if (vR.type == 'radio')	type = 'checkbox'; //Check boxes behaviour 
		if (vR.type == 'date') type = 'datetime';
		if (vR.type == 'select-one' || vR.type == 'select-multiple')	type = 'select';

		switch (type){
			case 'text':
                                if ($chk($(element.id))) {
                                    $(element.id).addEvent('keyup', addValidationEvent.getValidateFunc(vR, true));
                                    //element.onkeyup = addValidationEvent.getValidateFunc(vR, true);
                                    //element.onblur = addValidationEvent.getValidateFunc(vR);
                                    $(element.id).addEvent('blur', addValidationEvent.getValidateFunc(vR));
                                    //EventHandler.attachEvent(element.id, 'onblur','addValidationEvent.getValidateFunc',vR);
                                }
			break;
			case 'textarea':
                            if ($chk($(element.id))) {
                                $(element.id).addEvent('keyup', addValidationEvent.getValidateFunc(vR, true));
				//element.onkeyup = addValidationEvent.getValidateFunc(vR, true);
				//element.onblur = addValidationEvent.getValidateFunc(vR);
                            }
			break;
			case 'select':
				if (vR.validationFunc != 'fieldDependency') {
					vR.validationFunc = 'isSelected';		
				}
				//Check if this element has an on change event already assigned
				EventHandler.attachEvent(element.id, 'onchange','addValidationEvent.getValidateFunc',vR);
			break;
			case 'checkbox':
				//Need to add an onclick to each on of these checkboxes	
				
				if (element.length){
					if (vR.validationFunc != 'fieldDependency'){
						vR.validationFunc = 'isChecked';	
					}
					for (var i=0; i < element.length; i++){
			   			element[i].onclick = function (){							
							vR.validate(element);
		   				}
	   				}
				}
			break;	
			case 'datetime':
					    //get day, month , year and set onChange to validate.
					    var fields = ['[Day]','[Month]','[Year]'];
					    /* CHECK THIS ON SUBMIT INSTEAD
					    for (var i = 0; i < fields.length ; i++){
						    document.forms[vR.formName].elements[vR.divId+fields[i]].onchange = function(){
							    vR.validate(this);
						    }
					    }*/
			break;			
			    }
	},

	remove: function(element) {
		element.onclick = null;
		element.onBlur = null;
		element.onkeyup = null;
	}
}


/******************** Validation Rules *********************/

var validateRule = {
	//Check if the type is a string (anything really). params is an array. 1st is minimum, 2nd is max chars	
	hasValue: function(element , params, type) {
		val = element.value || '';	
		paramList = params || [1];
		return stringTools.check(val, 'string',paramList);
	},
	browseableHasValue: function(element, params, type) {
	    var min = null;
	    var max = null;
	    if (element && element.length > 1) {
		if (params) {
		    if (params.length > 1) {
			min = params[0];
			max = params[1];
		    } else {
			min = params[0];
		    }
		    if (min) {
			if ((element.length - 1) < min) {
			    return false;
			}
		    }
		    if (max) {
			if ((element.length - 1) > max) {
			    return false;
			}
		    }
		}
		return true;
	    } else {
		return false;
	    }
	},
	isUrl: function(element , params, type){
		val = element.value;
		if (val=='') {
			return false;
		}
		return true;
	},
	//Check if the type is a string (anything really). params is an array. 1st is minimum, 2nd is max chars	
	isString: function (element , params, type){	
		val = element.value || '';	
		paramList = params || [];
		if (type == 'textarea' || (element.id && element.id.indexOf('mce_editor') === 0)){
			try {
				var tinyInt = tinyMCE.getInstanceById(element.name);
				
				if(!tinyInt) {
					var tinyInt = tinyMCE.getInstanceById(element.id);
				}
				
				if (tinyInt){				
					val = tinyInt.getBody().innerHTML;
					//Strip tags
					val = val.replace(/<\/?[^>]+>/gi, '');
					val = val.replace(/&([^;]+);/gi, ' ');
					//If the string empty, then set value as empty
					if (val == '<br>' || val == '&nbsp;'){
						val = '';
					}
				}
			} catch (e){
				//alert('line 376');
			}
		}
        return stringTools.check(val, 'string',paramList);		
	},
	isWords: function (element, params, type){
		val = element.value || '';	
		paramList = params || [];
	
		if (type == 'textarea'){
			try {
				var tinyInt = tinyMCE.getInstanceById(element.name);
				
				if(!tinyInt) {
					var tinyInt = tinyMCE.getInstanceById(element.id);
				}
				if (tinyInt){				
					//val = tinyInt.getBody().innerHTML;
					
					var strip = (tinyInt.getBody().innerHTML).replace(/(<([^>]+)>)/ig,"");
					strip = strip.replace('&nbsp;', '');
					var strLength = strip.split(' ').length;
					if(strip.replace(' ', '') == '') {
					    strLength = 0;
					}
					val = strLength;
//
//					//Strip tags
//					//If the string empty, then set value as empty
//					if (val == '<br>' || val == '&nbsp;'){
//						val = '';
//					}
//					val = val.replace(/<[^>]*>/gi, ' ');
//					val = val.replace(/\&nbsp;/gi, ' ');
//					val = val.replace(/\s{1,}/gi, ' ');
//					val = val.replace(/^\s{1,}/gi,'');
//					val = val.replace(/\s{1,}$/gi,'');
//					val = val.split(/\s/gi);
				}
			} catch (e){
				//alert('line 376');
			}
		}
		if (!val) {
			return false;
		}
		min = Number(params[0]) || 1;
		max = Number(params[1]) || 0;
		// minimum words only
		if (max == 0) {
			if (val>=min) {
				return true;
			}
			return false;
		}
		if ((val>=min) && (val<=max)) {
			return true;
		}
		return false;
	},
	fieldDependency : function (element, dependantElement, params, type) {
		// calculate the value of the dependant element
		var dependantValue = '';

		if (dependantElement[0] && dependantElement.tagName != 'SELECT'){
			if (dependantElement[0].type == 'radio'){
				for (var i=0; i < dependantElement.length ; i++){
					if (dependantElement[i].checked){
						dependantValue = dependantElement[i].value;
						break;
					}
				}
			}
		} else {
			dependantValue = dependantElement.value;
		}
		
		var val = '';
		//get element value. it could be a radio
		if (element[0]){
			if (element[0].type == 'radio'){
				for (var i=0; i < element.length ; i++){
					if (element[i].checked){
						val = element[i].value;
						break;
					}
				}
			} else if (type == 'select-one' || type == 'select-multiple') {
				var index = element.selectedIndex;	
				val =  (element.options[index].value == '') ? '' : 'hasValue';				
			}
		} else {
			val = element.value;
		}

		// only execute the validation if the dependacy is met
		if (dependantValue == params[1]){
			//Check dependancy validation
			var validationFunc = params[2];
			if (validationFunc == 'isEmail'){
				var bit = stringTools.trim(val);
				if (bit.search(/^([a-zA-Z0-9_\.\-\+])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/) == -1){
					return false;
				}
			} else if (validationFunc == 'isString') {
				var otherParams = params.slice(3);
				return validateRule.isString(element,otherParams,type);	
			} else if (validationFunc == 'isRegExp') {
				regEx = new RegExp(params[3],"i");
				return regEx.test(val);
			} else if (validationFunc == 'isFile') {
				return val !== '';
			} else {
				return stringTools.check(val, 'string',[1,0]);				
			}
		}
		return true;
	},
	hasValueValidate : function (element, params){
		//First check if this element has any values, if it does then validate it
		var val = element.value || '';	
		var paramList = [1,0];
		
		if (stringTools.check(val, 'string',paramList)){
			//Get Validate Func. 
			if (params[0]){
				var correctParams = params.slice(0);
				var junk = correctParams.shift();
				return validateRule[params[0]](element,correctParams);	
			} else {
				return false;
			}
		} else {
			return true;
		}
	},
	thisOrThat : function (thisElement, thatElement, params) {
		var thisVal = thisElement.value || '';
		var thatVal = thatElement.value || '';
		
		if (!stringTools.check(thisVal, 'string',[1,0]) && !stringTools.check(thatVal, 'string',[1,0]) ){
			return false;			
		}return true;
	},
	// is it alpha only 
	isAlpha: function (element, params){	    
        val = element.value || '';
		paramList = params || [];
		return stringTools.check(val,'alpha',paramList);
	},
	//Check if the type is a string (anything really). params is an array. 1st is minimum, 2nd is max chars	
	mustEqual: function (element , params, type){	
		var val = stringTools.trim(element.value) || '';	
		paramList = params || [];
		if (params.length > 0){
			for (var i = 0; i < params.length; i++){
				if (val == params[i]) return true;
			}
		}
		return false;
	},
	/**
	 * 
	 * @param {Object} element
	 * @param {Object} params
	 */
	isRegExp : function (element,params){
		regEx = new RegExp(params[0],"i");
		return regEx.test(element.value);
	},
	/**
	 * Check that two element values are equal to each other.( used for confirmations )
	 * @param {Object} element
	 * @param {Object} params
	 */
	matchElementValue: function(element, dependantElement, params){
		if (element.value != dependantElement.value)
			return false;
		
		return true;
	},
	/**
	 * Check thats its just a number 
	 * @param {Object} element
	 * @param {Object} params
	 */
	//is it numeric only
	isNumeric: function (element, params){
		val = element.value || '';
		paramList = params || [];
		return stringTools.check(val,'numeric',paramList);
	},
	isUrlOrEmail : function (element, params) {
		if (validateRule.isUrl(element)) {
			return true;
		}
		if (validateRule.isEmail(element)) {
			return true;
		}
		return false;
	},
	/**
	 * Determines if ther integer is valid and within a RANGE
	 * USES is_numeric, instead of is_int
	 * 
	 * @param element form element - the element for the string/int we are testing
	 * @param rangeStart int - the start of the range
	 * @param rangeEnd int - the end of the range
	 * @param inclusive BOOLEAN - inclusive (true) or exclusive (false) of range
	 * @return BOOLEAN
	 */
	isNumRange: function (element, params) {
		var paramList = params || [];
		
		var rangeStart = parseInt(paramList[1]);
		var rangeEnd = parseInt(paramList[2]);
		var inclusive = paramList[3];
		
		
		if(validateRule.isNumeric(element)) {
			var eVal = parseInt(element.value);
			
			if(inclusive) {
				if(eVal >= rangeStart && eVal <= rangeEnd) return true;
			} else {
				if(eVal > rangeStart && eVal < rangeEnd) return true;
			}
		}
		
		return false;
	},

    //Is it a datetime value
    isDateTime: function (myFormArg, ePrefix){
		
		var myForm = idE(myFormArg);
		var MonthDays = new Array(31,28,31,30,31,30,31,31,30,31,30,31);  		
		var day = myForm.elements[ePrefix+'[Day]'].value;
		var month = myForm.elements[ePrefix+'[Month]'].value;
		var year = myForm.elements[ePrefix+'[Year]'].value;		
		dayLimit = MonthDays[month-1];
		if (day > dayLimit)	{
			return false;
		}
		if (day == '' || month == '' || year == '')	{
			return false;
		}
		
		return true;
    },
	
	// is it an email (allow multiple emails comma separated)
	isEmail: function(elementArg){
		var element = idE(elementArg);
		var emailBits = element.value.split(',');
		for (var i=0; i < emailBits.length; i++){
			var bit = stringTools.trim(emailBits[i]);
			if (bit.search(/^([a-zA-Z0-9_\.\-\+])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/) == -1){
				return false;
			}
		}
		return true;
		//return (element.value.search(/^([a-zA-Z0-9_\.\-\+])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/) != -1);
	},
	
	//Is this box checked
	isChecked: function (elementArg){
		
		if (typeof elementArg == 'string'){
			var element = idE(elementArg);			
		} else {
			var element = elementArg;
		}		
		var foundValue = false;
		if (element){
			if (!element.length) {
				if (element.checked) {
					foundValue = true;
				}
			} else {
				for (var i=0; i < element.length; i++){
					if (element[i].checked){
						foundValue = true;
					}
				}
			}
   		}
		return foundValue;
	},
	
	//Selection boxes.		
	isSelected: function (element, params){
		
		if (element.type == 'select-multiple'){
			var index = element.selectedIndex;	
			var selected =  (element.options[index].value == '') ? false : true;	
			
		} else {
			var index = element.selectedIndex;	
			var selected =  (element.options[index].value == '') ? false : true;
			var val = element.options[index].value;
			
			//Check if there are more than 2 params. If there are, the extra ones are values this str cannot equal
			if (params.length > 2){
				for (var i = 2; i < params.length; i++){
					if (val == params[i]) return false;
				}
			}
			var otherId = replaceErrDiv(element.name) + '_other';	
		}
				
		return selected;
	},
	//Clear the other select box 	
	clearOther: function (element){
		otherId = replaceErrDiv(element.name) + '_other';		
		msgId = replaceErrDiv(element.name)+'[other]_msg';
		
		displayMessage.flush(otherId, element.name);
		displayMessage.flush(msgId, element.name);
	},	
	//This determines if its a valid keystroke to initiate validation
	isValidKeyStroke: function(eArg){
		var e = window.event  || eArg;
		try {
			var key = e.keyCode || e.which;
		} catch (e){
			var key = 0;
		}
		
		//var keychar = String.fromCharCode(key);		
		//9 - tab, 8 - backspace, 46 - delete, 27 - escape, 16 shift, 35 - end, 36 home
		if (key == 17 || key == 18 || key == 9 || key == 27 || key ==16 || key == 35 || key == 36){
			return false;
		}
		return true;
	}
}


//Message Display
var displayMessage = {
	overrideBuildFunc: null,
	overrideFlushFunc: null,
	//displays the innerHtml of id with msg
	inId: function (id, msg){
		
        id = replaceErrDiv (id);
		obj = idE(id);
		//set the parent class
		displayMessage.findAndSetParentClass(obj, false, 2);
		if (obj){

			obj.innerHTML = '<div class="formErrorMessage">'+msg+'</div>';
			obj.style.display = "block";
			obj.style.visibility = "";
		}
	},
	//displays the innerHtml of id with msg
	buildId: function (element, msg, type){
		if(!element) {
			return;
		}
		if ($chk(displayMessage.overrideBuildFunc)) {
			return displayMessage.overrideBuildFunc.run([element, msg, type]);
		}
		//set the parent class		
		if (type == 'checkbox' || type == 'radio'){
			var errorid =  replaceErrDiv (element[0].name+'_msg');		
		} else {
			var errorid = replaceErrDiv (element.name+'_msg');		
		}
		errorDiv = document.getElementById(errorid);
		
		if (!errorDiv){
			displayMessage.findAndSetParentClass(element, false, 2);				
			msgElement = document.createElement('div');
			msgElement.setAttribute('id',errorid);
			msgElement.className = 'formErrorMessage';
			msgElement.appendChild(document.createTextNode(msg));

			var parent = null;
			var li = null;
			if (type == 'checkbox' || type == 'radio'){
				//if its a radio or checkbox, attach the message after the last element				
				parent = displayMessage.getParentNode(element[element.length-1]);
				//element[element.length-1].parentNode.appendChild(msgElement);
			} else {
				parent = displayMessage.getParentNode(element);
				//element.parentNode.appendChild(msgElement);
			    
			}
			parent.appendChild(msgElement);
		}
	},
	getParentNode : function(el) {
		// if form is for admin
		var parentNode = el.getParent();
		if (parentNode.get('tag') == 'td') {
			return parentNode;
		}
		var parent = el.getParent('div');
		if ($chk(parent)) {			
			return parent;			
		}
		if ($chk(el.parentNode)) {
			return el.parentNode;
		}else {
			return null;
		}
	},
	//Removes the Id from the document.
	//using parentNode.removeChild
	flush: function (id){
		id = replaceErrDiv(id);
		obj = idE(id);
		
		var elementId = '';
		if (arguments.length > 1) {
			elementId = arguments[1];
		}
		if ($chk(displayMessage.overrideFlushFunc)) {
			return displayMessage.overrideFlushFunc.run(arguments);
		}        
		displayMessage.findAndSetParentClass(obj, true, 2);		
		if (obj){
			obj.parentNode.removeChild(obj);
		}
	},	
	findAndSetParentClass: function (myElement, flushClass,  limit ){
		try {
			var parentObj = displayMessage.getParentNode(myElement);
			var parentClassName = null;
			if ($chk(parentObj)) {
				parentClassName = parentObj.get('class');
			} else {
				parentClassName = myElement.parentNode.className.split(' ');
			}
			
			//See if invalidInputArea class exists
			var newClasses = [];
			
			for (var i = 0; i < parentClassName.length ; i++){
				if (parentClassName[i] != 'invalidInputArea'){
					newClasses.push(parentClassName[i]);		
				}
			}
			if (!flushClass){
				newClasses.push('invalidInputArea');
			}
			if ($chk(parentObj)) {
				parentObj.addClass('invalidInputArea');
			} else {
				myElement.parentNode.className = newClasses.join(' ');
			}
			
		} catch (e){
			//
		}
	}
}

function replaceErrDiv(str){
    var newStr = '';
    for (i = 0; i < str.length; i ++){
        charStr = str.charAt(i);
        if (charStr == '[' || charStr == ']'){
            charStr = '_';
        }
        newStr += charStr;
    }    
    return newStr;
}

function idE(elementId){	
	if (typeof elementId == 'string'){
		var e = document.getElementById(elementId);
	} else {
		var e = elementId;
	}
	return e;
}
function setFieldValue(id, value) {
    $(id).set('value', value);
}
