/**
* Vinter.validate()
* Version 1.6
* Updated 9 jan 2008
*
*       Vinter.validate is (c) 2008 Lars Huring, Olov Nilzén and Vinter (www.vinterwebb.se) and is released under the MIT License:
*       http://www.opensource.org/licenses/mit-license.php
*
* Changelog:
* 1.1:
* - Added checkbox validation
* - Added checkbox groups validation
* - Added isNumber validation
* - Added onerror callback handler
*
* 1.2:
* - Added selectbox validation
* - Added file-validation
*
* 1.3
* - Added radiobutton validation
* - Added textarea validation
*
* 1.4
* - Added possibility to send html in errmsg
* - Fixed removal of notvalidclass on each validation.
*
* 1.5
* - Added possibility to check against default value (title attribute).
* - Added id to error li:s for possibity to hide em'
* - Updated the examples and added a little more documentation
*
* 1.6
* - Added selectbox default values array
* - Added "defaultval" class to <option>, config: selectboxdefaultclass
* - Added selectbox validation to example
*
* Usage:
* Simple: <input type="submit" value="skicka" onclick="return jQuery.validate();" />
* Advanced: http://labs.vinterwebb.se/jquery.validate/Default.aspx
*/
(function($) {

        $.validate = function(options)
        {

                // Set up some options
                options = options || {};
                options.fieldset = options.fieldset || "";
                options.messagecontainer = options.messagecontainer || "#validationmsg";
                options.errormsg = options.errormsg || ".errmsg";
                options.notvalidclass = options.notvalidclass || "notvalid";
                options.messageheader = options.messageheader || "Hittade några problem i formuläret";
                options.onerror = options.onerror || "";
                options.erroridprefix = options.erroridprefix || "validationerror_";
                options.selectboxdefault = options.selectboxdefault || [""];
                options.selectboxdefaultclass = options.selectboxdefaultclass || "defaultval";
                options.usedefault = options.usedefault || false;

            var errors = new Array();
                $(options.messagecontainer).empty();

                $("." + options.notvalidclass).each(function(i, item) {
                        $(item).removeClass(options.notvalidclass);
                });

           function isEmail(str)
            {
                    var regex = /^[a-zA-Z0-9._-]+@([a-zA-Z0-9.-]+\.)+[a-zA-Z0-9.-]{2,4}$/;
                    return regex.test(str);
            }

            function isNumber(str)
            {
                    var regex = /^[0-9]+$/;
                    return regex.test(str);
            }

            function isFloat(str)
            {
                    var regex = /^[0-9]+\.?[0-9]*$/;
                    return regex.test(str);
            }

            function isEmpty(item)
            {
                    if (item.value == "")
                        return true;

            if (options.usedefault && item.value == $(item).attr("title"))
                return true;

            return false;
            }

                function getMsg(item)
                {
                        return $(item.parentNode).find(options.errormsg).html();
                }

                function validateTextBox(item)
                {
                        if (isEmpty(item) == true || ($(item).hasClass("email") && isEmail(item.value) == false))
                                errors.push({id: item.id, msg: getMsg(item), type: "text"});

                        if (isEmpty(item) == false)
                         {
                          if ($(item).hasClass("number") && isNumber(item.value) == false)
                                errors.push({id: item.id, msg: getMsg(item), type: "number"});
                          if ($(item).hasClass("float") && isFloat(item.value) == false)
                                errors.push({id: item.id, msg: getMsg(item), type: "float"});
                         }
                }

                function validateTextBox2(item)
                {
                        if (isEmpty(item) == true) return;

                        if ($(item).hasClass("number") && isNumber(item.value) == false)
                                errors.push({id: item.id, msg: getMsg(item), type: "number"});

                        if ($(item).hasClass("float") && isFloat(item.value) == false)
                                errors.push({id: item.id, msg: getMsg(item), type: "float"});

                        if ($(item).hasClass("email") && isEmail(item.value) == false)
                                errors.push({id: item.id, msg: getMsg(item), type: "text"});

                }

                function validateCheckbox(item)
                {
                        if(item.checked != true)
                                errors.push({id: item.id, msg: getMsg(item), type: "checkbox"});
                }

                function validateSelect(item)
                {
                        if ($.inArray(item.value, options.selectboxdefault) > -1 || item[item.selectedIndex].className == options.selectboxdefaultclass)
                                errors.push({id: item.id, msg: getMsg(item), type: "select-one"});
                }

                /*
                * Validate checkbox groups
                */
                $(options.fieldset + " .checkboxgroup," + options.fieldset + " .radiogroup").each(function(i, item) {

                        var checked = 0;
                        var msg = $(item).find(options.errormsg).text();

                        $(item).find("input[type=checkbox], input[type=radio]").each(function(i, item) {
                                if (item.checked)
                                        checked++;
                        });

                        if(checked == 0)
                                errors.push({id: item.id, msg: msg, type: "group"});

                });

                // Loop
                $(options.fieldset + " .required").each(function(i, item) {

                        // Checkboxes
                        switch (item.type)
                        {
                                case "checkbox":
                                        validateCheckbox(item);
                                        break;

                                case "text":
                                case "file":
                                case "textarea":
                                        validateTextBox(item);
                                        break;

                                case "select-one":
                                        validateSelect(item);
                        }

                });

                // Loop
                $(options.fieldset + " .notrequired").each(function(i, item) {

                        switch (item.type)
                        {
                                case "text":
                                case "file":
                                case "textarea":
                                        validateTextBox2(item);
                        }

                });

                /*
                * Check errors length and output to page.
                */
                if (errors.length > 0)
                {

                        // Onerror returns errors array to callback
                        if (typeof(options.onerror) == "function")
                        {
                                options.onerror(errors);
                                return false;
                        }

                        $(options.messagecontainer).fadeIn("slow");

                        $("<h4/>")
                                .text(options.messageheader)
                                .appendTo($(options.messagecontainer));

                        var ul = $("<ul/>");

                        $(errors).each(function(i, item) {

                                $("#" + item.id).addClass(options.notvalidclass);
                                $("<li />").html(item.msg).attr("id", options.erroridprefix + item.id).appendTo(ul);

                        });

                        ul.appendTo($(options.messagecontainer));

                        return false;
                }

                // Hide if there are no errors
                $(options.messagecontainer).fadeOut();
                return true;

        }

})(jQuery);
