Ext.namespace('Mk');

/**
 * Uniwersalny obiekt formularza
 *  
 * @class Mk.Form
 * @extends Ext.form.FormPanel
 * 
 * @param {Object} config - konfiguracja indywidualna 
 * 
 */ 
Mk.Form = function(config){			
	
	config = config || {};	
	config.send = this.send; // zeby metoda byla dostepna rowniez w form.getForm().send() a nie tylko form.send()
	
	Mk.Form.superclass.constructor.call(this,
		Ext.applyIf(config,{
			buttonAlign : 'right'
			,labelAlign : 'left'
			,labelWidth : '30px'
			,bodyStyle : 'padding: 5px;'
			,monitorValid : true
			,border : false	 	
			,displayMsg : true
		})
	);	
	
}


/**
 * Dodanie metody ktora zwróci wszystkie elementy formularza
 */
Ext.override(Ext.form.BasicForm, {

	/**
     * Retrieves the fields in the form as a set of key/value pairs, using the {@link Ext.form.Field#getValue getValue()} method.
     * If multiple fields exist with the same name they are returned as an array.
     * 
     * Zwraca rowniez pola wylaczone (disabled:true)
     * 
     * @param {Boolean} dirtyOnly (optional) True to return only fields that are dirty.
     * @return {Object} The values in the form
     */
    getAllFieldValues : function(dirtyOnly){
        var o = {},
            n,
            key,
            val;
            
        this.items.each(function(f) {
            if ((dirtyOnly !== true || f.isDirty())) {

            	n = f.getName();
                val = f.getValue();

                // myk na RadioGroup w takim przypadku zwracał obiekt a my chcemy vartosc zaznaczonego radio
                if(Ext.isObject(val) && Ext.isDefined(val.inputValue)){
                	n = val.getName();
                	val = val.inputValue;
                }
				//ofmyk
                
                key = o[n];
                
                if(Ext.isDefined(key)){
                    if(Ext.isArray(key)){
                        o[n].push(val);
                    }else{
                        o[n] = [key, val];
                    }
                }else{
                    o[n] = val;
                }
            }
        });
        return o;
    }
    
    
    /**
     * Returns true if client-side validation on the form is successful.
     * Dodane wyswietlanie błędu w przypadku nie validowania sie wszystkich pol
     *  
     * @return Boolean
     */
    ,isValid : function(){
        var valid = true;
        this.items.each(function(f){
           if(!f.validate()){
               valid = false;
           }
        });
        
        if(!valid)
	    	Ext.Msg.show({
				title: 'Błąd'
				,msg: 'Błędnie wypełniony formularz'
				,icon: Ext.MessageBox.ERROR
				,buttons: Ext.Msg.OK
			});
        
        return valid;
    }
       
});


Ext.extend(Mk.Form, Ext.form.FormPanel,{
	
	/**
	 * Zapisuje formularz tj, wysyla requesta na serwer i odpala odpowiednie metody w przypadku zakonczenia sukcesem lub fiaskiem
	 * @param <code><pre><ul>{Object} config - konfiguracja indywidualna
	 * 		<li>success    {Function} - wywolywana po prawidłowym zwrocie jsona z serwera</li>
	 *  	<li>failure    {Function} - funkcja wywolywana po nie prawidłowym zwrrocie jsona z serwera</li>
	 *  	<li>scope      {Object}   - w ktorego kontekscie maja zostac odpalone metody success/failure</li>
	 *  	<li>displayMsg {Boolean}  - czy ma wyświetla informacje w chmurce (default:true)</li>
	 *  </ul></pre></code>
	 */
	send : function(params){
		
		scope = params.scope || this;
		params.waitMsg = params.waitMsg || 'Proszę czekać';
		params.waitTitle = params.waitTitle || 'Logowanie...';
		
		if (Ext.isDefined(params.success))
			var submitParamsSuccess = params.success;
		if (Ext.isDefined(params.failure))
			var submitParamsFailure = params.failure;
		
		params.success = function(form, resp){
			resp.result.displayMsg = Ext.isDefined(params.displayMsg) ? params.displayMsg : this.displayMsg;
			
			if (Mk.Exceptions.success(resp.result)){
				if (Ext.isFunction(submitParamsSuccess)) submitParamsSuccess.call(scope, form, resp);
			}
			else {
				if (Ext.isFunction(submitParamsFailure)) submitParamsFailure.call(scope, form, resp);
			}			
		}
		
		params.failure = function(form, resp) {
            
			if (!Ext.isDefined(resp.response.status) || resp.response.status == 200){
                
				if (Mk.Exceptions.success(resp.result)){
					if (Ext.isFunction(submitParamsSuccess)) submitParamsSuccess.call(scope, form, resp);
				}
				else {
					if (Ext.isFunction(submitParamsFailure)) submitParamsFailure.call(scope, form, resp);
				}
			}
			else {
                
				Mk.Exceptions.failure({succcess: false, message: Mk.util.ErrorCodes.get(resp.response.status)});
			}
	    }		
		this.submit(params);
	}
	
	
	/**
	 * Ustawia wszystkie fola danego formularza na zablokowane
	 * uruchamia na nich funkcje disable.
	 * Lista xtype które są blokowane w ten sposób :
	 * 'checkbox','combo','compositefield','datefield','field','htmleditor','numberfield','radio','textarea','textfield','timefield','trigger'
	 * 
	 * @param {Boolean} disabled - czy ma disablowac czy enablowac
	 * @param {Array} addAllowedXtype (Optional) - dodanie do standardowych jakiegos xtye do blokowania 
	 * @param {Array} allowedXtype (Optional) - nadpisanie standardowych xtype do blokowania
	 */
	,setDisabledFields: function(disabled, addAllowedXtype, allowedXtype){
		
		addAllowedXtype = addAllowedXtype || [];		
		var allowedDisabledXtypes = allowedXtype || ['checkbox','combo','compositefield','datefield','field','htmleditor','numberfield','radio','textarea','textfield','timefield','trigger'].concat(addAllowedXtype);
		
		try {		  			
		  	this.getForm().items.each(function(item){
		  		if(Ext.isDefined(item.xtype) && allowedDisabledXtypes.inArray(item.xtype)) 
		  			item[disabled ? 'disable' : 'enable']();
			});
		}
			catch (e){
			Mk.Exceptions.log('Błąd przy wyłaczaniu pól: ' + e);
		}
	}
	
});
