// jQuery extends
jQuery(function(){
    // alerter
    jQuery.blink = function(message, timeout) {
        jQuery("#alert_message").text(message).alignCenter().show();
        setTimeout(function(){
            jQuery("#alert_message").hide().text("");
        }, timeout*1000);
    };

    // align element at window center
    jQuery.fn.alignCenter = function() {
        var marginLeft = Math.max(15, parseInt(jQuery(window).width()/2 - jQuery(this).innerWidth()/2));
        var marginTop  = Math.max(15, parseInt(jQuery(window).height()/2 - jQuery(this).innerHeight()/2));

        return jQuery(this).css({"top":marginTop + "px", "left":marginLeft + "px"});
    };

    // jQuery plugins
    jQuery.fn.extend({
        // ajax form
        ajaxForm: function(options)
        {
            AppForm.enable(this, options);
            return this;
        },
        // ajax box
        ajaxBox: function(options)
        {
            AppAjaxBox.init(this, options || null);
            return this;
        }
    });
});

// Plugin: Ajax box
var AppAjaxBox = {
    // load content into box
    init: function(target, options) {
        if (options !== null) {
            target.data('ajaxbox-options', options);
        } else {
            options = target.data('ajaxbox-options');
        }

        // prevent multiple requests
        if (target.data('ajaxbox-process') || target.data('ajaxbox-error')) return;

        // request data
        jQuery.ajax({
            beforeSend: function() {
                target.data('ajaxbox-process', true);
                AppAjaxBox.enable(target);
            },
            complete: function(xhr) {
                target.data('ajaxbox-process', false);
                AppAjaxBox.disable(target);
            },
            error: function(xhr) {
                if (xhr.status === 0) return;
                target.data('ajaxbox-error', true);
                AppAjaxBox.disable(target);
                jQuery.blink('Application error', 5);
            },
            url: options.url,
            cache: false,
            type: 'get',
            data: options.request,
            dataType: 'html',
            success: function(response) {
                target.html(response);
            }
        });

        return this;
    },
    // loading
    enable: function(target)
    {
        target.empty();
        jQuery("#loading").clone().attr("id", "_loading_" + target[0].id).appendTo(target).show();
    },
    disable: function(target)
    {
        jQuery("#_loading_" + target[0].id).remove();
    }
};

// Ajax loading
var ajaxLoading = {
    enable: function(target)
    {
        if (!target) {
            jQuery("#loading").alignCenter().show();
        } else {
            jQuery("#loading").alignCenter(target).show();
        }
    },
    disable: function(target)
    {
        if (!target) {
            jQuery("#loading").hide();
        } else {
            jQuery("#loading").hide();
        }
    }
};

