/**
*  jQuery Validarw Plugin
* Copyright (c)  2010  F&aacute;brica de Software
* Dual licensed under the MIT and GPL licenses.
* Author: Valdirene Neves Júnior <valdirene@inf.ceulp.edu.br>
* Dependencies – jquery http://jquery.com/
* Version: 0.1.1
*/

jQuery.fn.extend({
    validate: function (settings) {
        var defaults = {
            errorClass: 'error',
            validClass: 'valid',
            messages: {
                required: "Campo obrigat&oacute;rio.",
                email: "E-mail inv&aacute;lido.",
                url: "Por favor, digite uma URL v&aacute;lida.",
                date: "Por favor, digite uma data v&aacute;lida.",
                dateNoRequired: "Por favor, digite uma data v&aacute;lida.",
                date2: "Por favor, digite uma data v&aacute;lida.",
                date2NoRequired: "Por favor, digite uma data v&aacute;lida.",
                number: "Por favor, digite apenas números.",
                equalTo: "Por favor, indique o mesmo valor novamente.",
                accept: "Por favor, indique um valor com uma extens&atilde;o v&aacute;lida.",
                minlength: "Por favor, n&atilde;o insira menos que {0} caracteres.",
                rangelength: "Por favor, insira um valor entre {0} e {1} caracteres.",
                range: "Por favor, insira um valor entre {0} e {1}.",
                max: "Por favor, indique um valor inferior ou igual a {0}.",
                min: "Por favor, indique um valor maior ou igual a {0}.",
                higherToday: "Por favor, digite uma data maior que hoje",
                dateHigher: "Por favor, digite uma data maior que a data anterior"
            },
            tooltip: {
            }
        }
        var options = jQuery.extend(defaults, settings);

        var findBy = ".required, .email, .url, .date, .dateNoRequired, .date2, .date2NoRequired, .number, [equalTo], [minlength], [rangelength], [range], [max], [min], .higherToday, [dateHigher]";

        //CORPO DO PLUGIN
        var $this = this;

        $(this).find(findBy)
		.each(function (i) {
		    // adiocinando eventos onBlur, onKeypress e onChange
		    addEvents(this);
		});

        function single(object) {
            return check(object);
        }
        function removeTooltip(object, options) {
            var tooltip = $(object).next();
            if (tooltip.hasClass('fsw-tooltip')) {
                tooltip.remove();

                $(object).removeClass(options.errorClass).addClass(options.validClass);
            }
        }
        function renderTooltip(object, options, message) {
            var tooltip = $(object).next();

            // Se o próximo elemento n&atilde;o for da classe "fsw-tooltip" ele pega, caso contr&aacute;rio ele cria uma instância
            if (!tooltip.hasClass('fsw-tooltip')) {
                tooltip = $('<div></div>')
							.css({
							    position: 'absolute',
							    zIndex: 5000,
							    display: 'none',
							    paddingBottom: '0'
							})
							.addClass('fsw-tooltip')
							.append(
								$('<div></div>')
								.css(options.tooltip)
							)
							.insertAfter(object);
            }

            tooltip.find('div').html(message);


            // Remova a classe "valid" e adiciona a classe "error"
            $(object).removeClass(options.validClass)
			.addClass(options.errorClass)
			.hover(function () {
			    if ($(object).hasClass(options.errorClass)) {
			        // Mostra a tooltip quando o mouse estiver encima
			        $(tooltip).show()
						.css({
						    top: $(object).position().top - $(tooltip).height() + 6,
						    left: $(object).position().left + $(object).width() - 142
						}); ;
			        //Adiciona um evento pra quando mexer o mouse

			    }
			},
				function () {
				    $(tooltip).hide();
				}
			)
            addEvents(object);
        }

        function check(object) {
            var valid = true;
            var value = $(object).val();
            var message = $(object).attr('title');

            if ($(object).hasClass('required')) {
                if ($(object).attr('type') == 'radio' || $(object).attr('type') == 'checkbox') {
                    if ($($this).find('[name=' + $(object).attr('name') + ']:checked').length == 0) {
                        message = options.messages.required;
                        valid = false;
                    }
                }

                else if ($(object).val().length < 1) {
                    message = options.messages.required;
                    valid = false;
                }
            }

            if ($(object).hasClass('email') && valid) {
                if (!/^((([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)) {
                    message = options.messages.email;
                    valid = false;
                }
            }

            /* dd/mm/aaaa required */
            else if ($(object).hasClass('date') && valid) {
                if (!/^((0[1-9]|[12][0-9]|3[01])+\/(0[1-9]|1[012])+\/(19|20)\d\d)$/.test(value)) {
                    message = options.messages.date;
                    valid = false;
                }
            }

            /* dd/mm/aaaa no required */
            else if ($(object).hasClass('dateNoRequired')) {

                if ($(object).val().length < 1) {
                    message = options.messages.dateNoRequired;
                    valid = true;
                }

                else if ($(object).val() == '__/__/____') {
                    message = options.messages.dateNoRequired;
                    valid = true;
                }

                else if (!/^((0[1-9]|[12][0-9]|3[01])+\/(0[1-9]|1[012])+\/(19|20)\d\d)$/.test(value)) {
                    message = options.messages.dateNoRequired;
                    valid = false;
                }
            }



            /* mm/aaaa required */
            else if ($(object).hasClass('date2')) {

                if (!/^((0[1-9]|1[012])+\/(19|20)\d\d)$/.test(value)) {
                    message = options.messages.date2;
                    valid = false;
                }
            }

            /* mm/aaaa no required */
            else if ($(object).hasClass('date2NoRequired')) {

                if ($(object).val().length < 1) {
                    message = options.messages.date2NoRequired;
                    valid = true;
                }

                else if ($(object).val() == '__/____') {
                    message = options.messages.date2NoRequired;
                    valid = true;
                }

                else if (!/^((0[1-9]|1[012])+\/(19|20)\d\d)$/.test(value)) {
                    message = options.messages.date2NoRequired;
                    valid = false;
                }
            }

            if (!valid) {
                renderTooltip(object, options, message);
            }
            else {
                removeTooltip(object, options);
            }
            return valid;
        }
        function addEvents(object) {
            return $(object)
			.blur(function () {
			    single(object);
			})
			.change(function () {
			    single(object);
			});
        }
        return {
            checkAll: function () {
                var valid = true;
                $($this).find(findBy)
				.each(function (i) {
				    var is = check(this);
				    if (!is)
				        valid = false;
				});
                if (valid == false) {
                    return false;
                }
                else {
                    return valid;
                }

            }
        };
    }
});

