﻿// JScript File

function ValidationScriptVersion()
{
    return "1.0";
}

var pageValidations = new Array();
function validatePage()
{
    var alertStr = "";
    for(index = 0; index < pageValidations.length; index++)
    {
        var validation = pageValidations[index];
        if(!IsValidPattern($F(validation.controlToValidate),validation.regularExpression))
        {
            alertStr += validation.errorString + "\n";
        }
    }
    if(alertStr.length > 0)
    {
        alert(alertStr);
        return false;
    }
    else
    {
        return true;
    }
}

function pageValidation(ctl, regex, errorStr)
{
    this.controlToValidate = ctl;
    this.regularExpression = regex;
    this.errorString = errorStr;
}

function addPageValidation(ctl, regex, errorStr,indication)
{
    // check for duplicates before adding
    for(var x=0;x<pageValidations.length;x++){
        if(pageValidations[x].controlToValidate == ctl){
            return;
        }
    }
    if(indication && $(ctl) != null){
//        var indDiv = new Element("SPAN", {"id": "indiciation_" + $(ctl).id});
//        $(ctl).insert({before: indDiv});
//        
//        indDiv.setStyle({"border": "solid 1px red", "backgroundColor": "red"});
//        indDiv.clonePosition($(ctl));
//        
//        var clonedCtrl = $(ctl).cloneNode(1);
//        
//        ctl = $(clonedCtrl).id;
//        indDiv.insert({top: $(ctl)});
        //        $(ctl).setOpacity(1);      
        $(ctl).setStyle({border: "1px solid red"});  
    }
    var pv = new pageValidation(ctl,regex,errorStr);
    pageValidations[pageValidations.length] = pv;
}

function addIndication(ctl, backgroundColor) {
    if (backgroundColor == null || backgroundColor.length == 0) {
        backgroundColor = "red";
    }
    $(ctl).setStyle({ border: "1px solid " + backgroundColor });        
}

function clearPageValidation()
{
    pageValidations = null;
    pageValidations = new Array();
}

//********************
//  GroupValidation Start
var validationGroups = new Hash();

/**
* Adds an input control to a group validation.  
* @param {string} ctl: Element, or ElementID
* @param {string} regex: the Regular Expression used to validate the input
* @param {string} errorStr: The full string that will be used to indicate that this control does not have a valid value
* @param {boolean} indication: Use a red border around the control to indicate that it is required
* @param {string} groupName: The name of the validation group
* @public
*/
function addGroupValidation(ctl, regex, errorStr, indication, groupName) {
    var validations = new Array();
    if (validationGroups.keys().indexOf(groupName) > -1) {
        validations = validationGroups.get(groupName);
    }
    else {
        validationGroups.set(groupName, validations);
    }
    
    for (var x = 0; x < validations.length; x++) {
        if (validations[x].controlToValidate == ctl) {
            return;
        }
    }
    if (indication && $(ctl) != null) {
        addIndication(ctl, "red");
    }
    var pv = new pageValidation($(ctl), regex, errorStr);
    validations[validations.length] = pv;
}

/**
* Adds an input control to a group validation.  Creates the validation group if one doesn't exist for the given group name
* This method is a convenient wrapper for the addGroupValidation function which offers more control of the validation logic.
* Call validateGroup to invoke validation logic.
* @param {string} ctlId: Element, or ElementID
* @param {string} ctlName: Friendly Name.  This is used to create the validation failure message
* @param {string} groupName: Name of the validation group
* @private
*/
function addSimpleGroupValidation(ctlId, ctlName, groupName) {
    addGroupValidation(protoda.$SID(ctlId), '.+','"' + ctlName + '" is required', true, groupName);
}

function clearGroupValidations(_groupName) {
    if (validationGroups.keys().indexOf(_groupName) > -1) {
        var validations = validationGroups.get(_groupName);
        for (var x = 0; x < validations.length; x++) {
            if ($("indication_" + validations[x].controlToValidate.id)) {
                var indication = $("indication_" + validations[x].controlToValidate.id);
                indication.up(0).insert({ top: $(validations[x].controlToValidate) });
                indication.remove();
            }
        }
        validationGroups.unset(_groupName);
    }
}

/**
* Validates all fields in a specific validation group. 
* @param {string} _groupName: Name of the validation group
* @param {boolean} _showAlert (optional): Prompt user of invalid fields.  Defaults to true
* @public
*/
function validateGroup(_groupName,_showAlert) {
    var alertStr = "";
    var validations = null;
    
    // get the validation group
    if (validationGroups.keys().indexOf(_groupName) > -1) {
        validations = validationGroups.get(_groupName);
    }
    else {
        return true;
    }
    
    
    for (index = 0; index < validations.length; index++) {
        var validation = validations[index];
        if (!IsValidPattern($F(validation.controlToValidate), validation.regularExpression)) {
            alertStr += unescape(validation.errorString).replace(/\&quot\;/g, '"') + "\n";
        }
    }
    if (alertStr.length > 0) {
        if (_showAlert == null || _showAlert == true) {
            alert(alertStr);
        }
        return false;
    }
    else {
        return true;
    }
}