// Form class
var AppForm = {
    enable: function(form, options)
    {
        // bind ajax_submit to form
        form.bind('ajax-submit', function(event){
            AppForm.submit(this, options);
        });

        // bind submit handler
        jQuery(".ajax_submit", form).click(function(event){
            event.preventDefault();
            form.trigger('ajax-submit');
        });

        // bind cancel handler
        if (options.cancel == "AppPopup.close") {
            jQuery(".ajax_cancel", AppPopup.container).click(function(event){
                event.preventDefault();
                AppPopup.close();
            });
        }
    },
    submit: function(form, options)
    {
        var $form = jQuery(form);

        // prevent multiple requests
        if ($form.data('ajaxform-process') || $form.data('ajaxform-error')) return;

        // can use uploading?
        if (typeof options.upload === 'undefined') {
            options.upload = true;
        }

        // form data
        var request = new Object();
        jQuery.each(form.elements, function(k, field) {
            var name = field.name, type = field.type, tag = field.tagName.toLowerCase();

            // filter fields
            if (!name || field.disabled ||
				type == 'reset' || type == 'button' || type == 'submit' || type == 'file' ||
                ((type == 'checkbox' || type == 'radio') && !field.checked) ||
                (tag == 'select' && field.selectedIndex == -1)) return;

            request[field.name] = field.value;
        });

        // custom request parameters
        if (options.request) {
            jQuery.extend(request, options.request);
        }
		
        // send form data
        jQuery.ajax({
            beforeSend: function() {
                $form.data('ajaxform-process', true);
				if (options.paymentProcess) {
					options.paymentCallbackStart();
				} else {
					ajaxLoading.enable($form);
				}
            },
            complete: function(xhr) {
                $form.data('ajaxform-process', false);
				if (options.paymentProcess) {
					options.paymentCallbackEnd();
				} else {
					ajaxLoading.disable($form);
				}
            },
            error: function() {
                $form.data('ajaxform-error', true);
                jQuery.blink('Application error', 5);
            },
            url: options.action,
            cache: false,
            type: 'post',
            data: request,
            dataType: 'json',
            success: function(xhr) {
                AppForm.response($form, xhr.response);
                // user callback
                if (options.callback) {
                    options.callback($form, xhr);
                }
            }
        });
    },
    response: function(form, response)
    {
        // remove errors
        jQuery("#"+form[0].id+"_errors").hide().empty();
        jQuery('div.error', form).removeClass('error').addClass('noerrors').hide().empty();

        // if has messages, showing it
        jQuery.each(response, function(element, errors){
            // make errors block
            var errstr = '<ul class="errors">';
            jQuery.each(errors, function(key, message){
                errstr += '<li>' + message + '</li>';
            });
            errstr += '</ul>';

            // append errors block to element
            if(element!=='form'){
                jQuery('.'+element+'_errors', form).html(errstr).show()
                    .removeClass('noerrors').addClass('error');
            }else{
                $("#"+form[0].id+"_errors").html(errstr).show();
            }
        });
    }
}

// Popup class
var AppPopup = {
    container: null,
    // showPopup
    open: function(name, request)
    {
        if (this.container !== null) {
            this.close();
        }
        var data = request || {};

        // show fade
        jQuery("#opaco").height(jQuery(document).height()).show().fadeTo("slow", 0.7);

        // get popup contents through ajax
        this.container = jQuery("#popup");

        jQuery.ajax({
            beforeSend: function() {
                AppPopup.enable();
            },
            complete: function(xhr) {
                AppPopup.disable();
            },
            error: function(xhr) {
                if (xhr.status === 0) return;
                jQuery.blink('Application error', 5);
                AppPopup.disable();
            },
            url: '/' + name.replace(/_/g, '/'),
            cache: false,
            data: data,
            dataType: 'html',
            success: function(content){
                AppPopup.container.html(content);
                AppPopup.alignCenter(AppPopup.container);
                AppPopup.container.show();
                jQuery(document).bind("keyup", AppPopup.keyPress);
            }
        });
    },
    // hidePopup
    close: function()
    {
        if (this.container === null) return;

        // hide and empty container
        this.container.hide().empty();
        this.container = null;

        // hide fade
        jQuery("#opaco").hide();

        // bind esc close window
        jQuery(document).unbind("keyup", AppPopup.keyPress);
    },
    // handler for keypress event
    keyPress: function(event)
    {
        // 'esc' key
        if (event.which == 27) {
            AppPopup.close();
        }
    },
    // loading
    enable: function()
    {
        jQuery("#loading").alignCenter().show();
    },
    disable: function()
    {
        jQuery("#loading").hide();
    },
    // align
    alignCenter: function(target)
    {
        var marginLeft = Math.max(15, parseInt(jQuery(window).width()/2 - jQuery(target).innerWidth()/2));
        var marginTop  = Math.max(15, parseInt(jQuery(window).height()/2 - jQuery(target).innerHeight()/2));
        var scrollTop  = parseInt(jQuery(window).scrollTop());
        marginTop = marginTop + scrollTop;

        return jQuery(target).css({"top":marginTop + "px", "left":marginLeft + "px"});
    }
};
