/*///////////////////////////////////////////////////////////////////////////////////////////////
Alex_validation.js v1.1 - form validation for Alex - by Jason Savage
for use with Alex v1.4 and higher
-------------------------------------------------------------------------------------------------

- Tested in:
	IE5 	= false;
	IE6 	= false;
	IE7 	= true;
	FF1 	= false;
	FF2 	= true;
	Opera8	= true;
	Opera9 	= true;
	NS7 	= true;
	NS8 	= true;
	Safari 	= false;
	
////////////////////////////////////////////////////////////////////////////////////////////////*/

var alex;
if(!alex) alert('Please include the Alex.js file for form validation');
var _vf = new Object();
_vf.version = '1.1';


alex.addValidation = function(formFieldName/*:String*/, formFieldValidationArr/*:Array*/) /*:Void*/{
	//formFieldValidationArr = [{type:'',validation:'',errormessage:''}];
	alex.Walk(formFieldValidationArr, function(ele,indx,arr){
		var Msg = (!alex.Empty(ele.errormessage))? ele.errormessage : '';
		Msg = Msg.replace('{fieldname}', formFieldName);
		
		_vf.validationScheme = alex.Push(_vf.validationScheme, {ID: formFieldName, VALIDATION : ele.validation, TYPE : ele.type, MESSAGE: Msg});
	});

}

alex.validateForm = function()/*:Boolean*/{ 

	//Setup////////////////////////////////////
	_vf.err.clear(); //reset error handler
	_vf.val.clear(); //reset validation handler
	///////////////////////////////////////////

	//registers validationScheme
	_vf.val.register(_vf.validationScheme);
	
	//run validation
	alex.Walk(_vf.val.dataHandler, function(ele,indx,arr){
		
		_vf.val.validate(ele); //creates _vf.err object on false
		
	});
	
	//Check for errors
	var validationFlag = _vf.err.getErrorReport();
	
	if(validationFlag){
		_vf.err.display();
		return false;
	}else{
		//no errors in form then submit
		alert("Thank you!");
		return true;
	}
	
}

//This hold all validation requests (validateForm cycles through this to test if form is valid)
_vf.validationScheme = new Array(); 


////Validation handler////////////////////////////////////////////////////////////////////////////////////////////
_vf.val = { 
		
	dataHandler : new Array(), //ArrayCollection Object - for the val class
	
	register : function(valScheme/*:Array*/) /*:Void*/{
		
		for(i=0; i < valScheme.length; i++){
			var HTMLElement = $O(valScheme[i].ID);
			
			//get real value for special items
			if(valScheme[i].TYPE == 'select'){
				//FF2 did not set type for a select element
				valScheme[i].VALUE = HTMLElement.options[HTMLElement.selectedIndex].getAttribute('value');																						   
			}
			if(valScheme[i].TYPE == 'checkbox'){
				//FF2 set checked to on
				valScheme[i].VALUE = (HTMLElement.checked == true || HTMLElement.checked == 'on')? 'true' : '';
			}
			
			valScheme[i].VALUE = HTMLElement.value;
			if(alex.Empty(valScheme[i].VALUE)) valScheme[i].VALUE = '';	
			
			if(valScheme[i].TYPE != 'radio'){ //use hidden fields for radios
				//alert('Registering ::\n\tID: ' + valScheme[i].ID + '\n\tVALIDATION: '+ valScheme[i].VALIDATION + '\n\tVALUE: '+ valScheme[i].VALUE + '\n\tMESSAGE: '+valScheme[i].MESSAGE);					
				_vf.val.dataHandler = alex.Push(_vf.val.dataHandler, valScheme[i]);
			}
		}
	},
	
	validate : function(validationObject/*:Object*/) /*:void*/{
	
		var valType  = validationObject.VALIDATION;
	
		if( _vf.defs.validators[valType] ){ //is there a definition for this validation type?
				
			//Validate value////////////////////////////////////////////////////
			var result = _vf.defs.validators[valType](validationObject.VALUE); //return true || false
			if(!result){
				_vf.err.register(validationObject);
			}
		}
	},
	
	clear : function() /*:void*/{
		_vf.val.dataHandler = new Array();
	}
		
} //END: val