//      End GroupValidation
//**********************


// Perform RegularExpression Validation
function IsValidPattern(_string,_pattern)
{
    //alert("string " + _string + "\npattern " + _pattern);
    var reg = new RegExp(_pattern);
    
    if(reg.exec(trim(_string)))
    {
        return true;
    }
    else 
    {
        return false;
    } 
}

function validateDouble(sender, e)
{
    e = ensureEvent(e);
    var odaKeyCode = new ODAKeyCode(e);
    
    if(odaKeyCode.IsNumber)
    {
        insertAtCursor(sender,odaKeyCode.keyCodeValue);
    }
    else if(odaKeyCode.keyCodeValue == '-' && new Selection(sender).create().start == 0 && $F(sender).indexOf('-') == -1)
    {
        insertAtCursor(sender, odaKeyCode.keyCodeValue);
    }
    else if(odaKeyCode.keyCodeValue == "." && sender.value.indexOf('.') == -1) // handle the decimal point
    {
        insertAtCursor(sender,'.');
    }
    else if(isAllowedSpecialChar(odaKeyCode))
    {
        return true;
    }
    //event.returnValue = false;
    Event.stop(e);
}

function isAllowedSpecialChar(odaKeyCode)
{
    if(odaKeyCode.keyCodeValue == odaKeyCode.BACKSPACE ||
        odaKeyCode.keyCodeValue == odaKeyCode.LEFT_ARROW ||
        odaKeyCode.keyCodeValue == odaKeyCode.UP_ARROW ||
        odaKeyCode.keyCodeValue == odaKeyCode.RIGHT_ARROW ||
        odaKeyCode.keyCodeValue == odaKeyCode.DOWN_ARROW ||
        odaKeyCode.keyCodeValue == odaKeyCode.DELETE ||
        odaKeyCode.keyCodeValue == odaKeyCode.END ||
        odaKeyCode.keyCodeValue == odaKeyCode.HOME ||
        odaKeyCode.keyCodeValue == odaKeyCode.TAB ||
        odaKeyCode._controlKey ||
        odaKeyCode._altKey)
    {
        return true;
    }
    return false;
}

function validateBlurHandler(sender,clientID,mask,_mode)
{
    //setMask(sender,mask);
    if(_mode == DateValidationModes.Time){
        validateTimeBlur(sender,mask,'if(typeof ' + clientID + 'ServerTextboxCallback == "function"){' + clientID + 'ServerTextboxCallback(\'DateTimeAnswerTEXTBOXAJAXDELIMITER' + sender.id + ',' + sender.value + '\',\'' + mask + '\',null);}',_mode);
    }
    else{
        validateDateTimeBlur(sender,mask,'if(typeof ' + clientID + 'ServerTextboxCallback == "function"){' + clientID + 'ServerTextboxCallback(\'DateTimeAnswerTEXTBOXAJAXDELIMITER' + sender.id + ',' + sender.value + '\',\'' + mask + '\',null);}',_mode);
    }
}

function validateTimeBlur(sender, mask, serverFunction, _mode){
    if(sender.value == mask)
    { return false; }
    
    if(sender.value.replace(/ /g) == '')
    {
        sender.value = '';
        setMask(sender,mask);
        return false;
    }
    
    // if the new date isn't valid, then the old date for sure isn't valid
    // so lets bail out and have them start over.
    if(!IsValidDate(trim($F(sender)),_mode))
    {
        alert('The time ' + $F(sender) + ' is not a valid time.');
        sender.value = '';
        setMask(sender,mask);
        return false; 
    }
    
    eval(serverFunction);
    
    return IsValidDate($F(sender), _mode);
}

//DateTime Modes
// Mode: 1
//      Date with optional time
// Mode: 2
//      Date with required time
// Mode: 3
//      Date without time

