Ext.namespace('Ext.ux.Wiz');

/**
 * Licensed under GNU LESSER GENERAL PUBLIC LICENSE Version 3
 *
 * @author Thorsten Suckow-Homberg <ts@siteartwork.de>
 * @url http://www.siteartwork.de/wizardcomponent
 */

/**
 * @class Ext.ux.Wiz.Card
 * @extends Ext.FormPanel
 *
 * A specific {@link Ext.FormPanel} that can be used as a card in a 
 * {@link Ext.ux.Wiz}-component. An instance of this card does only work properly
 * if used in a panel that uses a {@see Ext.layout.CardLayout}-layout.
 *
 * @constructor
 * @param {Object} config The config object 
 */ 
Ext.ux.Wiz.Card = Ext.extend(Ext.FormPanel, {
	
	/**
	 * @cfg {Boolean} header "True" to create the header element. Defaults to
	 * "false". See {@link Ext.form.FormPanel#header}
	 */
	header : false,
	
	/**
	 * @cfg {Strting} hideMode Hidemode of this component. Defaults to "offsets".
	 * See {@link Ext.form.FormPanel#hideMode}
	 */
	hideMode : 'display',

    initComponent : function()
    {
        this.addEvents(
        	/**
        	 * @event beforecardhide
        	 * If you want to add additional checks to your card which cannot be easily done
        	 * using default validators of input-fields (or using the monitorValid-config option), 
        	 * add your specific listeners to this event.
        	 * This event gets only fired if the activeItem of the ownerCt-component equals to
        	 * this instance of {@see Ext.ux.Wiz.Card}. This is needed since a card layout usually
        	 * hides it's items right after rendering them, involving the beforehide-event. 
        	 * If those checks would be attached to the normal beforehide-event, the card-layout 
        	 * would never be able to hide this component after rendering it, depending on the 
        	 * listeners return value.
        	 * 
        	 * @param {Ext.ux.Wiz.Card} card The card that triggered the event
        	 */
            'beforecardhide'
        );  
	
	
        Ext.ux.Wiz.Card.superclass.initComponent.call(this);
        
    },
	
// -------- helper
	isValid : function()
	{
		if (this.monitorValid) {
			return this.bindHandler();	
		}
		
		return true;
	},	
	
// -------- overrides	
    /**
     * Overrides parent implementation since we allow to add any element
     * in this component which must not be neccessarily be a form-element.
     * So before a call to "isValid()" is about to be made, this implementation
     * checks first if the specific item sitting in this component has a method "isValid"
     * to prevent errors.
     */
    bindHandler : function()
    {
        if(!this.bound){
            return false; // stops binding
        }
        var valid = true;
        this.form.items.each(function(f){
            if(f.isValid && !f.isValid(true)){
                valid = false;
                return false;
            }
        });
        if(this.buttons){
            for(var i = 0, len = this.buttons.length; i < len; i++){
                var btn = this.buttons[i];
                if(btn.formBind === true && btn.disabled === valid){
                    btn.setDisabled(!valid);
                }
            }
        }
        this.fireEvent('clientvalidation', this, valid);
    },
    
	/**
	 * Overrides parent implementation. This is needed because in case 
	 * this method uses "monitorValid=true", the method "startMonitoring" must
	 * not be called, until the "show"-event of this card fires. 
	 */
	initEvents : function()
	{
		var old = this.monitorValid;
		this.monitorValid = false;
        Ext.ux.Wiz.Card.superclass.initEvents.call(this);
		this.monitorValid = old;
		
		this.on('beforehide',     this.bubbleBeforeHideEvent, this);
		
		this.on('beforecardhide', this.isValid,    this);
	    this.on('show',           this.onCardShow, this);
		this.on('hide',           this.onCardHide, this);
    },

// -------- listener	
    /**
     * Checks wether the beforecardhide-event may be triggered.
     */
    bubbleBeforeHideEvent : function()
    {
        var ly         = this.ownerCt.layout;
        var activeItem = ly.activeItem;
        
        if (activeItem && activeItem.id === this.id) {
            return this.fireEvent('beforecardhide', this);    
        }
        
        return true;
    },

    /**
     * Stops monitoring the form elements in this component when the
     * 'hide'-event gets fired.
     */
	onCardHide : function()
	{
		if (this.monitorValid) {
			this.stopMonitoring();	
		}
	},

    /**
     * Starts monitoring the form elements in this component when the
     * 'show'-event gets fired.
     */
	onCardShow : function()
	{
	    if (this.monitorValid) {
			this.startMonitoring();	
		}
	}
	
});
