﻿function RegExpAndType(a_RegularExpression, a_Type)
{
    this.m_RegularExpression = a_RegularExpression;
    this.m_Type = a_Type;
}

//=============================================================================
// ** IMPORTANT
//
// The following is straight up regular expression validation.  However, it is
// important to realize that:
//
// 1) JavaScript has the backslash as the escape character.
//
//  AND
//
// 2) The regular expression itself uses the backslash as an escape charater.
//
// The upshot of this is that when trying to specify a single backslash in a
// group, you need FOUR backslashes.  I.E.: The following group from the
// g_RegExpType_UNCPath regular expression:
// 
//     (\\\\|\\\\\\\\|[a-zA-Z]:)
//
// means:
//
// a) A Single Backslash or,
// b) A Double Backslash or,
// c) A Alpha character and a colon
//
//=============================================================================

var g_RegExpType_FtpUri = new RegExpAndType('^(ftp)\\://([a-zA-Z0-9\\.\\-]+(\\:[a-zA-Z0-9\\.&amp;%\\$\\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\\-]+\\.)*[a-zA-Z0-9\\-]+\\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\\:[0-9]+)*(/($|[a-zA-Z0-9\\.\\,\\?\\\'\\\\\\+&amp;%\\$#\\=~_\\-]+))*$'
                                                        , 'FTP URI Example: ftp://name:password@mydomain.com');

var g_RegExpType_HttpUri = new RegExpAndType('^(http)\\://([a-zA-Z0-9\\.\\-]+(\\:[a-zA-Z0-9\\.&amp;%\\$\\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\\-]+\\.)*[a-zA-Z0-9\\-]+\\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\\:[0-9]+)*(/($|[a-zA-Z0-9\\.\\,\\?\\\'\\\\\\+&amp;%\\$#\\=~_\\-]+))*$'
                                                        , 'HTTP URI Example: http://www.mydomain/com');

var g_RegExpType_FtpOrHttpUri = new RegExpAndType('^(ftp|http)\\://([a-zA-Z0-9\\.\\-]+(\\:[ a-zA-Z0-9\\.&amp;%\\$\\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\\-]+\\.)*[a-zA-Z0-9\\-]+\\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\\:[0-9]+)*(/($|[a-zA-Z0-9\\.\\,\\?\\\'\\\\\\+&amp;%\\$#\\=~_\\-]+))*$'
                                                        , 'FTP or HTTP URI Example: ftp://name:password@mydomain.com or http://www.mydomain/com');

var g_RegExpType_EmailAddress = new RegExpAndType('^([a-zA-Z0-9_\\+\\-\\.]+)@([a-zA-Z0-9_\\.]+)$'
                                                        , 'Email Address: Example: dave@mydomain.com or david.allen@netips.com');

var g_RegExpType_UNCPath = new RegExpAndType('^(\\\\|\\\\\\\\|[a-zA-Z]:)([ a-zA-Z0-9_\\.\\\\!@#\\$\\^&\\(\\)\\-\\+=\\{\\}\\[\\],]*)$'
                                                        , 'UNC File Path: Example: C:\\ or \\\\Server\\share\\path\\File.txt or E:\\My Files\\Are\\Number1');

var g_RegExpType_PositiveInteger = new RegExpAndType('^[1-9]([0-9]*)$'
                                                        , 'positive integer');

var g_RegExpType_NonNegativeInteger = new RegExpAndType('^([0-9]+)$'
                                                        , 'non negative integer');

var g_RegExpType_Currency = new RegExpAndType( '^([1-9]([0-9]*)\.[0-9][0-9]|[1-9]([0-9]*)\.|[1-9]([0-9]*))$'
                                             , ' currency.  Example: 1.23 or 11000.22 or 99. or 100');

var g_RegExpType_IPAddress = new RegExpAndType('^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
                                                        , 'IP XX.XX.XX.XX');

var g_RegExpType_NotBlank = new RegExpAndType('^(.+)$'
                                                        , 'something - cannot be blank');