function validateDateTimeBlur(sender,mask,serverFunction, _mode)
{
    if(sender.value == mask)
    { return false; }
    
    if(sender.value.replace(/ /g) == '')
    {
        sender.value = '';
        setMask(sender,mask);
        return false;
    }
    
    var sections = sender.value.split(' ');
    var parts = sections[0].split('/');
    var oldVal = sender.value;
    
    // slashcount==2 so we know that parts[0] and parts[1] are 2 in length
    if(parts.length != 3)
    {
        sender.value = '';
        setMask(sender,mask);
        return false;
    }
    
    while(parts[0].length < 2)
    {parts[0] = '0' + parts[0];}
    
    while(parts[1].length < 2)
    {parts[1] = '0' + parts[1];}
    
    if(parts[2].length == 2 && IsValidPattern(parts[2],'^[0-9]+$'))
    {
        if((+parts[2]) > 49)
        {
            parts[2] = '19' + parts[2];
        }
        else
        {
            parts[2] = new Date().getFullYear().toString().substring(0,2) + parts[2];
        }
    }
    else if(parts[2].length == 0)
    {parts[2] = new Date().getFullYear();}
    
    sections[0] = parts[0] + '/' + parts[1] + '/' + parts[2];
    
    var newDate = '';
    for(var j=0; j<sections.length; j++)
    {
        if(j==0)
        {
            newDate = sections[j];
        }
        else
        {
            newDate += ' ' + sections[j];
        }
    }
    
    // if the new date isn't valid, then the old date for sure isn't valid
    // so lets bail out and have them start over.
    if(!IsValidDate(trim(newDate),_mode))
    {
        alert('The date ' + oldVal + ' is not a correct date.');
        sender.value = '';
        setMask(sender,mask);
        return false; 
    }
    // the new value is valid, see if the user wants to swap them out.
    if(oldVal != newDate)
    {
        sender.value = newDate;
    }
    
    eval(serverFunction);
}

function trim(string)
{
    if(string == '')
    {return string;}
    
    var result = string;
    while(result.length > 0 && result.charAt(0) == ' ')
    {
        result = result.substring(1,string.length);
    }
    
    while(result.length > 0 && result.charAt(result.length-1) == ' ')
    {
        result = result.substring(0,result.length-1);
    }
    
    return result;
}

function validateTimeKeyDown(sender, _mode, e){
        e = ensureEvent(e);
    var odaKeyCode = new ODAKeyCode(e);
    
    if(odaKeyCode.keyCode == odaKeyCode.DELETE) // delete
    {   
        var nextChar = getNextChar(sender);
        if(nextChar == '/' || nextChar == ':' || nextChar == ' ')
        {
            MoveCursor(sender,1);
            
            Event.stop(e);
            return;
        }
        else if(nextChar == 'A' || nextChar == 'P')
        {
            sender.value = sender.value.substring(0, sender.value.length-3);
            //event.returnValue = false;
            Event.stop(e);
            return;
        }
        else if(nextChar == '')
        {
            //event.returnValue = false;
            Event.stop(e);
            return;
        }
        
        if(getCursorPosition(sender) < 9)
        {
            dateTimeDeleteKey(sender);
            MoveCursor(sender,1);
        }
        
        //event.returnValue = false;
        Event.stop(e);
    }
    else if(odaKeyCode.keyCode == odaKeyCode.SPACE) // space bar
    {

        //event.returnValue = false;
        Event.stop(e);
        
        // split on ':'
        // if the length there is 1 then make sure that the length of 1 is 2 then add a :
        // if the length is 2 then make sure that position 2 is 2 in length then add a space
        
        var sections = sender.value.split(' ');
        var timepart = sections[0].split(':');
        
        if(timepart.length == 1)
        {
            if(timepart[0].length == 1)
            {
                sections[1] = '0' + timepart[0] + ':';
            }
            else if(timepart[0].length == 2)
            {
                sections[1] += ':';
            }
        }
        else if(timepart.length == 2)
        {
            if(timepart[1].length == 1)
            {
                sections[1] = timepart[0] + ':0' + timepart[1];
            }
            else if(timepart[1].length == 2)
            {
                sections[1] += ' ';
            }
        }
        
        for(var j=0; j<sections.length; j++)
        {
            if(j==0)
            {
                sender.value = sections[j];
            }
            else
            {
                sender.value += ' ' + sections[j];
            }
        }
        
        
        if(getCharCount(sender.value,' ') < 2 && 
        (
        getCursorPosition(sender) == 10 ||
        getCursorPosition(sender) == 16
        ))
        {
            
            insertAtCursor(sender,odaKeyCode.keyCodeValue);
        }
        
        return;
        
    }    
    
    // datetime consists of three sections
    // sections one and two are 1-2 characters long
    // section three is 2 or 4 characters long
 
    if(odaKeyCode.IsNumber)
    {
        if(sender.value.length >= 9)
        {deleteAtCursor(sender);}
        var oldVal = sender.value;
        
        insertAtCursor(sender,odaKeyCode.keyCodeValue);
        dateTimeParts = sender.value.split(' ');
        
        
        if(dateTimeParts.length >= 1)
        {
            parts = dateTimeParts[0].split(':');
            if(parts.length > 0)
            {
                if(parts[0].length > 2)
                {
                    sender.value = oldVal;
                    //event.returnValue = false;
                    Event.stop(e);
                    return;
                }
            }
            if(parts.length > 1)
            {
                if(parts[1].length > 2)
                {
                    sender.value = oldVal;
                    //event.returnValue = false;
                    Event.stop(e);
                    return;
                }
            }
        }
        
        if(sender.value.length == 2)
        {sender.value += ':';}
        
        if(sender.value.length > 9)
        {sender.value = sender.value.substring(0,9);}
    }
    else if(odaKeyCode.keyCodeValue.toString().toUpperCase() == 'P' ||
    odaKeyCode.keyCodeValue.toString().toUpperCase() == 'A')
    {
        if(sender.value.length == 6)
        {
            sender.value += odaKeyCode.keyCodeValue.toUpperCase()
            + 'M';
        }
        else if(sender.value.length == 5)
        {
            sender.value += ' '
            + odaKeyCode.keyCodeValue.toUpperCase()
            + 'M';
        }
    }
    else if(odaKeyCode.keyCodeValue == ':')
    {
        // so split on ' '
        // if the sections.length >=2 then
        // if(sections[1].length == 1)
        // sections[1] = '0' + sections[1];
        // if(sections[1].length == 2)
        // sections[1] += ':';
        
        var sections = sender.value.split(' ');
        if(getCharCount(sender.value, ':') == 0)
        {
            if(sections[0].length == 1)
            {
                sections[0] = '0' + sections[0] + ':';
            }
            else if(sections[0].length == 2)
            {
                sections[0] += ':';
            }
            
            for(var j=0; j<sections.length; j++)
            {
                if(j== 0)
                {
                    sender.value = sections[j];
                }
                else
                {
                    sender.value += ' ' + sections[j];
                }
            }
        }
    }
    else if(isAllowedSpecialChar(odaKeyCode))
    {
        return true;
    }
    //event.returnValue = false;
    Event.stop(e);
}

