(function($) {   
    $.fn.safix = function() {}
    
    $.safix = {
        getInput: function(selector) {
            return (!selector.is(':input'))? selector.find(':input'): selector;
        }
    }
    
    $.sfFunctions = {
        numberFormat: function(number, decimals, dec_point, thousands_sep ) {   
            // Format a number with grouped thousands
            // 
            // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
            // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
            // +     bugfix by: Michael White (http://crestidg.com)

            var i, j, kw, kd, km;

            // input sanitation & defaults
            if( isNaN(decimals = Math.abs(decimals)) ){
                decimals = 2;
            }
            if( dec_point == undefined ){
                dec_point = ",";
            }
            if( thousands_sep == undefined ){
                thousands_sep = ".";
            }

            i = parseInt(number = (+number || 0).toFixed(decimals)) + "";

            if( (j = i.length) > 3 ){
                j = j % 3;
            } else{
                j = 0;
            }

            km = (j ? i.substr(0, j) + thousands_sep : "");
            kw = i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands_sep);
            //kd = (decimals ? dec_point + Math.abs(number - i).toFixed(decimals).slice(2) : "");
            kd = (decimals ? dec_point + Math.abs(number - i).toFixed(decimals).replace(/-/, 0).slice(2) : "");


            return km + kw + kd; 
        },
        
        isFloat: function(value) {
            return /^\d*(\.?)\d*?$/.test(value);    
        },
        
        isInt: function(value) {
            return /^\d+$/.test(value);    
        },
        isEmail: function(value) {
            return /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value);
        }
    }
    
    //Показать сообщение
    $.fn.sfShowMessage = function(message, typeMessage, br, options) {
        var defaults = {
            message: message,
            typeMessage: typeMessage,
            br: br,
            htmlElement: 'span',
            errorClass: 'infobox_error',
            successClass: 'infobox_success'
        };
        var options = $.extend(defaults, options);
        
        input = $.safix.getInput($(this));        
        $(this).sfHideMessage();
        eclass = (options.typeMessage == 1)? options.successClass: options.errorClass; 
        fclass = '';
        if (options.br == 1) {
            fclass = 'block';
        }
        
        $(this).after('<'+ options.htmlElement +' ename="'+ input.attr('name') +'" class="'+ eclass +' '+ fclass +'">' + options.message + '</'+ options.htmlElement +'>');
    }
    //Скрыть сообщение
    $.fn.sfHideMessage = function(message, typeMessage, br, options) {
        $(this).parents('form').find('[ename]').remove();
    }
    
    $.fn.sfValidateValueOnline = function(options) {
        var defaults = {
            errorClass: 'input_error',
            attr: 'validateo',
            keyRepresentation : {
                8    : 'backspace',
                9    : 'tab',
                13    : 'enter',
                16    : 'shift',
                17    : 'control',
                18    : 'alt',
                27    : 'esc',
                33    : 'page up',
                34    : 'page down',
                35    : 'end',
                36    : 'home',
                37    : 'left',
                38    : 'up',
                39    : 'right',
                40    : 'down',
                45    : 'insert',
                46    : 'delete',
                116   : 'f5',
                123   : 'f12',
                224   : 'command'
            }
        };
        var options = $.extend(defaults, options);
        
        $(this).find(':input['+ defaults.attr +']').bind('keypress', function(event) {
            parts = $(this).attr(defaults.attr).split(',');
            bExit = false;
 
            for (i = 0; i < parts.length; i++) {
                if (bExit) {
                    break;
                }
                switch (parts[i]) {
                    case 'float': reg = /^\d+((?=>\.|,)\d*|)$/;
                        break;
                    case 'int': reg = /^\d+$/;
                        break;
                    default: reg = /^.*$/;
                }
                
                if (event.keyCode == 0) {
                    return (event.charCode == 0 || reg.test($(this).val() + String.fromCharCode(event.charCode)))    
                } else {
                    return (typeof(defaults.keyRepresentation[event.keyCode]) != 'undefined') || reg.test($(this).val() + String.fromCharCode(event.keyCode));
                }
            }    
        });
    }
    //Валидация поля
    $.fn.sfValidateValue = function(options) {
        var defaults = {
            errorClass: 'input_error',
            attr: 'validate'  
        };
        var options = $.extend(defaults, options);
        
        var submit = true;
        
        $(this).find(':input['+ defaults.attr +']').bind('keyup focus', function() {
            parts = $(this).attr(defaults.attr).split(',');
            bExit = false;
            $(this).parents('form').attr('notsubmit', '0');
                
            for (i = 0; i < parts.length; i++) {
                if (bExit) {
                    break;
                }
                switch (parts[i]) {
                    case 'float': reg = /^\d*(\.?|,?)\d*$/;
                        break;
                    case 'int': reg = /^\d+$/;
                        break;
                    case 'proc_int': reg = /^\d{1,2}$/;
                        break;
                    case 'email': reg = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i;
                        break;
                    default: reg = '/^.*$/';
                }
                
                if (!reg.test($(this).val())){
                    $(this).addClass(defaults.errorClass);
                    bExit = true;
                    $(this).parents('form').attr('notsubmit', '1');
                } else {
                    $(this).removeClass(defaults.errorClass);   
                }
            }       
         }); 
         
         $(this).bind('submit', function() {
            return (!($(this).attr('notsubmit') == 1));
         });
         
         $(this).bind('reset', function() {
            $(this).find(':input[validate]').removeClass(defaults.errorClass); 
            $(this).attr('notsubmit', '0');
        });  
    } 
    
    //Валидая формы
    $.fn.sfValidator = function(options) {
        var defaults = {
            errorElement: 'span',
            errorClass: 'infobox_error',
            validate: function () {},
        };
        var options = $.extend(defaults, options);

        $(this).bind('reset', function() {
            $(this).find('[ename]').remove().empty();
            $(this).find('[emessage]').removeAttr('emessage').removeAttr('typeMessage');  
        });
        
        $(this).bind('submit', function() {
            
            $(this).find('[ename]').remove().empty();
            $(this).find('[emessage]').removeAttr('emessage').removeAttr('typeMessage');
        
            options.validate();
            
            form = $(this);  
            count = $(this).find('[emessage]').each(function() {
                $(this).after('<'+ options.errorElement +' ename="'+ $(this).attr('name') +'">' + $(this).attr('emessage') + '</'+ options.errorElement +'>');
                
                fclass = '';
                if ($(this).attr('ebr') == 1) {
                    fclass = 'block';
                }
                
                form.find('[ename='+ $(this).attr('name') +']').addClass(options.errorClass).addClass(fclass);
            }).size();
        
            return (count > 0)? false: true;
        });
        
        return $(this);
    }; 
})(jQuery);

$(document).ready(function() {
    $('form').sfValidateValue();     
    $('form').sfValidateValueOnline();     
});
