﻿

var Validate = {
    element : function(control, dontTrip, scrollContainer)
    {
        if(!control) return;
        Validate.control = $(control);
        Validate.isRequired = (control.getAttribute('required') && control.getAttribute('required').toLowerCase() == 'true') ? true : false;
        Validate.dontTrip = dontTrip ? true : false;
        Validate.customFunction = control.getAttribute('customvalidationfunction') ? control.getAttribute('customvalidationfunction') : undefined;
        Validate.validationType = control.getAttribute('validationtype') ? control.getAttribute('validationtype') : undefined;
        Validate.errorIsPopup = control.getAttribute('errorispopup') ? control.getAttribute('errorispopup') : 'true';
        Validate.scrollContainer =  window;
        var tagName = control.tagName.toLowerCase();
        if (tagName == 'input')
        {
            switch (control.type.toLowerCase())
            {
                case 'text':
                case 'password':
                case 'file':
                    return Validate.textbox();
                break;
                
                case 'checkbox':
                    return Validate.checkbox();
                break;
                
                case 'radio':
                    return Validate.radio();
                break;
                
                default:
                    AppErrors += "Validator unrecognized control: " + (control ? control.inspect() : '[undefined]') + '\n';
                return false;
            }
        }
        else if (tagName == 'select')
        {
            if(control.getAttribute('size'))
                return Validate.listbox();
            else
                return Validate.dropdown();
        }
        else if (tagName == 'textarea')
        {
            return Validate.textarea();
        }
        else if (tagName == 'table')
        {
            if (Validate.control.controltype == 'radiolist')
            {
                return Validate.radiolist();
            }
            else if (Validate.control.controltype == 'checkboxlist')
            {
                return Validate.checkboxList();
            }
            else if(Validate.control.controltype == 'editablegrid')
            {
                return Validate.editableGrid();
            }
            else
            {
                return false;
            }
                //alert("Validation function did not recognize " + control.id + "'s type.");
        }
        else
        {
            return false;//alert("Validation function did not recognize " + control.id + "'s type.");
        }
    },
    
    showError : function(element, errorIsPopup, scrollContainer, invalidRequired)
    {
        Validate.scrollContainer = scrollContainer || 'mainContent';
        Validate.control = element;
        Validate.errorIsPopup = errorIsPopup ? true : false;
        Validate.showErrorLabel(invalidRequired);
    },
    
    execValidationType : function()
    {
        switch (Validate.validationType.toLowerCase())
        {
            case 'date':
                return regEx.isValidDate(Validate.control.value);
            break;
            
            case 'year':
                return regEx.isValidDate(Validate.control.value, 'Y');
            break;
            
            case 'zip':
                return regEx.isValidZipCode(Validate.control.value);
            break;
            
            case 'phone':
                return regEx.isValidPhone(Validate.control.value);
            break;
            
            case 'email':
                return regEx.isValidEmail(Validate.control.value);
            break;
            
             case 'ssn':
                return regEx.isValidSSN(Validate.control.value);
            break;
            
            case 'currency':
                return regEx.isValidCurrency(Validate.control.value);
            break;
            
            case 'numeric':
                return true;
            break;
            
            case 'numericwithnegative':
                return regEx.isValidnumericWithNegative(Validate.control.value);
            break;
            
            case 'alphanumeric':
                return true;
            break;
            
            case 'fileupload':
				return regEx.isValidFileUpload(Validate.control.value);
			break;
			case 'fileuploadCSV':
				return regEx.isValidFileUploadCSV(Validate.control.value);
			break;

            default:
            return true;
        }
        
    },
    
    checkValidationType : function()
    {
        if (Validate.validationType)
            return Validate.execValidationType();
        else
            return true;
    },
    
    checkCustomValidation : function()
    {
        
        if (Validate.customFunction)
        {
            var rc = eval(Validate.customFunction + '(Validate.control)');
            if (rc)
            {
                return Validate.controlIsValid();
            }
            else
            {
                return Validate.controlIsInvalid('invalid');
            }
        }
        else
            return Validate.controlIsValid();
            
        
    },
    
    textbox : function()
    {
        if (Validate.isRequired)
        {
            if (Validate.control.value.length > 0)//if it's not empty
            {   
                if (Validate.checkValidationType())
                {
                    
                    return Validate.checkCustomValidation();
                }
                else
                {
                    return Validate.controlIsInvalid('invalid');
                }
            }
            
        }
        else
        {
            if (Validate.control.value.length > 0)
            {
                if (Validate.checkValidationType())
                {
                    return Validate.checkCustomValidation();
                }
                else
                {
                    return Validate.controlIsInvalid('invalid');
                }
            }
            else // is empty
            {
               return Validate.controlIsValid();
            }
        }
        return Validate.controlIsInvalid('required');
    },
    
    checkbox : function()
    {
        if (Validate.isRequired)
        {
            if (Validate.control.checked != true)
            {      
                if (Validate.dontTrip) return false;   
                     
                Validate.showErrorLabel('required');
                return false;
            }
            else
            {
                if (Validate.dontTrip) return true;
                    
                Validate.hideErrorLabel();
                return true;
            }
        }
        else
            return true;
    },
    
    dropdown : function()
    {
        if (Validate.isRequired)
        {   
            if (Validate.control[0].selected)
            {
                if (Validate.dontTrip) return false;
                
                Element.addClassName(Validate.control, "error_field");
                Validate.showErrorLabel('required');
                return false;
            }
        }
        return Validate.checkCustomValidation();
    },
    
    listbox : function()
    {
        if (Validate.isRequired)
        {  
            if (!Validate.control.value)
            {
                if (Validate.dontTrip) return false;
                
                Element.addClassName(Validate.control, "error_field");
                Validate.showErrorLabel('required');
                return false;
            }
        }
        return Validate.checkCustomValidation();
    },
    
    textarea : function()
    {
        return Validate.textbox();
    },
    radio : function()
    {
        if(Validate.control.checked == true)
            return true;
        return false;
    },
    
    radiolist : function()
    {
        //should we put the name of the control on the container?
        if (Validate.isRequired)
        {
            var radiolistControl = Validate.control.getElementsByTagName('input');
            for(var i=0; i < radiolistControl.length; i++)
            {
                if (radiolistControl[i].checked)
                {
                    if (Validate.dontTrip) return true;
                    Validate.hideErrorLabel('required', errorLabel);
                    return true;
                }
            }
            if (Validate.dontTrip) return false;
            Validate.showErrorLabel();
            return false;
        }
        else { return true; } // not required radiolist always valid
    },
    
    checkboxList : function()
    {
        if (Validate.isRequired)
        {
            var checkboxes = Validate.control.getElementsByTagName('input');
            var errorLabel = $("error_" + Validate.control.name);
            //make array for future use can validate the number of controls that are checked
            //var checkboxAry = [];
            //for(var i=0; i < checkboxes.length; i++)
            //{
                //checkboxAry[i] = Validate.required(checkboxes[i]);
            //}
            for (var i=0; i < checkboxes.length; i++)
            {
                if (checkboxes[i].checked)
                {
                    if (Validate.dontTrip) return true;
                    Validate.hideErrorLabel(errorLabel);
                    return true;
                }
            }
            if (Validate.dontTrip) return false;
            Validate.showErrorLabel('required', errorLabel);  
            return false;
        }
        else { return true; } // not required, checkboxlist always valid
    },
    
    editableGrid : function()
    {
        if (Validate.isRequired)
        {
            var errorLabel = $("error_" + Validate.control.id);
            if (Validate.control.tBodies(0).childNodes.length > 0)
            {
                if(Validate.dontTrip) return true;
                Validate.hideErrorLabel(errorLabel);
                Validate.control.className = Validate.control.className.replace(' invlaid', '');
                return true;
            }
            if (Validate.dontTrip) return false;
            Validate.showErrorLabel('required', errorLabel);
            Validate.control.className += " invalid";
            return false;
        }
        else { return true; }
    },
    
    controlIsValid : function(errorLabel)
    {
        if (Validate.dontTrip) return true;

        Element.removeClassName(Validate.control, "error_field");
        Validate.hideErrorLabel(errorLabel);
        return true;
    },
    
    controlIsInvalid : function(args, errorLabel)
    {
        if (Validate.dontTrip) return false;   
        
        Element.addClassName(Validate.control, "error_field");
        Validate.showErrorLabel(args, errorLabel);
        return false;
    },
    
    
    showErrorLabel : function(args, errorLabel)
    {
        if (!errorLabel)
            var errorLabel = $("error_" + Validate.control.id);
        if(!errorLabel)
            var errorLabel = Validate.control.nextSibling.childNodes[0] || Validate.control.nextSibling.nextSibling.childNodes[0] || Validate.control.nextSibling.nextSibling.nextSibling.childNodes[0];
        if (!args)
            var args = 'required';
        
        var errorTitle = 'Required Field';
        
        if (args == 'invalid')
            errorTitle = 'Invalid Field';
        if (errorLabel)
        {
            if (Validate.errorIsPopup == 'True' || Validate.errorIsPopup == 'true')
            {
                new Tip(
                  Validate.control,
                  errorLabel.innerHTML,
                  {
                    className: 'protoClassic', 
                    closeButton: false, 
                    duration: 0.3, 
                    delay: 0,
                    effect: 'slide', 
                    fixed: true, 
                    hideAfter: false, 
                    hideOn: 'blur',
                    hook: { target: 'bottomLeft', tip: 'topLeft' }, 
                    offset: {x: 2, y: 1},
                    showOn: 'focus', 
                    title: errorTitle, 
                    viewport: false                  
                  }
                );
            }
            else
            {
                errorLabel.style.display = '';
                errorLabel.parentNode.style.display = '';
            }
            
        }
        else
            alert('Could not find error label associated with control ' + Validate.control.id + '.');
    },
    hideErrorLabel : function(errorLabel)
    {
        if (!errorLabel)
            var errorLabel = $("error_" + Validate.control.id);
        if(!errorLabel)
        {
            try
            {
                var errorLabel = Validate.control.nextSibling.childNodes[0] || Validate.control.nextSibling.nextSibling.childNodes[0] || Validate.control.nextSibling.nextSibling.nextSibling.childNodes[0];
            }
            catch(e)
            {
                //do nothing
            }
            
        }
            
        if (errorLabel)
        {
            if (Validate.errorIsPopup == 'True' || Validate.errorIsPopup == 'true')
            {
                Tips.remove(Validate.control);
                //Tips.hideAll();
            }
            else
            {
                errorLabel.style.display = 'none';
                errorLabel.parentNode.style.display = 'none';
            }
            
        }
//        else
//            alert('Could not find error label associated with control ' + Validate.control.id + '.');
        
    },
    
    //Page Validation method to be called on click of submit button.
    //args == 'all' will validate all required controls
    //args == 'withoutgroup' will validate required controls that do not have a validation group
    //args can also be passed as a validation group to validate
    submit : function(args, containerID, dontTrip, dontFocus, scrollContainer) //optional container, else will validate all document elements
    {
        scrollContainer = scrollContainer || 'mainContent';
        dontTrip = dontTrip == true ? true : false;
        dontFocus = dontFocus == true ? true : false;
        var container = $(containerID) ? $(containerID) : document;
        var inputs = container.getElementsByTagName('input');
        var selects = container.getElementsByTagName('select');
        var textareas = container.getElementsByTagName('textarea');
        var tables = container.getElementsByTagName('table');
        var allControls = [inputs, selects, textareas, tables];
        var hasRequired, hasGroup, isGroup;
        hasRequired = hasGroup = isGroup = false;
        
        var firstInvalidControl, controls;
        firstInvalidControl = control = null;
        var invalidControls = 0;
        var isFirstTime;
        for (var i = 0; i < allControls.length; i++)
        {
            controls = allControls[i];
            isFirstTime = true;
            for (var control in controls)
            {
                if (isFirstTime || !controls[control] || !controls[control].tagName){ isFirstTime = false; continue; }
                hasRequired = controls[control].getAttribute("required") ? true : false;
                //isRequired = hasRequired ? (controls[control].required.toLowerCase() == 'true') : false;
                
                switch (args)
                {
                    case 'all':
                        hasGroup = true;
                        isGroup = true;
                    break;
                    case 'withoutgroup':
                        hasGroup = !controls[control].getAttribute('validationgroup') ? true : false;
                        isGroup = true;
                    
                    break;
                    default: //args == the group
                        hasGroup = controls[control].getAttribute('validationgroup') ? true : false;
                        isGroup = hasGroup ? (controls[control].getAttribute('validationgroup') == args) : false;
                }
                if (hasRequired && hasGroup && isGroup)
                {
                    if(!Validate.element(controls[control], dontTrip, scrollContainer))
                    {
                        if(!dontFocus)
                        {
                            if (!firstInvalidControl)
                            {
                                firstInvalidControl = controls[control];
                            }
                            else if (firstInvalidControl.sourceIndex > controls[control].sourceIndex)
                            {
                                firstInvalidControl = controls[control];
                            }
                        }   
                        invalidControls++;
                    }
                }
            }
        }
        
        if (invalidControls > 0)
        {
            //alert("validation failed");
            try{
                firstInvalidControl.focus();
            }
            catch(failure){
                
            }
            
            return false;
        }
        else
        {
            //alert("validation passed");
            return true;
        }
    },
    
    numeric : function(event, txtbox, allowNegative) //onkeydown handler
    {
        if (!event) event = window.event;
        if (event.keyCode >= 96 && event.keyCode <= 111) 
		{
			event.keyCode -= 48;
		}
        //if (!maxLength) maxLength = txtbox.value.length + 1;
        allowNegative = allowNegative == true ? true : false;
            
        var keysToAllowAry = { 
            backspace: Event.KEY_BACKSPACE,
            tab: Event.KEY_TAB,
            leftArrow: Event.KEY_LEFT,
            rightArrow: Event.KEY_RIGHT,
            'delete': Event.KEY_DELETE,
            numPad0: 96,
            numPad1: 97,
            numPad2: 98,
            numPad3: 99,
            numPad4: 100,
            numPad5: 101,
            numPad6: 102,
            numPad7: 103,
            numPad8: 104,
            numPad9: 105
        }
        if (allowNegative)
        {
            keysToAllowAry.numPadNegative = 61;
            keysToAllowAry.negative = 189;
        }
        for (allowKey in keysToAllowAry)
        {   
            if (event.keyCode == keysToAllowAry[allowKey])
                return;
        }
        
        if (event.shiftKey)
            Event.stop(event);
            
        var theVal = String.fromCharCode(event.keyCode);
        if (!(theVal >= '0' && theVal <= '9'))
        {
           Event.stop(event);
        }
    },
    
    alphaNumeric : function(event, txtbox) //onkeydown handler
    {
        if (!event) event = window.event;
        if (event.keyCode >= 96 && event.keyCode <= 111) 
		{
			event.keyCode -= 48;
		}
        
        var keysToAllowAry = { 
            backspace: Event.KEY_BACKSPACE,
            tab: Event.KEY_TAB,
            leftArrow: Event.KEY_LEFT,
            rightArrow: Event.KEY_RIGHT,
            'delete': Event.KEY_DELETE
        }
        for (allowKey in keysToAllowAry)
        {   
            if (event.keyCode == keysToAllowAry[allowKey])
                return;
        }
        var theVal = String.fromCharCode(event.keyCode);
        if (!(theVal >= '0' && theVal <= '9') && !(theVal >= 'a' && theVal <= 'z') && !(theVal >= 'A' && theVal <= 'Z'))
        {
           Event.stop(event);
        }
    },
    
    currency : function(event, txtbox, allowNegative) //onkeydown handler
    {
        if (!event) event = window.event;
        if (event.keyCode >= 96 && event.keyCode <= 109) 
		{
			event.keyCode -= 48;
		}
        //if (!maxLength) maxLength = txtbox.value.length + 1;
        allowNegative = allowNegative == true ? true : false;
            
        var keysToAllowAry = { 
            backspace: Event.KEY_BACKSPACE,
            tab: Event.KEY_TAB,
            leftArrow: Event.KEY_LEFT,
            rightArrow: Event.KEY_RIGHT,
            'delete': Event.KEY_DELETE,
            'decimal': 190,
            decimal2: 110,
            numPadNegative: 61
        }
        for (allowKey in keysToAllowAry)
        {
            if (event.keyCode == keysToAllowAry[allowKey])
                return;
        }
        if (event.shiftKey) Event.stop(event);
//        if (allowNegative)
//        {
//            if ((txtbox.value.length == 0) && (event.keyCode == 189)) return;
//        }
        //if ((txtbox.value.length == 0) && (event.keyCode == 190)) Event.stop(event);
        
//        if ((event.keyCode == 190) && (txtbox.value.lastIndexOf('.') != -1)) Event.stop(event); 
//        
//        if (txtbox.value.lastIndexOf('.') != -1 && ((txtbox.value.length - 1) - txtbox.value.lastIndexOf('.')) == 2) Event.stop(event);
//        
        var theVal = String.fromCharCode(event.keyCode);
        
        if (!(theVal >= '0' && theVal <= '9') && (event.keyCode != 190)) Event.stop(event);
    }
    
    
}