// Handle Delete/Tab and other special chars here
function validateDateTimeKeyDown(sender,_mode, e)
{
    if(_mode == DateValidationModes.Time){
        validateTimeKeyDown(sender, _mode, e);
        return;
    }
    
    e = ensureEvent(e);
    var odaKeyCode = new ODAKeyCode(e);

    if (odaKeyCode.keyCodeValue == 't' || odaKeyCode.keyCodeValue == 'T' && $F(sender).length == 0) {
        var tmpDate= new Date();
        if (_mode == DateValidationModes.DateAndOptionalTime 
            || _mode == DateValidationModes.DateOnly) {
            $S(sender, tmpDate.toFormattedString(false));
            
        }
        else if(_mode == DateValidationModes.DateAndRequiredTime){
            $S(sender,tmpDate.toFormattedString(true));
        }
    } 
    else if(odaKeyCode.keyCode == odaKeyCode.DELETE) // delete
    {   
        var nextChar = getNextChar(sender);
        if(nextChar == '/' || nextChar == ':' || nextChar == ' ')
        {
            MoveCursor(sender,1);
            
            Event.stop(e);
            return;
        }
        else if(nextChar == 'A' || nextChar == 'P')
        {
            sender.value = sender.value.substring(0, sender.value.length-3);
            //event.returnValue = false;
            Event.stop(e);
            return;
        }
        else if(nextChar == '')
        {
            //event.returnValue = false;
            Event.stop(e);
            return;
        }
        
        if(getCursorPosition(sender) < 20)
        {
            dateTimeDeleteKey(sender);
            MoveCursor(sender,1);
        }
        
        //event.returnValue = false;
        Event.stop(e);
    }
    else if(odaKeyCode.keyCode == odaKeyCode.SPACE) // space bar
    {

        //event.returnValue = false;
        Event.stop(e);
        // so if we are trying to type the year, and the year length isn't 4 digits long, then make it 4 digits long
        var dateParts = sender.value.split(' ')[0].split('/');
        if(dateParts.length == 3)
        {
            var modified = false;
            if(dateParts[2].length == 2 && IsValidPattern(dateParts[2],'^[0-9]+$'))
            {
                if((+dateParts[2]) > 49)
                {
                    dateParts[2] = '19' + dateParts[2];
                    modified = true;
                }
                else
                {
                    dateParts[2] = new Date().getFullYear().toString().substring(0,2) + dateParts[2];
                    modified = true;
                }
            }
            else if(dateParts[2].length == 0)
            {dateParts[2] = new Date().getFullYear();modified = true;}
            
            if(modified)
            {
                sender.value = dateParts[0] + '/' + dateParts[1] + '/' + dateParts[2];
                for(var j=1; j<sender.value.split(' ').length; j++)
                {
                    sender.value += ' ' + sender.value.split(' ')[j];
                }
                
            }
        }        
        if(_mode == 3)
        {
            sender.value = trim(sender.value);
            //event.returnValue = false;
            Event.stop(e);
            return false;
        }
        if(sender.value.split(' ').length >= 2)
        {
            // split on ':'
            // if the length there is 1 then make sure that the length of 1 is 2 then add a :
            // if the length is 2 then make sure that position 2 is 2 in length then add a space
            
            var sections = sender.value.split(' ');
            var timepart = sections[1].split(':');
            
            if(timepart.length == 1)
            {
                if(timepart[0].length == 1)
                {
                    sections[1] = '0' + timepart[0] + ':';
                }
                else if(timepart[0].length == 2)
                {
                    sections[1] += ':';
                }
            }
            else if(timepart.length == 2)
            {
                if(timepart[1].length == 1)
                {
                    sections[1] = timepart[0] + ':0' + timepart[1];
                }
                else if(timepart[1].length == 2)
                {
                    sections[1] += ' ';
                }
            }
            
            for(var j=0; j<sections.length; j++)
            {
                if(j==0)
                {
                    sender.value = sections[j];
                }
                else
                {
                    sender.value += ' ' + sections[j];
                }
            }
        }
        
        if(getCharCount(sender.value,' ') < 2 && 
        (
        getCursorPosition(sender) == 10 ||
        getCursorPosition(sender) == 16
        ))
        {
            
            insertAtCursor(sender,odaKeyCode.keyCodeValue);
        }
        
        return;
        
    }    
    
    // datetime consists of three sections
    // sections one and two are 1-2 characters long
    // section three is 2 or 4 characters long
 
    if(odaKeyCode.IsNumber)
    {
        if(sender.value.length >= 20)
        {deleteAtCursor(sender);}
        var oldVal = sender.value;
        
        insertAtCursor(sender,odaKeyCode.keyCodeValue);
        dateTimeParts = sender.value.split(' ');
        
        var parts = dateTimeParts[0].split('/');
        if(parts.length > 0)
        {
            if(parts[0].length > 2)
            {
                sender.value = oldVal;
                //event.returnValue = false;
                Event.stop(e);
                return;
            }
        }
        if(parts.length > 1)
        {
            if(parts[1].length > 2)
            {
                sender.value = oldVal;
                //event.returnValue = false;
                Event.stop(e);
                return;
            }
        }
        if(parts.length > 2)
        {
            if(parts[2].length > 4)
            {
                sender.value = oldVal;
                //event.returnValue = false;
                Event.stop(e);
                return;
            }
        }
        if(dateTimeParts.length > 1)
        {
            parts = dateTimeParts[1].split(':');
            if(parts.length > 0)
            {
                if(parts[0].length > 2)
                {
                    sender.value = oldVal;
                    //event.returnValue = false;
                    Event.stop(e);
                    return;
                }
            }
            if(parts.length > 1)
            {
                if(parts[1].length > 2)
                {
                    sender.value = oldVal;
                    //event.returnValue = false;
                    Event.stop(e);
                    return;
                }
            }
        }
        
        if(sender.value.length == 2)
        {sender.value += '/';}
        else if(sender.value.length == 5)
        {sender.value += '/';}
        else if(sender.value.length == 13)
        {sender.value += ':';}
        
        if(sender.value.length > 20)
        {sender.value = sender.value.substring(0,20);}
    }
    else if(odaKeyCode.keyCodeValue == "/") // the foward slash character
    {
        var slashCount = 0;
        var lastIndex = -1;
        
        if(getPreviousChar(sender) == '/' || sender.value.length == 0)
        {
            //event.returnValue = false;
            Event.stop(e);
            return;
        }
        
        for(var j=0; j<sender.value.length; j++)
        {
            if(lastIndex == -1)
            {
                lastIndex = sender.value.indexOf('/');
                if(lastIndex > -1){slashCount++;}
            }
            else
            {
                var temp = sender.value.indexOf('/',lastIndex+1);
                if(temp > -1)
                {
                    lastIndex = temp;
                    slashCount++;
                }
            }
        }
        if(sender.value.length == 1)
        {
            sender.value = '0' + sender.value;
        }
        if(sender.value.length == 4)
        {
            var parts = sender.value.split('/');
            sender.value = parts[0]
            + '/'
            + '0' + parts[1];
        }
        
        if(slashCount < 2)
        {
            insertAtCursor(sender,odaKeyCode.keyCodeValue);
        }
    }
    else if(odaKeyCode.keyCodeValue.toString().toUpperCase() == 'P' ||
    odaKeyCode.keyCodeValue.toString().toUpperCase() == 'A')
    {
        if(sender.value.length == 17)
        {
            sender.value += odaKeyCode.keyCodeValue.toUpperCase()
            + 'M';
        }
        else if(sender.value.length == 16)
        {
            sender.value += ' '
            + odaKeyCode.keyCodeValue.toUpperCase()
            + 'M';
        }
    }
    else if(odaKeyCode.keyCodeValue == ':')
    {
        // so split on ' '
        // if the sections.length >=2 then
        // if(sections[1].length == 1)
        // sections[1] = '0' + sections[1];
        // if(sections[1].length == 2)
        // sections[1] += ':';
        
        var sections = sender.value.split(' ');
        if(sections.length >=2 && getCharCount(sender.value, ':') == 0)
        {
            if(sections[1].length == 1)
            {
                sections[1] = '0' + sections[1] + ':';
            }
            else if(sections[1].length == 2)
            {
                sections[1] += ':';
            }
            
            for(var j=0; j<sections.length; j++)
            {
                if(j== 0)
                {
                    sender.value = sections[j];
                }
                else
                {
                    sender.value += ' ' + sections[j];
                }
            }
        }
    }
    else if(isAllowedSpecialChar(odaKeyCode))
    {
        return true;
    }
    //event.returnValue = false;
    Event.stop(e);
} 


