﻿/// <reference path="spider.js" />
// 5/25/2010
spider.validation = {
    base: {
        formId: 'formid',
        classAlarm: 'alarm'
    },

    isValid: function (settings) {
        var _settings;
        switch (typeof settings) {
            case 'string':
                _settings = spider.utility.create(this.base);
                _settings.formId = settings;
                break;

            case 'object':
                _settings = settings;
                spider.utility.setProperties(spider.validation.base, _settings);
                break;
        }
        var allGood = true;
        var throwFail = function (me, allGood) {
            me.addClass(_settings.classAlarm);
            j('label[for=' + me.attr('id') + ']').addClass(_settings.classAlarm);
            return false;
        };
        var throwSuccess = function (me) {
            me.removeClass(_settings.classAlarm);
            j('label[for=' + me.attr('id') + ']').removeClass(_settings.classAlarm);
        };
        j('#' + _settings.formId + ' .required').each(function (e, d) {
            switch (d.type) {
                case 'text': case 'password': case 'textarea':
                    j.trim(j(this).val()) == '' ? allGood = throwFail(j(this)) : throwSuccess(j(this));
                    break;
                case 'checkbox':
                    j(this).is(':checked') ? throwSuccess(j(this)) : allGood = throwFail(j(this));
                    break;
                case 'select-one':
                    d.selectedIndex === 0 ? allGood = throwFail(j(this)) : throwSuccess(j(this));
                    break;
            }
        });
        return allGood;
    },

    validator: function (element, settings) {
        var _returnObject;

        var _validators = {
            hasValue: function (element) {
                var jthis = spider.utility.make_jquery(element);

                if (jthis.is('input') || jthis.is('textarea')) {
                    // The element is a spider dropdown.
                    if (jthis.hasClass('spider-ui-common-dropdown-keyvalue')) {
                        if ((j.trim(jthis.val()) === '') || j.trim(jthis.val()) === '0' || (jthis.val()) === 0) {
                            _settings.throwError(jthis, 0, 'You must specify a value for this field.');
                            return false;
                        }
                    }

                    // The element is a generic textbox or textarea.
                    if ((j.trim(jthis.val()) === '')) {
                        _settings.throwError(jthis, 0, 'You must specify a value for this field.');
                        return false;
                    }
                }

                if (jthis.is('select')) {
                    if (jthis.hasClass('spider-validation-mvcdropdown')) {
                        if ((j.trim(jthis.val()) === '') || (j.trim(jthis.val()) === '0') || (jthis.val() === 0) || (jthis.get(0).selectedIndex === 0)) {
                            _settings.throwError(jthis, 0, 'You must specify a value for this field.');
                            return false;
                        }
                    }
                }

                return true;
            },

            required: function (element) {
                return _validators.hasValue(element);
            },

            money: function (element) {
                if (_validators.hasValue() === false) {
                    return true;
                } else {
                    return _validators.regEx(element, '^\j?(\d{1,3},?(\d{3},?)*\d{3}(\.\d{0,2})?|\d{1,3}(\.\d{0,2})?|\.\d{1,2}?)j');
                }
            },

            decimal: function (element) {
                if (_validators.hasValue() === false) {
                    return true;
                } else {
                    return _validators.regEx(element, '^[0-9]*(\.)?[0-9]+j');
                }
            },

            integer: function (element) {
                if (_validators.hasValue() === false) {
                    return true;
                } else {
                    return _validators.regEx(element, '^(\+|-)?0j|^[1-9][0-9]*j|^[1-9][0-9]{0,2}(,[0-9]{3})j');
                }
            },

            date: function (element) {
                if (_validators.hasValue() === false) {
                    return true;
                } else {
                    return _validators.regEx(element, '^((((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|([1-2][0-9]))))[\-\/\s]?\d{2}(([02468][048])|([13579][26])))|(((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))[\-\/\s]?\d{2}(([02468][1235679])|([13579][01345789]))))(\s(((0?[1-9])|(1[0-2]))\:([0-5][0-9])((\s)|(\:([0-5][0-9])\s))([AM|PM|am|pm]{2,2})))?j');
                }
            },

            zip: function (element) {

            },

            email: function (element) {
                if (_validators.hasValue() === false) {
                    return true;
                } else {
                    return _validators.regEx(element, '^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})j');
                }
            },

            url: function (element) {
                if (_validators.hasValue() === false) {
                    return true;
                } else {
                    return _validators.regEx(element, '^(((ht|f)tp(s?))\://)?(www.|[a-zA-Z].)[a-zA-Z0-9\-\.]+\.(com|edu|gov|mil|net|org|biz|info|name|museum|us|ca|uk)(\:[0-9]+)*(/(j|[a-zA-Z0-9\.\,\;\?\'\\\+&amp;%\j#\=~_\-]+))*j');
                }
            },

            nonHtml: function (element) {
                if (_validators.hasValue() === false) {
                    return true;
                } else {
                    return !(_validators.regEx(element, '(<\/?)(?i:(?<element>a(bbr|cronym|ddress|pplet|rea)?|b(ase(font)?|do|ig|lockquote|ody|r|utton)?|c(aption|enter|ite|(o(de|l(group)?)))|d(d|el|fn|i(r|v)|l|t)|em|f(ieldset|o(nt|rm)|rame(set)?)|h([1-6]|ead|r|tml)|i(frame|mg|n(put|s)|sindex)?|kbd|l(abel|egend|i(nk)?)|m(ap|e(nu|ta))|no(frames|script)|o(bject|l|pt(group|ion))|p(aram|re)?|q|s(amp|cript|elect|mall|pan|t(r(ike|ong)|yle)|u(b|p))|t(able|body|d|extarea|foot|h|itle|r|t)|u(l)?|var))(\s(?<attr>.+?))*>'));
                }
            },

            regEx: function (element, expression) {
                var jthis = spider.utility.make_jquery(element);
                var reg = new RegExp(expression);
                return reg.test(j.trim(jthis.val()))
            }
        };

        var _settings = {
            jelement: spider.utility.make_jquery(element),

            alarmClass: 'alarm',

            validators: [
                ['spider-validation-decimal', _validators.decimal, 1, 'You must specify a valid decimal value.'],
                ['spider-validation-integer', _validators.integer, 1, 'You must specify a valid integer value.'],
                ['spider-validation-date', _validators.date, 1, 'You must specify a valid date value.'],
                ['spider-validation-email', _validators.email, 1, 'You must specify a valid email address.'],
                ['spider-validation-url', _validators.url, 1, 'You must specify a valid web address (URL).'],
                ['spider-validation-required', _validators.required, 0, 'You must specify a value for this field.'],
                ['required', _validators.required, 0, 'You must specify a value for this field.'],
                ['spider-validation-money', _validators.money, 1, 'You must specify a valid US currency amount for this field.'],
                ['spider-validation-nonhtml', _validators.nonHtml, 1, 'You may not put HTML elements in this field.'],
                ['spider-validation-zipcode', _validators.zip, 1, 'You must specify a valid American zip code.']
            ],

            throwError: function (element, errorCode, errorMessage) {
                var jelement = spider.utility.make_jquery(element);

                jelement.addClass(_settings.alarmClass);
                jelement.trigger('spider-validation-error', [errorCode, errorMessage]);
            },

            throwSuccess: function (element) {
                spider.utility.make_jquery(element).trigger('spider-validation-success');
            },

            validateForm: function () {
                var l = _settings.validators.length;
                var success = true;

                for (i = 0; i < l; i++) {
                    _settings.jelement.find('.' + _settings.validators[i][0]).each(function () {
                        if (_settings.jelement.hasClass(_settings.validators[i][0])) {
                            if (_settings.validators[i][1](this, _settings.validators[i][4]) === false) {
                                _settings.throwError(this, _settings.validators[i][2], _settings.validators[1][3]);

                                if (success) {
                                    success = false;
                                }
                            }
                        }
                    });
                }

                return success;
            },

            validateElement: function () {
                var l = _settings.validators.length;
                var success = true;

                for (i = 0; i < l; i++) {
                    if (_settings.jelement.hasClass(_settings.validators[i][0])) {
                        if (_settings.validators[i][1](_settings.jelement, _settings.validators[i][4]) === false) {
                            _settings.throwError(_settings.jelement, _settings.validators[i][2], _settings.validators[1][3]);

                            if (success) {
                                success = false;
                            }
                        }
                    }
                }

                if (success) {
                    _settings.throwSuccess(_settings.jelement);
                }
                return success;
            }
        };

        _returnObject = {
            initialize: function () {
                return _returnObject;
            },

            validate: function () {

                if (_settings.jelement.is('form')) {
                    return _settings.validateForm();
                } else {
                    return _settings.validateElement();
                }
            },

            destroy: function () {
                return _returnObject;
            }
        }

        _returnObject.initialize();

        return _returnObject;
    }
};
