﻿/* ____________________________________________________________________________
 *
 * VALIDATION.JS
 * ____________________________________________________________________________
 * Purpose:
 *  Provides input validation functions.
 *
 * Author:
 *  Chris Martinez
 *
 * Last Modified:
 *  01/31/2007 - created.
*/

// ____________________________________________________________________________
//
// Trims leading and trailing characters
// ____________________________________________________________________________
String.prototype.trim = function( trimChars )
{
	var regex;
	
	if ( trimChars == null || typeof( trimChars ) == "undefined" ||
		( typeof( trimChars ) == "string" && trimChars.length == 0 ) )
	{	
		// capture everything except leading and trailing whitespace
		return this.replace( /^\s*(\S+(.+\S+)?)\s*$/, "$1" );
	}
	else if ( typeof( trimChars ) == "object" && trimChars.constructor == Array )
	{
		// build string
		var chars = "";
		
		for ( var i = 0; i < trimChars.length; i++ )
		    chars += trimChars[i];
		
		trimChars = chars;
	}
	
	if ( typeof( trimChars ) == "string" )
	{
		// escape characters that have special meaning in regular expressions
		trimChars = trimChars.replace( /([\.\$\^\{\[\(\|\)\*\+\?\\\/])/, "\\$1" );
		trimChars = trimChars.replace( /\n/, "\\n" );
		trimChars = trimChars.replace( /\r/, "\\r" );
		trimChars = trimChars.replace( /\t/, "\\t" );
		
		// capture everything except leading and trailing specified characters
		regex = new RegExp( "^[" + trimChars + "]*([^" + trimChars + "]*)[" + trimChars + "]*$" );
		
		// return replacement
		return this.replace( regex, "$1" );
	}
	
	// return original (if not replaced)
	return this;
}

// ____________________________________________________________________________
//
// Determines if a string ends with the specified string
// ____________________________________________________________________________
String.prototype.endsWith = function( value )
{
	// exit if there is nothing to do
	if ( value == null || typeof( value ) != "string" || value.length == 0 )
	    return false;
	
	// test this string against the value passed
	var regex = new RegExp( value + "$" );
	var result = regex.test( this );
	
	// destroy object
	regex = null;
	
	return result;
}

// ____________________________________________________________________________
//
// Locates the first control in the document matching the id and tag name
// ____________________________________________________________________________
function FindControl( id, tag )
{
    // find controls
    var controls = window.document.body.getElementsByTagName( tag );
    
    if ( controls == null )
        return null;
    
    // find the first match
    for ( var i = 0; i < controls.length; i++ )
    {
        var control = controls[i];
        
        if ( control.id.endsWith( id ) )
            return control;
    }
    
    return null;
}

// ____________________________________________________________________________
//
// Removes mask formatting when the input focus is received
// ____________________________________________________________________________
function MaskRemove( input, maxLen )
{
    input.value = input.value.replace( /[^\d]/g, "" );
    input.maxLength = maxLen;
    input.select();
    return true;
}

// ____________________________________________________________________________
//
// Validates and formats user input when the input focus is lost
// ____________________________________________________________________________
function MaskZip( input )
{
    var len = input.value.length;
    var valid = ( len == 0 );
    
    switch ( len )
    {
        case 5 :
        case 9 :
        {
            var regex = /\d{5,9}/;
            valid = regex.test( input.value );
            regex = null;
        }
    }
    
    if ( valid == true && len == 9 )
    {
        input.maxLength = 10;
        input.value = input.value.replace( /(\d{5})(\d{4})/, "$1-$2" );
    }

    return true;
}

// ____________________________________________________________________________
//
// Validates and formats user input when the input focus is lost
// ____________________________________________________________________________
function MaskPhone( input )
{
    var len = input.value.length;
    var valid = ( len == 0 );
    
    switch ( len )
    {
        case 7 :
        case 10 :
        case 11 :
        {
            var regex = /\d{7,10}/;
            valid = regex.test( input.value );
            regex = null;
        }
    }
    
    if ( valid == true )
    {
        input.maxLength = 14;
        
        if ( len == 7 )
            input.value = input.value.replace( /\d?(\d{3})(\d{4})/, "(916) $1-$2" );
        else if ( len == 10 || len == 11 )
            input.value = input.value.replace( /(\d?)(\d{3})(\d{3})(\d{4})/, "($2) $3-$4" );
    }

    return true;
}

// ____________________________________________________________________________
//
// Returns whether the specified key code is valid user input
// ____________________________________________________________________________
function IsValidInput( keyCode, shift )
{
    switch ( keyCode )
    {
        case 8  :   // BACKSPACE
        case 9  :   // TAB
        case 35 :   // END
        case 36 :   // HOME
        case 37 :   // LEFT
        case 38 :   // UP
        case 39 :   // RIGHT
        case 40 :   // DOWN
        case 46 :   // DELETE
        {
            return true;
        }
    }
    
    if ( shift == false )
    {
        if ( keyCode > 47 && keyCode < 58 )         // KEY0-KEY9
            return true;
        else if ( keyCode > 95 && keyCode < 106 )   // NUM0-NUM9
            return true;
    }
        
    return false;
}

// ____________________________________________________________________________
//
// Validates numeric user input
// ____________________________________________________________________________
function NumericKeyDown( e )
{    
   var allowed = IsValidInput( e.keyCode, e.shiftKey );
    
    e.returnValue = allowed;
    return allowed;
}

// ____________________________________________________________________________
//
// Resets the brochure input
// ____________________________________________________________________________
function ResetBrochure()
{
    var control = null;
    
    FindControl( "txtFirstName", "input" ).parentNode.previousSibling.style.color = "black";
    FindControl( "txtLastName", "input" ).parentNode.previousSibling.style.color = "black";
    FindControl( "txtAddress", "input" ).parentNode.previousSibling.style.color = "black";
    FindControl( "txtCity", "input" ).parentNode.previousSibling.style.color = "black";
    FindControl( "txtZip", "input" ).parentNode.previousSibling.style.color = "black";
    FindControl( "txtPhone", "input" ).parentNode.previousSibling.style.color = "black";
}

// ____________________________________________________________________________
//
// Validates the brochure input
// ____________________________________________________________________________
function ValidateBrochure( input )
{
    var invalid = 0;
    var control = null;
    var label = null;
    
    control = FindControl( "txtFirstName", "input" );
    label = control.parentNode.parentNode.cells[0];
    if ( control.value.trim().length == 0 )
    {
        ++invalid;
        label.style.color = "red";
    }
    else
        label.style.color = "black";
        
    control = FindControl( "txtLastName", "input" );
    label = control.parentNode.parentNode.cells[0];
    if ( control.value.trim().length == 0 )
    {
        ++invalid;
        label.style.color = "red";
    }
    else
        label.style.color = "black";
        
    control = FindControl( "txtAddress", "input" );
    label = control.parentNode.parentNode.cells[0];
    if ( control.value.trim().length == 0 )
    {
        ++invalid;
        label.style.color = "red";
    }
    else
        label.style.color = "black";
        
    control = FindControl( "txtCity", "input" );
    label = control.parentNode.parentNode.cells[0];
    if ( control.value.trim().length == 0 )
    {
        ++invalid;
        label.style.color = "red";
    }
    else
        label.style.color = "black";
        
    control = FindControl( "txtZip", "input" );
    label = control.parentNode.parentNode.cells[0];
    if ( control.value.trim().length == 0 )
    {
        ++invalid;
        label.style.color = "red";
    }
    else
        label.style.color = "black";
        
    if ( invalid > 0 )
    {
        alert( "Please enter the required fields in marked in red." );
        return false;
    }
    
    return true;
}

// ____________________________________________________________________________
//
// Validates the enrollment order input
// ____________________________________________________________________________
function ValidateOrder( input, step )
{
    var invalid = 0;
    var control = null;
    var label = null;
    var message = null;
    
    switch ( step )
    {
        case 1 :
        {
            control = FindControl( "txtFirstName", "input" );
            label = control.parentNode.parentNode.cells[0];
            if ( control.value.trim().length == 0 )
            {
                ++invalid;
                label.style.color = "red";
            }
            else
                label.style.color = "black";
                
            control = FindControl( "txtLastName", "input" );
            label = control.parentNode.parentNode.cells[0];
            if ( control.value.trim().length == 0 )
            {
                ++invalid;
                label.style.color = "red";
            }
            else
                label.style.color = "black";
                
            control = FindControl( "txtAddress", "input" );
            label = control.parentNode.parentNode.cells[0];
            if ( control.value.trim().length == 0 )
            {
                ++invalid;
                label.style.color = "red";
            }
            else
                label.style.color = "black";
                
            control = FindControl( "txtCity", "input" );
            label = control.parentNode.parentNode.cells[0];
            if ( control.value.trim().length == 0 )
            {
                ++invalid;
                label.style.color = "red";
            }
            else
                label.style.color = "black";
                
            control = FindControl( "txtZip", "input" );
            label = control.parentNode.parentNode.cells[0];
            if ( control.value.trim().length == 0 )
            {
                ++invalid;
                label.style.color = "red";
            }
            else
                label.style.color = "black";
                
            control = FindControl( "ddlClassification", "select" );
            label = control.parentNode;
            if ( control.selectedIndex == 0 )
            {
                ++invalid;
                label.style.color = "red";
            }
            else
                label.style.color = "black";
                
            if ( invalid > 0 )
            {
                alert( "Please enter the required fields in marked in red." );
                return false;
            }
            break;
        }
        case 2 :
        {
            var today = new Date();
            var month = 0;
            var year = 0;
            var cardName = null;
            
            control = FindControl( "txtCardholder", "input" );
            label = control.parentNode.parentNode.cells[0];
            if ( control.value.trim().length == 0 )
            {
                ++invalid;
                label.style.color = "red";
            }
            else
                label.style.color = "black";
            
            control = FindControl( "ddlCreditCard", "select" );
            label = control.parentNode.parentNode.cells[0];
            if ( control.selectedIndex == 0 )
            {
                ++invalid;
                label.style.color = "red";
            }
            else
            {
                label.style.color = "black";
                cardName = control.options[control.selectedIndex].value;
            }

            control = FindControl( "txtCreditCard", "input" );
            label = control.parentNode.parentNode.cells[0];
            if ( ( message = ValidateCreditCard( cardName, control.value.trim() ) ) != null )
            {
                ++invalid;
                label.style.color = "red";
            }
            else
                label.style.color = "black";
                
            control = FindControl( "ddlMonth", "select" );
            label = control.parentNode.parentNode.cells[0];
            if ( control.selectedIndex == 0 )
            {
                ++invalid;
                label.style.color = "red";
            }
            else
            {
                label.style.color = "black";
                month = control.selectedIndex;
            }
                
            control = FindControl( "ddlYear", "select" );
            year = parseInt( control.options[control.selectedIndex].value );

            // make sure the card hasn't expired
            if ( year < today.getFullYear() || ( year == today.getFullYear() && month < today.getMonth() ) )
            {
                ++invalid;
                message = "The expiration date entered indicates the specified credit card has expired.";
                FindControl( "ddlMonth", "select" ).parentNode.parentNode.cells[0].style.color = "red";
            }
                
            break;
        }
    }
    
    // display error message
    if ( invalid > 0 )
    {
        if ( message == null )
            message = "Please enter the required fields in marked in red.";
            
        alert( message );
        return false;
    }
    
    return true;
}