//FUNCTION: isNumberKey(event evt)
//
//Attach to keypress event to allow only numeric entries
// <TAG onkeypress="return isNumberKey(event)"></TAG>
function isNumberKey(evt)
{
 var charCode = (evt.which) ? evt.which : event.keyCode
 if (charCode > 31 && (charCode < 48 || charCode > 57))
    return false;

 return true;
}

/*
 * **********************************************************
 * Validation
 * **********************************************************
*/
var	RULE_REQUIRED 	        = 1;
var RULE_REGEX		        = 2;
var RULE_COMPARE	        = 3;
var RULE_NUMERIC_MIN        = 4;
var RULE_CUSTOM_FN          = 5;

var REGEX_ZIPCODE           = /^\d{5}([\-]\d{4})?$/;
var REGEX_EMAIL             = /^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i ;
var REGEX_PHONE             = /^(\+\d)*\s*(\(\d{3}\)\s*)*\d{3}(-{0,1}|\s{0,1})\d{2}(-{0,1}|\s{0,1})\d{2}$/;
var REGEX_PHONE_DASH_ONLY   = /^\d{3}\-\d{3}\-\d{4}$/;
var REGEX_DATE	            = /^(?=\d)(?:(?:(?:(?:(?:0?[13578]|1[02])(\/|-|\.)31)\1|(?:(?:0?[1,3-9]|1[0-2])(\/|-|\.)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})|(?:0?2(\/|-|\.)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))|(?:(?:0?[1-9])|(?:1[0-2]))(\/|-|\.)(?:0?[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2}))($|\ (?=\d)))?(((0?[1-9]|1[012])(:[0-5]\d){0,2}(\ [AP]M))|([01]\d|2[0-3])(:[0-5]\d){1,2})?$/;

var REGEX_CC_ALL            = /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/;
var REGEX_CC_VISA           = /^4[0-9]{12}(?:[0-9]{3})?$/;
var REGEX_CC_MC             = /^5[1-5][0-9]{14}$/;
var REGEX_CC_AMEX           = /^3[47][0-9]{13}$/;
var REGEX_CC_DINERS         = /^3(?:0[0-5]|[68][0-9])[0-9]{11}$/;
var REGEX_CC_DISCOVER       = /^6(?:011|5[0-9]{2})[0-9]{12}$/;
var REGEX_CC_JCB            = /^(?:2131|1800|35\d{3})\d{11}$/;


/*	
	***************************************************
	*ValidationRule
	***************************************************
*/
ValidationRule.prototype 				= new Object();
ValidationRule.prototype.elementId 		= null;
ValidationRule.prototype.type			= null;
ValidationRule.prototype.errorMessage 	= null;
ValidationRule.prototype.data			= null;
ValidationRule.prototype.errorMessageElementId = null;
ValidationRule.prototype.validationMethod = null;
ValidationRule.prototype.getElement 	= function()
	{
		return document.getElementById( this.elementId );
	};
ValidationRule.prototype.getErrorMessageElement = function()
    {
        return document.getElementById( this.errorMessageElementId );
    };
ValidationRule.prototype.isValid 		= function()
	{
		var ele = this.getElement();
		var valid = false;
		
		if( ele )
		{
			switch( ele.tagName )
			{
				case 'INPUT':
					
					switch( ele.type.toLowerCase() )
					{
						case 'text':
						case 'password':
						case 'hidden':
						case 'checkbox':
							valid = true;
							break;
					}
					break;
					
				case 'TEXTAREA':
					valid = true;
					break;
			}
		}
		
		return valid;
	};
	
ValidationRule.prototype.getValue       = function()
    {
        if( !this.isValid() )
            return;
            
        var ele     = this.getElement();
        var value;
        
        switch( ele.tagName )
        {
            case 'INPUT':
				switch( ele.type.toLowerCase() )
				{
					case 'text':
					case 'password':
					case 'hidden':
					    value = ele.value;
					    break;
					    
					case 'checkbox':
                        value = ele.checked ? 'true' : '';
                        break;
				}
				break;
				
            case 'TEXTAREA':
                value = ele.value;
                break;
        }
        
        return value;
    };
	
function ValidationRule( eleId, ruleType, errMsg, data, errMsgEleId )
	{
		this.elementId = eleId;
		this.type = ruleType;
		this.errorMessage = errMsg;
		this.data = data;
		this.errorMessageElementId = errMsgEleId;
	}
	
