var FormControl = Class.create(BaseControl, {
    form: null,
    noreload:null,
    url:null,
    container:null,

    initialize: function($super, element)
    {
        $super(element);
        this.noreload = this.view.hasClassName('noreload');
        if (this.view.hasClassName('stub'))
            this.render();
        else
            this.observeEvent();
    },

    observeEvent: function()
    {
        var me = this;
        this.view.observe('keypress', function(event){
            if (event.keyCode == 13 && (event.target.tagName=='INPUT'))
            {
                me.submitSaveForm();
                // :BUG: hoannd003 Stop to prevent submit form again because the default button click is call when ENTER key downs
                //  Solution: stop event
                event.stop(); 
            }
        });
        this.find('.submit').invoke('observe', 'click', function(){
            me.submitSaveForm();
        });
    },

    find: function()
    {
        var me = this;
        var args = $A(arguments);
        args.each(function(a, index){
            if (a[0]=='.') args[index] = me.container + a;
            else args[index] += me.container;
        });
        return Selector.findChildElements(this.view, args);
    },

    findOne: function(selector)
    {
        return this.find(selector).first();
    },

    checkForChanges: function(){},

    checkForFilterChanges: function(){},

    formBeforeSubmit: function(){},

    discardAllChanges: function(){},

    loadview: function($super, element)
    {
        $super(element);
        this.form = this.view.up('form');
        this.url = this.view.getAttribute('url');
        this.container = this.view.hasClassName('xcontainer') ? '.' + this.view.id : '';
    },

    render: function()
    {
        var params = this.getLocationHash();
        this.find('input').each(function(e){
            params[e.name] = e.value;
        });
        this.requestAjax(params);
    },

    refresh: function()
    {
        if (this.checkForChanges())
        {
            if (!confirm('Do you want to discard all changes?')) return;
            else this.discardAllChanges();
        }
        this.checkForFilterChanges();
        this.submitForm();
    },

    //Sumit form with handle function
    refreshWithHandler: function(oncompleteHandler, dontAutoProcess)
    {
        this.submitForm(oncompleteHandler, dontAutoProcess);
    },

    submitSaveForm: function()
    {                
        if (this.checkForChanges())
        {             
            this.setFormAction('save');
            this.checkForFilterChanges();
            this.submitForm();
        }
        else if (this.checkForFilterChanges())
        { 
            this.submitForm();
        }
    },

    submitForm: function(oncompleteHandler, dontAutoProcess)
    {                      
        if (!dontAutoProcess)
            this.formBeforeSubmit();      
        
        if (this.view.hasClassName('noajax'))
            this.submitFormNormal();
        else
            this.submitFormAjax(oncompleteHandler, dontAutoProcess);
    },

    submitFormAjax: function(oncompleteHandler, dontAutoProcess)
    {                     
        var action = this.getFormAction();        
        if (!action){
            var hashable = this.getHashable();
            this.setLocationHash(hashable);
        } 
        var params = this.serialize();  
        
        if (!dontAutoProcess)
            this.showAjaxloader();
        this.requestAjax(params, oncompleteHandler, dontAutoProcess);
    },

    getHashable: function()
    {
        var elements = this.find('input:not(.nohash)', 'select:not(.nohash)', 'textarea:not(.nohash)');
        return Form.serializeElements(elements);
    },

    setValue: function(e, value)
    {
        if (Object.isUndefined(e.originValue)) e.originValue = e.value;
        if (value != e.originValue){
            e.addClassName('changed');
            e.value = value;
        }
    },

    requestAjax: function(params, oncompleteHandler, dontAutoProcess)
    {
        var me = this;
        var wrapper = this.view.up();
        var action = this.getFormAction();
        Client.ajax(this.url, {
            parameters: params,
            onComplete: function(response){
                if (!dontAutoProcess)
                {
                    if(me.noreload)
                    {
                        me.hideAjaxloader();
                        me.find('.msgflash').invoke('update', response);
                    }
                    else
                    {
                        wrapper.update(response);
                        me.loadview(wrapper.down(me.selector));
                        me.ajaxComplete();
                        me.observeEvent();
                    }
                }
                
                if (oncompleteHandler)
                    oncompleteHandler(this, response);
                    
                me.fire('ajaxcomplete', {action: action});
            }
        });
    },


    ajaxComplete: function()
    {
    },

    hideAjaxloader: function()
    {
        this.find('.loading_bar_holder').each(function(e){
            e.update('');
        });
        this.find('.loading_circle_holder').each(function(e){
            e.update('');
        });
    },

    showAjaxloader: function()
    {
        this.find('.loading_bar_holder').each(function(e){
            e.update('<input type="button" class="loading_bar"></input>');
        });
        this.find('.loading_circle_holder').each(function(e){
            e.update('<div class="loading_circle"></div>');
        });
        this.find('.loading_longbar_holder').each(function(e){
            e.update('<div class="ajaxloading"></div>');
        });
    },

    submitFormNoajax: function()
    {
        this.form.action = this.url;
        this.submitFormNormal();
    },

    submitFormNormal: function()
    {
        var action = this.getFormAction();
        if (action) this.form.method = 'post';
        this.form.submit();
    },

    setFormAction: function(action)
    {
        this.findOne('.action').value = action;
        return this;
    },

    getFormAction: function()
    {
        var e = this.findOne('.action');
        return e ? e.value : null;
    },

    setLocationHash: function(params)
    {
        this.setHash(this.name, params);
    },

    getLocationHash: function()
    {
        var hash = this.getHash(this.name);
        if (!hash) hash = '';
        return hash.toQueryParams();
    },

    setHash: function(key, value)
    {
        var value = value.replace(/&/g, ';').replace(/=/g, ':');
        History.set(key, value);
    },

    getHash: function(key)
    {
        var value = History.get(key);
        return value ? value.replace(/;/g, '&').replace(/:/g, '=') : null;
    }
});