/**
 * Форма, которую можно отправлять как по ajax так и обычным способом. При отправке по ajax она после возвращения ответа перезаписывает сама себя.
 *
 */

/**
 * @param form - форма или идентификатор формы, которую нужно отправлять через ajax
 * @param callback - функция, которая вызывается после ответа сервера. Можно использовать стандартные коллбэки:
 *                   AjaxForm.redirectCallback - редиректит на страницу, указанную в ответе в параметре redirect_to
 *                   AjaxForm.refreshCallback  - обновляет форму, подставляя вместо неё html, переданный в параметре form ответа
 */
var AjaxForm = function(form, callback) {

    this.form = null;
    if ( this.form = $(form) ) {
        this.form_id = this.form.get("id")
    } else {
        return;
    }
    
    var callback = callback ? callback : null;

    this.activate = function() {
        var form = $(this.form_id);
        if( form ) {
            AjaxSubmitter.setAllSubmitsAjax(form, callback ? callback.bind(this) : null);
            AjaxSubmitter.setAjaxSubmit(form, callback ? callback.bind(this) : null);

            // для каждого элемента на основании тайтла ставим inline hint
            form.getElements("input").each(function(input) {
                if (input.get("title")) {
                    InlineHint.appendTo(input, input.get("title"));
                }
            });
        }
    }

    this.activate();

}

AjaxForm.redirectCallback = function(response) {
    response = JSON.decode(response);

    if(!response.result ) {
        AjaxSubmitter.showFormErrors( this.form_id, response.messages);
        return;
    }

    document.location = response.redirect_to;
},

AjaxForm.refreshLocationCallback = function(response) {
    response = JSON.decode(response);

    if(!response.result ) {
        AjaxSubmitter.showFormErrors( this.form_id, response.messages);
        return;
    }

    document.location.reload();
}

AjaxForm.refreshCallback = function(response) {
    response = JSON.decode(response);

    if(!response.result ) {
        AjaxSubmitter.showFormErrors( this.form_id, response.messages);
        return;
    }

    var form = $(this.form_id);
    var holder = new Element('div');
    holder.set('html', response.form);
    holder.firstChild.replaces(form);

    this.activate();
}

