document.clientValidate = {
    forms:    [],
    elements: [],

    urls:     [],

    locked: false,

    registerId: function(id, url) {
        var element = $('#' + id);
        var form    = element.parents('form');

        if ((i = $.inArray(form.attr('id'), this.forms)) < 0) {
            i = this.forms.push(form.attr('id')) - 1;

            document.clientValidate.elements[i] = [];
            document.clientValidate.urls[i]     = [];
        }

        this.elements[i].push(element.attr('id'));

        this.urls[i].push(url);

        element.bind('change blur', document.clientValidate.checkElement);

        this.checkElements($('input.error'));
    },

    checkElement: function(event) {
        return document.clientValidate.checkElements([this.id]);
    },

    checkElements: function(elements) {
        var that = this;

        $(elements).each(function(index, element) {
            if (typeof(element) == 'string') element = $('#' + element);

            var formIndex    = that.getFormIndex(element.attr('id'));
            var elementIndex = that.getElementIndex(element.attr('id'));

            var url = document.clientValidate.urls[formIndex][elementIndex];
            var parameters = {name: element.attr('name'), value: element.val()};

            $.ajax({
                url: url,
                type: 'post',
                data: parameters,
                context: document.clientValidate,
                complete: function(transport) {
                    if ($.trim(transport.responseText) != '') {
                        document.clientValidate.hideValid(element);
                        document.clientValidate.showError(element, transport.responseText);
                    } else {
                        document.clientValidate.hideError(element);

                        if (element.val() != '') {
                            document.clientValidate.showValid(element);
                        }
                    }
                }
            });
        });
    },

    showError: function(element, error) {
        $(element).addClass('error');

        var next = $(element.next());

        var list = $('<ul></ul>').append($('<li></li>')).attr('class', 'error')
                                                        .html(error);

        if (next.is('ul')) {
            next.replaceWith(list);
        } else {
            list.insertAfter($(element));
        }
    },

    hideError: function(element) {
        element.removeClass('error');

        $(element).next('ul').remove();
    },

    showValid: function(element) {
        if (! $(element).next().is('img')) {
            var img = $('<img />').attr('class', 'valid')
                                  .attr('src', '/media/images/layout/valid.png')
                                  .attr('alt', 'OK')
                                  .attr('title', 'dit veld is juist ingevuld')
                                  .insertAfter($(element));
        }
    },

    hideValid: function(element) {
        $(element).next('img').remove();
    },

    getFormIndex: function(id) {
        var returnVal = null;

        $(this.elements).each(function(index, elements) {
            if ($.inArray(id, elements) != -1) {
                returnVal = index;
            }
        });

        return returnVal;
    },

    getElementIndex: function(id) {
        var returnVal = null;

        $(this.elements).each(function(index, elements) {
            if ($.inArray(id, elements) != -1) {
                returnVal = $.inArray(id, elements);
            }
        });

        return returnVal;
    }
};