// Perform RegularExpression Validation
function IsValidDate(_string,_mode)
{
    var RegExPattern = '';
    if(_mode == 2) // date with required time
    {
        RegExPattern = '^(0[1-9]|1[0-2])\\/(0[1-9]|[1-2][0-9]|3[0-1])\\/(19[0-9][0-9]|2[0-2][0-9][0-9])\\ (((0[1-9]|1[0-2]):[0-5][0-9] ([ap]m|[AP]M))$|(([0-1][0-9]|2[0-3])\\:([0-5][0-9]))$)';
    }
    else if(_mode == 1) // date with optional time
    {
        RegExPattern = '^(^(0[1-9]|1[0-2])\\/(0[1-9]|[1-2][0-9]|3[0-1])\\/(19[0-9][0-9]|2[0-2][0-9][0-9])$)|((0[1-9]|1[0-2])\\/(0[1-9]|[1-2][0-9]|3[0-1])\\/(19[0-9][0-9]|2[0-2][0-9][0-9])\\ (((0[1-9]|1[0-2]):[0-5][0-9] ([ap]m|[AP]M))$|(([0-1][0-9]|2[0-3])\\:([0-5][0-9])))$)';
    }
    else if (_mode == 3) // date without time
    {
        RegExPattern = '^(0[1-9]|1[0-2])\\/(0[1-9]|[1-2][0-9]|3[0-1])\\/(19[0-9][0-9]|2[0-2][0-9][0-9])$';
    }
    else if(_mode == 4) // time only
    {
        RegExPattern = "^(0[1-9]|1[0-2]):[0-5][0-9] ([ap]m|[AP]M)$";
    }
    
    //var reg = new RegExp('^\\d{2}\/\\d{2}\/\\d{4}$');
    var reg = new RegExp(RegExPattern);
    
    if(reg.exec(_string))
    {
        return true;
    }
    else 
    {
        return false;
    } 
}

