

var Validate = Validate || { };

// Prevent form from actually submitting before validation finishes
$(function() {
    $('#zvCalcValidationForm').bind('submit', function(e) {
        e.preventDefault();
        jsValidate();
    });
});

/**
 * Escape special chars in element names
 */
function cleanElementName(name)
{
    name = name.replace('[', '\\[');
    name = name.replace(']', '\\]');

    return name;
}

function jsValidate()
{
    //Resett all errors
    $('ul[class="zvCalcErrors"]').remove();
    $('*').removeClass('zvCalcInputError');

	
    //Form is valid until we prove it wrong!
    var isValide = true;
	
    //Walk validation object
    $(validateObject).each(function(){
		
        //Current object has validators?
        if (typeof(this.validators) == 'undefined') {
            return;
        }
		
        //Get form element
        var element = $(':input[name*="' + cleanElementName(this.name) + '"]:last');

        //Get Element Value
        var value = '';
        
        if (element.attr('type') == 'radio') {
            var elemName = element.attr('name');
            $(':input[name*="'+ cleanElementName(this.name) +'"]').each(function(){
                if ($(this).attr('checked') == true) {
                    value = $(this).val();
                }
            });
        } else {
            value = (element.attr('nodeName') == 'TEXTAREA') ? element.html() : element.val();
        }
        
        //Walk validators
        var elementErrors = new Array();
        for (var i = 0; i < this.validators.length; i++) {
            var validator = this.validators[i];    			
            var result    = Validate.zfValidate(validator, value);
            //Add error
            if (result !== true) {
                elementErrors.push(this.validators[i].message[result]);
                isValide = false;
            }
        }
		
        //Handle errors for current element
        var errorElement = $(':input[name*="' + cleanElementName(this.name) + '"]:last').parent('label');
        if (!errorElement[0]) {
            errorElement = element;
        }
        Validate.setErrors(errorElement, elementErrors);
		
    });

    if (false === isValide) {
        // Jump to the first error in the DOM
        $('.zvCalcErrors:first').focus();
        return false;
    }

    if (jQuery('.nextLoader').length >= 1) {
    	zvCalcShowLoader();
    }
    
    $('#zvCalcValidationForm').unbind('submit').submit();
    return true;
}

Validate.zfValidate = function(validator, value)
{
    // console.log(validator);
    var name = validator.name;
    return Validate.Framework[name](value, validator.parameters);
}

Validate.setErrors = function(element, messages)
{
    if (messages.length <= 0) {
        return;
    }

    if (element.attr('nodeName') != 'LABEL') {
        $(element).addClass('zvCalcInputError');
    }
    
    var ul = $('<ul class="zvCalcErrors" />');
    var li = $('<li />');
    li.html(messages[0].replace(/%value%/, $(element).attr('value')));
    li.appendTo(ul);
    
    ul.appendTo($(element).closest('.zvCalcElementRow'));
}

Validate.Framework = {
		
    /*
     * Zend_Validate_NotEmpty
     */
    Zend_Validate_NotEmpty:			function(value, parameters)
    {
        if (value != '') {
            return true;
        }
        return 'isEmpty';
    },

    /*
     * Zend_Validate_Digits
     */
    Zend_Validate_Digits:                       function(value, parameters)
    {
        // FIXME Immer zutreffend?
        if ('' == value) {
            return true;
        }

        if (value.match(/^\d+$/)) {
            return true;
        }

        return 'notDigits';
    },
		
    /*
     * Zend_Validate_Regex
     */
    Zend_Validate_Regex:                       function(value, parameters)
    {
    	var regex = new RegExp(parameters.pattern);
        if (regex.test(value)) {
            return true;
        }

        return 'regexNotMatch';
    },
		
    /*
     * Zend_Validate_Alnum
     */
    Zend_Validate_Alnum:			function(value, parameters)
    {
        if (parameters.allowWhiteSpace) {
            if (value.match(/^[a-z0-9\s]*$/i)) {
                return true;
            }
        } else {
            if (value.match(/^[a-z0-9]*$/i)) {
                return true;
            }
        }
        return 'notAlnum';
    },
		
    /*
     * Zend_Validate_InArray
     */
    Zend_Validate_InArray:			function(value, parameters)
    {
        for (var i = 0; i < parameters.haystack.length; i++) {
            if (parameters.haystack[i] == value) {
                return true;
            }
        }
        return 'notInArray';
    },

    /*
     * Zend_Validate_EmailAddress
     * TODO
     */
    Zend_Validate_EmailAddress:			function(value, parameters)
    {
        var reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{1,6})$/;

        if (true === reg.test(value)) {
            return true;
        }

        return 'emailAddressInvalid';
    },
    
    /*
     * Zend_Validate_StringLength
     */
    Zend_Validate_StringLength:		function(value, parameters)
    {
        if (value.length < parameters.min
            && parameters.min != 0)
            {
            return 'stringLengthTooShort';
        }
    	
        if (value.length > parameters.max
            && parameters.max != 0)
            {
            return 'stringLengthTooLong';
        }
    	
        return true;
    },

    /*
     * Zend_Validate_Date
     */
    Zend_Validate_Date:				function(value, parameters)
    {
        var reg = /^[0123]?\d\.[01]?\d\.\d{4}$/;
        if (value != '') {
            if (false === reg.test(value)) {
                return 'dateInvalid';
            }
        }
        return true;
    },

    /*
     * Zend_Validate_Db_NoRecordExists
     */
    Zend_Validate_Db_NoRecordExists:            function(value, parameters)
    {
        return true;
    }
};