/*	
	***************************************************
	*Validator
	***************************************************
*/
Validator.prototype						= new Object();
Validator.prototype.rules 				= null;
Validator.prototype.errors              = null;
Validator.prototype.containerId			= null;
Validator.prototype.listId				= null;
Validator.prototype.cssError			= null;
Validator.prototype.cssErrorElement		= null;
Validator.prototype.validateRule		= function(rule)
	{

		if( !rule )
			return true;
			
		var isValid = true;	
		var evaluated = true;
		
		if( rule.isValid() )
		{
			var ele = rule.getElement();
			var eleErrMsg = rule.getErrorMessageElement();
			var value = rule.getValue();
			
			
			switch( rule.type )
			{
				case RULE_REQUIRED:
					isValid = ( value.length > 0 );
					break;
					
				case RULE_REGEX:
				    if( ele.value.length > 0 )
				    {
					    isValid = ( value.match( rule.data ) );
					}
					else
					{
					    evaluated = false;
					}   
					break;
					
				case RULE_COMPARE:
					var otherControl = document.getElementById( rule.data );
					isValid = ( otherControl.value.toLowerCase() == value.toLowerCase() );
					break;
				
				case RULE_NUMERIC_MIN:
				    var number  = parseInt( value );
				    var min     = parseInt( rule.data );
				    
				    isValid = ( number > min );
				    break;
				case RULE_CUSTOM_FN:
				    isValid = ( rule.validationMethod(value) == true);
				    break;
			}
		
			if( evaluated )
			{
			    ele.className = isValid ? '' : this.cssErrorElement;
			    
			    if( eleErrMsg )
			        eleErrMsg.innerHTML = isValid ? '' : rule.errorMessage;
			}
		}
		
		return isValid;
	};
Validator.prototype.validate	= function()
	{
		if( !this.rules )
			return true;
			
		var errors = new Array();
		
		var divContainer	= document.getElementById( this.containerId );
		var ul				= document.getElementById( this.listId );
		var hasErrors		= false;
		
			
		//hide error container
		
		if( divContainer)
		{
		    divContainer.style.display 	= 'none';
		    divContainer.className 		= '';
		}
		
		//clear children		
		if( ul )
		    ul.innerHTML = '';

		
		
		for( i = 0; i < this.rules.length; i++)
		{
			var rule = this.rules[i];
			if( !this.validateRule( rule ) )
			{
			    //save rule that errored out
			    errors.push( rule );
			    
			    if( ul )
			    {
				    var li = document.createElement('li');
				    li.innerHTML = rule.errorMessage;				
				    ul.appendChild( li );
                }
                
				hasErrors = true;
			}
		}
		
		//show error container
		if( divContainer &&  hasErrors )
		{
			divContainer.className		= this.cssError;		
			divContainer.style.display 	= 'block';
		}
		
		//save errors to class
		this.errors = errors;
		
		return !hasErrors;
	};
function Validator( container, list , cssContainer, cssElement )
	{
		this.rules 				= new Array();
		this.cssError 			= cssContainer;
		this.cssErrorElement	= cssElement;
		this.containerId		= container;
		this.listId				= list;
		
	}
	

/*
 * The following class returns information about errors back to the server
 */
ValidationReporting.prototype = new Object();
ValidationReporting.prototype.destinationUrl = null;
ValidationReporting.prototype.sourceName     = null;
ValidationReporting.prototype.additionalParameters = null;
ValidationReporting.prototype.elementId = null;
ValidationReporting.prototype.parentId  = null;
ValidationReporting.prototype.errors    = null;
ValidationReporting.prototype.element = function()
    {
        return document.getElementById( this.elementId );
    };
    
ValidationReporting.prototype.parent    = function()
    {
        return document.getElementById( this.parentId );
    };
ValidationReporting.prototype.elementExists = function()
    {
        if( this.element() && this.parent() )
        {   
            return true;
        }
        else
        {
            return false;
        }
    };
ValidationReporting.prototype.url = function()
    {
        var baseUrl = this.destinationUrl;
         
        return baseUrl + '?' + this.getParameters();
    };

ValidationReporting.prototype.getParameters = function()  
    {
        var params = 'Source=' + this.sourceName;
        
        for( i = 0; i < this.errors.length; i++ )
        {
            var rule = this.errors[i];
            
            params = params + '&' + rule.elementId + '=' + escape(rule.errorMessage);
        }
        
        //add any custom additional parameters
        if( this.additionalParameters )
            params+= '&' + this.additionalParameters;
            
        return params;
    };
    
ValidationReporting.prototype.reportError = function ()
    {
        var image = this.element();
        
        if( image  )
        {
            if( this.parent() )
            {
                this.parent().removeChild( image );
            }
        }
        
        image = document.createElement('img');
        image.id = this.elementId;
        
        if( this.parent() )
        {
            this.parent().appendChild( image );
        }

        
        var url = this.url();
        image.src = this.url();
    };
    
function ValidationReporting( parentId, elementId, destinationUrl, sourceName )
{
    this.parentId = parentId;
    this.elementId = elementId;
    this.destinationUrl = destinationUrl;
    this.sourceName = sourceName;
}


