AjaxForm = Class.create();

AjaxForm.prototype = {

    form   : null,

    initialize : function(form)
    {
        this.form = $(form);
        this.form.observe('submit', this.onSubmit.bindAsEventListener(this));
        this.resetErrors();
	},

    resetErrors : function()
    {
       $$('div.form_element div.error').invoke('hide');
       $('messages').hide();
    },

    showError : function(key, val)
    {
        var container = $(key);
        if (container) {
            container.update(val);
            new Effect.BlindDown(container, {duration: 0.5});
        }
    },

    /**
     * let child class has chance to update its own data logic,
     * especially to add tinyMCE input.
     * @todo: allow to add tinyMCE field to AjaxForm so config in view.phtml file like this 
     * - {tinymce mode='full' elements = 'description' height=600}
     * can be generated dynamically in javascript.
     */
    _beforeOnSubmit: function(data){
    	return data;
    },
    
    /**
     * let child class has chance to validate form with its own data logic,
     * @return
     */
    _validate: function(){
    	return true;
    },
    
    onSubmit : function(e)
    {
    	Event.stop(e);
    	
    	if(!this._validate()){
    		return;
    	}
        
        var data;
        if(typeof(tinyMCE) != 'undefined'){
	        data = $H(this.form.serialize(true));
	        if(!Object.isUndefined(tinyMCE.get('source'))){
	        	data.set('source', tinyMCE.get('source').getContent());
	        }
	        data = this._beforeOnSubmit(data);
        }else{
        	data = this.form.serialize();
        	data = this._beforeOnSubmit(data);
        }
        
        var options = {
            parameters : data,
            method     : this.form.method,
            onSuccess : this.onFormSuccess.bind(this)
        };
        this.resetErrors();
        new Ajax.Request(this.form.action, options);
    },

    /**
     * let child class has chance to do form processing with its own data logic,
     * @return
     */
    _beforeOnFormSuccess: function(transport){
    	
    },
    
    onFormSuccess : function(transport)
    {	
    	this._beforeOnFormSuccess(transport);
    	
       	if(transport.responseText == 'good'){
       		this.form.submit();
       	}else{
       		var json = transport.responseText.evalJSON();
        	var errors = $H(json.errors);
        	var messages = $H(json.messages);
			
        	if (errors.size() > 0) {
        		this.form.up('fieldset').scrollTo();
        		errors.each(function(pair) {
					var key = 'errors-'+pair.key;
					this.showError(key, pair.value);
				}.bind(this));
        	}
        	
        	if(messages.size() > 0){
        		var container = $('messages');
        		var html;
        		container.scrollTo();
        		if(messages.size() > 1){
        			html = '<ul>';
        			messages.each(function(pair) {
        				html += '<li>';
        				html += pair.value;
        				html += '</li>';
        			});
        			html += '</ul>';
        		} else {
        			html = messages.values();
        		}
        		container.update(html);
        		new Effect.BlindDown(container);
        	}

        	if(json.reload == true){
        		window.location.reload();
        	}
        	
        	if(json.redirect.length > 0){
        		window.location.href = json.redirect;
        	}
        }
    }
};