// Handle Standard keys here
function validateDateTime(sender,_mode, e)
{
    // datetime consists of three sections
    // sections one and two are 1-2 characters long
    // section three is 2 or 4 characters long
 
    e = ensureEvent(e);
    var odaKey = new ODAKeyCode(e);
    
    if(odaKey.IsNumber)
    {
        if(sender.value.length >= 20)
        {deleteAtCursor(sender);}
        var oldVal = sender.value;
        
        insertAtCursor(sender,odaKey.keyCodeValue);
        dateTimeParts = sender.value.split(' ');
        
        var parts = dateTimeParts[0].split('/');
        if(parts.length > 0)
        {
            if(parts[0].length > 2)
            {
                sender.value = oldVal;
                //event.returnValue = false;
                Event.stop(e);
                return;
            }
        }
        if(parts.length > 1)
        {
            if(parts[1].length > 2)
            {
                sender.value = oldVal;
                //event.returnValue = false;
                Event.stop(e);
                return;
            }
        }
        if(parts.length > 2)
        {
            if(parts[2].length > 4)
            {
                sender.value = oldVal;
                //event.returnValue = false;
                Event.stop(e);
                return;
            }
        }
        if(dateTimeParts.length > 1)
        {
            parts = dateTimeParts[1].split(':');
            if(parts.length > 0)
            {
                if(parts[0].length > 2)
                {
                    sender.value = oldVal;
                    //event.returnValue = false;
                    Event.stop(e);
                    return;
                }
            }
            if(parts.length > 1)
            {
                if(parts[1].length > 2)
                {
                    sender.value = oldVal;
                    //event.returnValue = false;
                    Event.stop(e);
                    return;
                }
            }
        }
        
        if(sender.value.length == 2)
        {sender.value += '/';}
        else if(sender.value.length == 5)
        {sender.value += '/';}
        else if(sender.value.length == 13)
        {sender.value += ':';}
        
        if(sender.value.length > 20)
        {sender.value = sender.value.substring(0,20);}
    }
    else if(odaKey.keyCodeValue == "/") // the foward slash character
    {
        var slashCount = 0;
        var lastIndex = -1;
        
        if(getPreviousChar(sender) == '/' || sender.value.length == 0)
        {
            //event.returnValue = false;
            Event.stop(e);
            return;
        }
        
        for(var j=0; j<sender.value.length; j++)
        {
            if(lastIndex == -1)
            {
                lastIndex = sender.value.indexOf('/');
                if(lastIndex > -1){slashCount++;}
            }
            else
            {
                var temp = sender.value.indexOf('/',lastIndex+1);
                if(temp > -1)
                {
                    lastIndex = temp;
                    slashCount++;
                }
            }
        }
        if(sender.value.length == 1)
        {
            sender.value = '0' + sender.value;
        }
        if(sender.value.length == 4)
        {
            var parts = sender.value.split('/');
            sender.value = parts[0]
            + '/'
            + '0' + parts[1];
        }
        
        if(slashCount < 2)
        {
            insertAtCursor(sender,odaKey.keyCodeValue);
        }
    }
    else if(odaKey.keyCodeValue.toUpperCase() == 'P' ||
    odaKey.keyCodeValue.toUpperCase() == 'A')
    {
        if(sender.value.length == 17)
        {
            sender.value += odaKey.keyCodeValue.toUpperCase()
            + 'M';
        }
        else if(sender.value.length == 16)
        {
            sender.value += ' '
            + odaKey.keyCodeValue.toUpperCase()
            + 'M';
        }
    }
    else if(odaKey.keyCodeValue == ':')
    {
        // so split on ' '
        // if the sections.length >=2 then
        // if(sections[1].length == 1)
        // sections[1] = '0' + sections[1];
        // if(sections[1].length == 2)
        // sections[1] += ':';
        
        var sections = sender.value.split(' ');
        if(sections.length >=2 && getCharCount(sender.value, ':') == 0)
        {
            if(sections[1].length == 1)
            {
                sections[1] = '0' + sections[1] + ':';
            }
            else if(sections[1].length == 2)
            {
                sections[1] += ':';
            }
            
            for(var j=0; j<sections.length; j++)
            {
                if(j== 0)
                {
                    sender.value = sections[j];
                }
                else
                {
                    sender.value += ' ' + sections[j];
                }
            }
        }
    }
    else if(isAllowedSpecialChar(odaKey))
    {
        return true;
    }
    //event.returnValue = false;
    Event.stop(e);
}