////Error handler////////////////////////////////////////////////////////////////////////////////////////////
_vf.err = {
	
	dataHandler : new Array(), //ArrayCollection Object - for the err class
	
	register : function(formDataItem/*:Object*/){ 
		_vf.err.dataHandler = alex.Push(_vf.err.dataHandler, formDataItem);
	},
	
	getErrorReport : function(){
		return (_vf.err.dataHandler.length != 0)? true : false;
	},
	
	display : function(){
		alert('Alert!\nErrors were found in the form you submitted.');	
		alex.Walk(_vf.err.dataHandler, function(ele,indx,arr){
			alex.Show(ele.MESSAGE);
		});
			
	},
	clear : function(){
		alex.Walk(_vf.err.dataHandler, function(ele,indx,arr){
			alex.Hide(ele.MESSAGE);
		});
		_vf.err.dataHandler = new Array();
	}
		
} //END: err

////Definitions//////////////////////////////////////////////////////////////////////////////////////////////
_vf.defs = {

	validators : {
		//Note: Only required will return false if empty//
		required : function(value/*:String*/)/*:Boolean*/{
			var value = alex.Trim(value);
			if(alex.Empty(value)) return false; 
			
			//validation code match: empty value
			var currentExp = /^.+$/;
			return currentExp.test(value);
		},
		number : function(value/*:String*/)/*:Boolean*/{
			var value = alex.Trim(value);
			if(alex.Empty(value)) return true; 
			
			//validation code match: (3 | 33 | +3 | -3 | 3.3) but !( 3. | .3 | + | - | 1,3)
			var currentExp = /^[\-\+]?[\d]+([\.]?[\d]+)?$/;
			return currentExp.test(value);
		},
		letter : function(value/*:String*/)/*:Boolean*/{
			var value = alex.Trim(value);
			if(alex.Empty(value)) return true; 
			
			//validation code match: only letters
			var currentExp = /^\D*$/;
			return currentExp.test(value);
		},
		zipcode : function(value/*:String*/)/*:Boolean*/{
			var value = alex.Trim(value);
			if(alex.Empty(value)) return true; 
			
			//validation code match: only letters
			var currentExp = /^\d{5}(-\d{4})?$/;        
			return currentExp.test(value);
		},
		canada_zipcode : function(value/*:String*/)/*:Boolean*/{
			var value = alex.Trim(value);
			if(alex.Empty(value)) return true; 
			
			//validation code match: (X0X-0X0 | X0X 0X0)
			var currentExp = /^[a-zA-Z]\d[a-zA-Z](| |-)\d[a-zA-Z]\d$/;                    
			return currentExp.test(value);
		},
		email : function(value/*:String*/)/*:Boolean*/{
			var value = alex.Trim(value);
			if(alex.Empty(value)) return true; 
			
			//validation code match: (XXXXX@XXX.XXX | XXX.XXX@XXX.XX)
			var currentExp = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
			return currentExp.test(value);
		},
		phone : function(value/*:String*/)/*:Boolean*/{
			var value = alex.Trim(value); 
			if(alex.Empty(value)) return true; 
			
			value = value.replace(/[\(\)\-\s]?/g,'');
			//validation code match: (000-000-0000 | 0000000000)
			var currentExp = /^((\d{10})|(\d{3}\-?\d{3}\-?\d{4}))$/;
			return currentExp.test(value);
		}
	}
} //END: Class defs

//extra - Utilities/////////////////////////////////////////////////////////////////////////////////////////////////////

alex.Push = function(arr/*:Array*/, str/*:String*/)/*:Array*/{
	if(!alex.Is.array(arr)) return [];
	arr[arr.length] = str;
	return arr;
}
alex.Show = function(id/*:String*/)/*:Void*/{
	if($O(id)) $O(id).style.display = 'block';
}
alex.Hide = function(id/*:String*/)/*:Void*/{
	if($O(id)) $O(id).style.display = 'none';
}