var regEx = {

    isValidDate : function(dateStr, format) 
    {
        var today=new Date();
        if (format == null) 
        { 
            format = "MDY"; 
        }
        format = format.toUpperCase();
        if (format.length != 3 && format != 'Y') 
        { 
            format = "MDY"; 
        }
        if ( ((format.indexOf("M") == -1) || (format.indexOf("D") == -1) || (format.indexOf("Y") == -1)) && format != 'Y' )
        { 
            format = "MDY"; 
        }
        if (format.length == 1 && format.substring(0, 1) == "Y")
        {
            var thisYear = (dateStr*1);
            if ((thisYear > (today.getFullYear() + 500 )) || (thisYear < (today.getFullYear() - 500)) || (dateStr.length < 4)) 
            { 
                return false; 
            }
            else 
            {
                return true;
            }
        }
        
        if (format.substring(0, 1) == "Y") 
        { // If the year is first
            var reg1 = /^\d{2}(\-|\/|\.)\d{1,2}\1\d{1,2}$/
            var reg2 = /^\d{4}(\-|\/|\.)\d{1,2}\1\d{1,2}$/
        }
        else if (format.substring(1, 2) == "Y") 
        { // If the year is second
            var reg1 = /^\d{1,2}(\-|\/|\.)\d{2}\1\d{1,2}$/
            var reg2 = /^\d{1,2}(\-|\/|\.)\d{4}\1\d{1,2}$/
        } 
        else 
        { // The year must be third
            var reg1 = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{2}$/
            var reg2 = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{4}$/
        }
        // If it doesn't conform to the right format (with either a 2 digit year or 4 digit year), fail
        if ( (reg1.test(dateStr) == false) && (reg2.test(dateStr) == false)) 
        { 
            return false; 
        }
        var parts = dateStr.split(RegExp.$1); // Split into 3 parts based on what the divider was
        // Check to see if the 3 parts end up making a valid date
        if (format.substring(0, 1) == "M") 
        {
            var mm = parts[0]; 
        } 
        else if (format.substring(1, 2) == "M") 
        { 
            var mm = parts[1]; 
        } 
        else 
        { 
            var mm = parts[2]; 
        }
        if (format.substring(0, 1) == "D") 
        { 
        var dd = parts[0]; 
        } 
        else if (format.substring(1, 2) == "D") 
        {
            var dd = parts[1]; 
        } 
        else 
        { 
        var dd = parts[2]; 
        }
        if (format.substring(0, 1) == "Y") 
        { 
            var yy = parts[0]; 
        } 
        else if (format.substring(1, 2) == "Y") 
        { 
            var yy = parts[1]; 
        } 
        else 
        { 
        var yy = parts[2]; 
        }
        if (parseFloat(yy) <= 50) 
        { 
            yy = (parseFloat(yy) + 2000).toString(); 
        }
        if (parseFloat(yy) <= 99) 
        { 
            yy = (parseFloat(yy) + 1900).toString(); 
        }
        var dt = new Date(parseFloat(yy), parseFloat(mm)-1, parseFloat(dd), 0, 0, 0, 0);
        if ((parseFloat(yy) > (today.getFullYear() + 100)) || (parseFloat(yy) < (today.getFullYear() - 100))) return false;
        if (parseFloat(dd) != dt.getDate()) { return false; }
        if (parseFloat(mm)-1 != dt.getMonth()) { return false; }
        return true;
    },
    
    isValidSSN : function(value)
    { 
        var re = /^([0-6]\d{2}|7[0-6]\d|77[0-2])([ \-]?)(\d{2})\2(\d{4})$/; 
        if (!re.test(value)) { return false; } 
        var temp = value; 
        if (value.indexOf("-") != -1) { temp = (value.split("-")).join(""); } 
        if (value.indexOf(" ") != -1) { temp = (value.split(" ")).join(""); } 
        if (temp.substring(0, 3) == "000") { return false; } 
        if (temp.substring(3, 5) == "00") { return false; } 
        if (temp.substring(5, 9) == "0000") { return false; } 
        return true; 
    },
    
    isValidEmail : function(emailAddress) 
    {
        var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[(2([0-4]\d|5[0-5])|1?\d{1,2})(\.(2([0-4]\d|5[0-5])|1?\d{1,2})){3} \])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
        return re.test(emailAddress);
    },
    
    isValidZipCode : function(value) 
    {
       var re = /^\d{5}([\-]\d{4})?$/;
       return (re.test(value));
    },
    
    isValidPhone : function(strPhone) 
    {
        var re = /^(\+\d)*\s*(\(\d{3}\)\s*)*\d{3}(-{0,1}|\s{0,1})\d{2}(-{0,1}|\s{0,1})\d{2}$/;
		var re2 = /^(1?(-?\d{3})-?)?(\d{3})(-?\d{4})$/
        if (strPhone.match(re) || strPhone.match(re2)) 
        {
            return true;
        }
        return false;
    },
    
    isValidCurrency : function(strCurrency) 
    {
        return /^[-+]?[0-9]+(\.[0-9]+)?$/.test(strCurrency);
    },
    
    isValidnumericWithNegative : function(strNumber)
    {
        return /^[-]?\d+(\.\d{2})?$/.test(strNumber);
    },
    
    isValidFileUpload : function(strFilePath)
    {
		return /^(([a-zA-Z]:)|(\\{2}\w+)\$?)(\\(\w[\w].*))(.doc|.DOC|.docx|.DOCX|.pdf|.PDF)$/.test(strFilePath);
    },
    isValidFileUploadCSVFile : function(strFilePath)
    {
		return /^(([a-zA-Z]:)|(\\{2}\w+)\$?)(\\(\w[\w].*))(.csv)$/.test(strFilePath);
    }

}