// changes the value to the right to a Zero
function dateTimeDeleteKey(myField,_mode)
{
    var sel = new Selection(myField);
    var rng = sel.create();
    
    sel.setRange(rng.start,rng.end+1);
    sel.create().setText("0");
    
    sel.setRange(rng.start,rng.end);
}
function validateMoney(sender,floatingPoints, e, _currencySymbol, _currencySymbolAtStart) {

    if(_currencySymbol == null){_currencySymbol = "$";}
    if(_currencySymbolAtStart == null){_currencySymbolAtStart = true;}
    
    //sender.value = sender.value.replace(/\$/g, '');
    e = ensureEvent(e);
    var odaKey = new ODAKeyCode(e);
    
    if(isAllowedSpecialChar(odaKey))
    {
        return true;
    }
    
    if(odaKey.IsNumber)
    {
        if(sender.value.indexOf('.') > -1)
        {
            var oldString = sender.value;
            insertAtCursor(sender,odaKey.keyCodeValue);
            formatMoney(sender,floatingPoints);
        }
        else
        {
            insertAtCursor(sender,odaKey.keyCodeValue);
        }
    }
    else if(odaKey.keyCodeValue == '-' 
        && new Selection(sender).create().start == 0 
        && $F(sender).indexOf('-') == -1)
    {
        insertAtCursor(sender, odaKey.keyCodeValue);
    }
    else if(odaKey.keyCodeValue == "." && sender.value.indexOf('.') == -1) // handle the decimal point
    {
        insertAtCursor(sender,'.');
        formatMoney(sender,floatingPoints);
    }
   
    if(sender.value.indexOf(_currencySymbol) == -1)
    { 
        if(_currencySymbolAtStart){
            sender.value = _currencySymbol + sender.value; 
        }
        else{
            sender.value = sender.value + _currencySymbol; 
        }
    }

    //event.returnValue = false;
    Event.stop(e);
}

