﻿/*

we add a change event to each element that is matched for validation.
we validate it based on the validation type. If it's valid we add the specified class
if not then we don't
*/


(function($) {


    $.fn.vValidate = function(options) {



        if (this.length > 1) {
            alert("vValidate can only be applied to a single DOM element");
            return false;
        }

        //an element can only have one instance of a datasource
        return this.each(function() {
            var element = $(this);
            var lookfor = "vValidate-" + options.applyto;

            // Return early if this element already has a plugin instance
            if (element.data(lookfor)) {
                vLog('vValidate', 'already instantiated!' + lookfor);
                return;
            }
            // pass options to plugin constructor
            var vrs = new vValidate(this, options);

            // Store plugin object in this element's data
            element.data(lookfor, vrs);

            $(document).trigger('vnx-reg-vvalidate', vrs);

        });
    };





    var vValidate = function(element, options) {
        var $element = element;
        var Config = {
            applyto: 'vval',
            validclass: 'valid',
            invalidclass: 'invalid',
            placeholderclass: 'placeholder',
            triggerfailclass: 'validationfailed',
            triggersuccessclass: 'validationsuccess'

        };
        if (options) {
            jQuery.extend(Config, options);
        };
        var Us = this;

        var $lastfailedtrigger = null;


        this.applyto = function() {
            return Config.applyto;
        }

        //make sure placeholder text and labels are correct
        this.initialisevalidators = function($panel) {

            if ($panel == null) {
                $panel = $(document);
            }

            $panel.find('[data-vvl=' + Config.applyto + ']').each(function() {
                var $t = $(this);
                //if nothing in the box then add the placeholder and class
                if (!$t.val()) {
                    var $ph = $t.attr('data-placeholder');
                    if ($ph) {
                        $t.val($ph);
                        $t.addClass(Config.placeholderclass);
                    }
                }
                $t.attr('data-vvlstate', 'init');
            });
            vLog('vValidate', 'Initialised ' + Us.applyto());
        }

        this.focusin = function($elm) {
            //remove the placeholder text and class if needed
            var ph = $elm.attr('data-placeholder');
            if (ph != null && ph == $elm.val()) {
                $elm.val("").removeClass(Config.placeholderclass);
            }
            $elm.attr('data-vvlstate', 'preval');
        }

        this.focusout = function($elm) {
            //add the placeholder text and class if needed or validate
            if ($elm.val() == '') {
                if ($elm.attr('data-placeholder') != null) $elm.val($elm.attr('data-placeholder')).addClass(Config.placeholderclass);
                $elm.attr('data-vvlstate', 'init');
            } else {
                Us.validateone($elm);
            }

        }

        //validate the given group and we can also make an indication
        //on the triggering element (usually a button of some kind)
        this.validategroup = function($trigger) {
            var allvalid = true;
            vLog('vValidate', 'validating group:' + Config.applyto);
            $('[data-vvl=' + Config.applyto + ']').each(function() {
                var $t = $(this);
                var isv = Us.validateone($t);
                allvalid = isv ? allvalid : false;
            });
            if (!allvalid) {
                $trigger.removeClass(Config.triggersuccessclass).addClass(Config.triggerfailclass);
                $lastfailedtrigger = $trigger;
            }
            else {
                $trigger.removeClass(Config.triggerfailclass).addClass(Config.triggersuccessclass);
                $lastfailedtrigger = null;
            }
        }

        //validate everything within the passed fragment element
        this.validatefragment = function($trigger, $fragment) {
            var allvalid = true;
            vLog('vValidate', 'validating fragment for :' + Config.applyto);
            $fragment.find('[data-vvl=' + Config.applyto + ']').each(function() {
                var $t = $(this);
                var isv = Us.validateone($t);
                allvalid = isv ? allvalid : false;
            });
            if (!allvalid) {
                $trigger.removeClass(Config.triggersuccessclass).addClass(Config.triggerfailclass);
                $lastfailedtrigger = $trigger;
            }
            else {
                $trigger.removeClass(Config.triggerfailclass).addClass(Config.triggersuccessclass);
                $lastfailedtrigger = null;
            }

        }

        this.validateone = function($elm) {

            var isrequired = $elm.attr('data-vvl-req') == "true" ? true : false;
            var validationtype = $elm.attr('data-vvl-type');
            if (validationtype == null) validationtype = "text";
            var currentvalue = $elm.val();
            if ($elm.attr('data-placeholder') == currentvalue) {
                if (!isrequired) $elm.val("");
                currentvalue = "";
            }

            var tagn = $elm[0].tagName.toLowerCase();
            var isvalid = false;

            //use - in selects for nothing selected
            if ((currentvalue == "" || currentvalue == "-") && isrequired == true) {
                isvalid = false;
            }
            else {
                switch (validationtype) {
                    case 'required':
                        if (tagn == "select") {
                            if (currentvalue != "-" && currentvalue.length > 0) isvalid = true;
                        }
                        else {
                            if (currentvalue != null && currentvalue.length > 0) isvalid = true;
                        }
                        break;
                    case 'numeric':
                        if (currentvalue != null && currentvalue.length > 0) {
                            //is it a number?
                            var chknum = /^[0-9]*$/;
                            if (chknum.exec(currentvalue)) isvalid = true;
                        }
                        break;
                    case 'email':
                        var filter = /^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$/;
                        isvalid = filter.test(currentvalue); ;
                        break;
                    case 'text':
                        isvalid = true;
                        break;
                    case 'password':
                        isvalid = true;
                        break;
                    case 'decimal':
                        if (currentvalue != null && currentvalue.length > 0) {
                            //is it a number?
                            var chknum = parseFloat(currentvalue)
                            if (chknum == currentvalue) isvalid = true;
                        }
                        break;
                }
            }
            if (isvalid) {
                $elm.removeClass(Config.invalidclass);
                $elm.addClass(Config.validclass);
                $elm.attr('data-vvlstate', 'valid');
            } else {
                $elm.removeClass(Config.validclass);
                $elm.addClass(Config.invalidclass);
                $elm.attr('data-vvlstate', 'invalid');
            }
            if ($lastfailedtrigger != null) {
                //validate the group if we have a previous failed trigger
                $lastfailedtrigger.removeClass(Config.triggerfailclass)
                $lastfailedtrigger = null;
            }
            return isvalid;
        }

        //now actually perform the first initialisation
        Us.initialisevalidators();

    };






})(jQuery);