var g_RegExpType_FormDateTimeInput = new RegExpAndType('^([0-9][0-9]|[0-9])/([0-9][0-9]|[0-9])/([0-9][0-9][0-9][0-9]|[0-9][0-9]) ([0-9][0-9]|[0-9]):([0-9][0-9]|[0-9]):([0-9][0-9]|[0-9])$'
                                                        , 'valid date Time Example: 10/12/1984 21:00:00');

var g_RegExpType_FormDateInput = new RegExpAndType('^([0-9][0-9]|[0-9])/([0-9][0-9]|[0-9])/([0-9][0-9][0-9][0-9]|[0-9][0-9])$'
                                                        , 'valid date example: 10/12/1984');

var g_RegExpType_Percentage = new RegExpAndType('^(1[0-9][0-9]|[1-9][0-9]|[0-9])$'
                                                        , 'integer in range from 1 - 100');

var g_RegExpType_ZipCode = new RegExpAndType('^[0-9][0-9][0-9][0-9][0-9]$'
                                                        , 'Zip code must be exactly 5 digits');

function FormElement(a_Id, a_Text, a_Required, a_RegExpAndType) {
    this.m_Id = a_Id;
    this.m_Text = a_Text;
    this.m_Required = a_Required;
    this.m_RegExpAndType = a_RegExpAndType;

    FormElement.prototype.text = function text(a_Id, a_Text, a_Required, a_RegExpAndType) {
        return 'Id="' + this.m_Id + '" '
	       + 'Text="' + this.m_Text + "' "
		   + 'Required="' + (this.m_Required ? 'true' : 'false') + '" '
		   + 'RegExpAndType=' + (this.m_RegExpAndType == null
		                        ? 'null'
								: ('("' + this.m_RegExpAndType.m_RegularExpression + '", '
								  + '"' + this.m_RegExpAndType.m_Type + '")')
								);
    }
}

function FormValidation(a_Button) {
    this.m_Fields = new Array();
    this.m_Button = a_Button;

    FormValidation.prototype.add = function add(a_Id, a_Text, a_Required, a_RegExpAndType) {
        var l_Required = (a_Required == null ? true : a_Required);
        var l_FormElement = new FormElement(a_Id, a_Text, l_Required, a_RegExpAndType);
        //alert( 'adding: ' + l_FormElement.text());
        this.m_Fields.push(l_FormElement);
    }

    FormValidation.prototype.validate = function validate() {
        var i = 0;
        var l_Errors = new Array();
        var l_iErrorCount = 0;

        for (i = 0; i < this.m_Fields.length; ++i)
        {
            //alert( 'm_Fields[' + i + ']');
            //alert( 'm_Fields[' + i + '].text: ' + this.m_Fields[i].text());
            var l_Element = getFormElement(this.m_Button, this.m_Fields[i].m_Id);
            //alert( 'cp1');
            if ((this.m_Fields[i].m_Required)
			    && (l_Element.value == ''))
                l_Errors.push((++l_iErrorCount) + ') "' + this.m_Fields[i].m_Text + '" '
				             + 'is a required field.');
            else if ((l_Element.value != '')
			         && (this.m_Fields[i].m_RegExpAndType != null))
			{
                //alert( 'cp3:' + l_Element.value + ':' + this.m_Fields[i].m_RegExpAndType.m_RegularExpression);
                if (!matchesRegularExpression(l_Element.value, this.m_Fields[i].m_RegExpAndType.m_RegularExpression))
                    l_Errors.push((++l_iErrorCount) + ') "' + this.m_Fields[i].m_Text + '" '
					             + (this.m_Fields[i].m_RegExpAndType.m_Type == null
					               ? 'is not valid acording to type.'
					               : 'is not a(n) ' + this.m_Fields[i].m_RegExpAndType.m_Type
					               )
					             );
            }
            //alert( 'cp4');
        }

        if (l_Errors.length > 0)
        {
            alert('You have errors in your form:\r\n\r\n'
			     + l_Errors.join('\r\n')
				 + '\r\n\r\nPlease correct and re-submit');
        }

        return l_Errors.length == 0;
    }
}