function formatMoney(field,floatingPoints)
{
    if((field.value.length-1)-field.value.indexOf('.') > floatingPoints)
    {
        var decimalParts = field.value.split('.');
        var leftPart = decimalParts[0];
        for(var j=0; j< (decimalParts[1].length-floatingPoints); j++)
        { leftPart += decimalParts[1].charAt(j); }
        var rightPart = decimalParts[1].substring(decimalParts[1].length-floatingPoints,decimalParts[1].length);
        field.value = leftPart + '.' + rightPart;
    }
}

function validatePercent(sender,floatingPoints, e)
{
    e = ensureEvent(e);
    var odaKey = new ODAKeyCode(e);
    
    if(isAllowedSpecialChar(odaKey))
    {    
        return true;
    }
    
    var sel = new Selection(sender);
    
    var rng = sel.create();
    sender.value = sender.value.replace(/\%/g, '');
    sel.setRange(rng.start,rng.end);
    
    if(odaKey.IsNumber)
    {
        if(sender.value.indexOf('.') > -1)
        {
            var oldString = sender.value;
            insertAtCursor(sender,odaKey.keyCodeValue);
            formatMoney(sender,floatingPoints);
        }
        else
        {
            insertAtCursor(sender,odaKey.keyCodeValue);
        }
    }
    else if(odaKey.keyCodeValue == "." && sender.value.indexOf('.') == -1) // handle the decimal point
    {
        insertAtCursor(sender,'.');
        formatMoney(sender,floatingPoints);
    }
    
    rng = sel.create();
    if(sender.value.indexOf('%') == -1 && sender.value.length > 0)
    { sender.value = sender.value +'%' ; }    
    sel.setRange(rng.start,rng.end);

    //event.returnValue = false;
    Event.stop(e);
}


function validateInteger(sender, e)
{
    e = ensureEvent(e);
    var odaKey = new ODAKeyCode(e);
    
    if(odaKey.IsNumber)
    {
        insertAtCursor(sender,odaKey.keyCodeValue);
    }
    else if(odaKey.keyCodeValue == '-' 
        && new Selection(sender).create().start == 0
        && $F(sender).indexOf('-') == -1)
    {
        insertAtCursor(sender, odaKey.keyCodeValue);
    }
    else if(isAllowedSpecialChar(odaKey))
    {
        return true;
    }
    //event.returnValue = false;
    Event.stop(e);
}

//////////////////////////////////////////////////////////////////////////////////////////
////////    Textbox Helper Methods
//////////////////////////////////////////////////////////////////////////////////////////

/**
* Checks to see if the date is before the current date on the client (optional Time)
* @param {string} date: value to check
* @param {bool} ignoreTime: (Optional default true) whether or not to ignore time of day 
* @returns true if date before now, otherwise false
* @type bool
*/
function isDateBeforeNow(date, ignoreTime)
{
    if(ignoreTime == null)
    { ignoreTime = true; }

    try
    {
        var parsedDate = Date.parse(date);
        var now = new Date();
        
        if(ignoreTime)
        {
            //floor now to make sure passed in date is before today
            // to return true;
            now.setHours(0,0,0,0);
            var parsedNowNoTime = Date.parse(now.toString());
            
            return parsedNowNoTime > parsedDate;
        }
        else
        {
            var parsedNow = Date.parse(now.ToString());
            
            return parsedNow > parsedDate;
        }
    }
    catch(e)
    {
        return false;
    }
}

/**
* Checks to see if the date is after the current date on the client (optional Time)
* @param {string} date: value to check
* @param {bool} ignoreTime: (Optional default true) whether or not to ignore time of day 
* @returns true if date after now, otherwise false
* @type bool
*/
function isDateAfterNow(date, ignoreTime)
{
    if(ignoreTime = null)
    { ignoreTime = true; }
    
    try
    {
        var parsedDate = Date.parse(date);
        var now = new Date();
        
        if(ignoreTime)
        {
            var parsedNow = Date.parse(now.toString());
            
            //floor date passed in to make sure it is tomorrow or after
            // to return true
            var OrgDate = new Date();
            OrgDate.setTime(parsedDate);
            OrgDate.setHours(0,0,0,0);
            parsedDate = Date.parse(OrgDate.toString());
            
            return parsedNow < parsedDate;
        }
        else
        {
            var parsedNow = Date.parse(now.ToString());
            
            return parsedNow < parsedDate;
        }
    }
    catch(e)
    {
        return false;
    }
}