var AjaxSubmitter = function () {

    // Выключить все сабмиты в форме (нужно для правильной отправки)
    function disableSubmits( form ) {
        if( $(form) ) {
            $(form).getElements('button').set('disabled', true);
            $(form).getElements('input[type=submit]').set('disabled', true);
        }
    }

    // Включить все сабмиты в форме (нужно для правильной отправки)
    function enableSubmits(form) {
        if( $(form) ) {
            $(form).getElements('button').set('disabled', false);
            $(form).getElements('input[type=submit]').set('disabled', false);
        }
    }

    // Подтвердить действие
    function confirmAction() {
        return window.confirm("Вы действительно хотите это сделать?");
    }

    // Обрабатывает ответ от сервера стандартным образом - показывает ошибки или перезагружает страницу
    function handleAjaxSubmitResponse(form_id, response_text) {
        var response = JSON.decode(response_text)

        if( response.result ) {
            document.location = response.redirect_to;
        } else {
            AjaxSubmitter.showFormErrors(form_id, response.messages);
        }
    }

    var $o = {
        // Показать ошибки формы, возвращённые formProcessorом
        'showFormErrors' : function(form_id, messages) {
            var msg = '';
            for ( var i in messages ) {
        		msg += messages[i];
                break;
            }
            msg = msg.replace( '<p></p>', '' );

            Notification.show(msg);
            setTimeout( Notification.hide, 1300 );
        },

        // Отправялет форму по Ajax, устанавливая нужный коллбэк
        'submitFormAjax' : function(form, callback, pressed_button){
            form = $(form);
            if ( ! form ) {
                return;
            }

            if ( ! form.action ) {
                form.action = document.location;
            }

            $$( ".form_error" ).dispose();

            if( !pressed_button || pressed_button.hasClass('hidden') ) {
                var buttons = form.getElements('input[type="submit"]');
                pressed_button = buttons[buttons.length-1];
            }
            var loader = new PreLoader( pressed_button, {
                'position' : 'after'
            });
            loader.show();

            // Заполняем форму реальными значениями (если были инлайн-хинты)
            form.getElements("input").each(function(el) {
                if( el.getValue ) {
                    el.value = el.getValue()
                }
            });

            if( !form.getElement('input[name="format"]')) {
                form.appendChild(new Element('input', {'type' : 'hidden', 'name' : 'format', 'value' : 'json'})); // Добавляем формат
            }

            form.set("send", {
                onRequest: function() {

                },
                onSuccess: function(response) {
                    loader.hide();

                    if (callback instanceof Function ) {
                        callback(response);
                    } else {
                        handleAjaxSubmitResponse(form, response);
                    }
                },
                onFailure: function() {
                    loader.hide();
                }
            } );
            form.send();

            //Восстанавливаем значения подсказок
            form.getElements( "input" ).each( function( el ) {
                if ( el.getValue ) {
                    el.fireEvent( 'blur' );
                }
            });
        },

        // Устанавливает режим отправки формы через ajax (событие submit)
        'setAjaxSubmit' : function(form, callback, confirm) {
            if( $(form) ) {
                $(form).addEvent("submit", function(event) {
                    new Event(event).stop();

                    if ( !confirm || ( confirm && confirmAction())) {
                        AjaxSubmitter.submitFormAjax(form, callback);
                    }
                } );
            }
        },

        // Устанавливает отправку формы по ajax при нажатии на указанную кнопку
        'setButtonAjaxSubmit' : function(button, callback, confirmation) {
            button = $(button);
            if( button ) {
                button.addEvent("click", function(event) {
                    event.stop();
                    if(!confirmation || (confirmation && confirmAction(confirmation))) {
                        form = button.form;
                        disableSubmits(form);
                        var hid = new Element('input', {'type':'hidden', 'name': button.name, 'value': button.value});
                        button.form.appendChild(hid);
                        AjaxSubmitter.submitFormAjax(button.form, callback, button);
                        hid.dispose();
                        enableSubmits(form);
                    }
                } );
            }
        },

        // Устанавливает отправку формы по ajax при нажатии любой кнопки в ней
        'setAllSubmitsAjax' : function(form, callback, confirmation) {
            form = $(form);
            if( form ) {
                form.getElements('button').each(function(elem) { AjaxSubmitter.setButtonAjaxSubmit(elem, callback, confirmation)} );
                form.getElements('input[type=submit]').each(function(elem) { AjaxSubmitter.setButtonAjaxSubmit(elem, callback, confirmation)} );
            }
        }
    }

    return $o;
}();

var NewAjaxForm = new Class( {
	Implements : [ Events, Options ],
	
	options : {
		form_el : null,
		loader : null,
		loader_opts : {
			'position' : 'after'
		},
		format : 'json'
	},

	initialize : function ( form, opts ) {
		this.options.form_el = form;
		var self = this;
		if ( !form.action ) {
			form.action = location.href;
		}
		
		if ( !form.getElement( 'input[name="format"]' ) ) {
            form.appendChild( new Element('input', {'type' : 'hidden', 'name' : 'format', 'value' : self.options.format } ) );
        }
			
		form.set( "send", {
            onRequest: function() {

            },
            onSuccess: function () {
            	self.options.loader.hide();
            	
            	self.fireEvent( 'onSuccess', arguments );
            },
            onFailure: function() {
            	self.options.loader.hide();

                self.fireEvent( 'onFailure', arguments );
            }
        } );
		
		form.getElements( 'input[button]' ).extend( form.getElements( 'input[type=submit]' ) ).addEvent( 'click', function ( e ) {
			e.stop();

			self.options.loader = new PreLoader( this, self.options.loader_opts );
			
			self.options.loader.show();
			form.send();
		} );
		
		this.setOptions( opts );
	}
} );
