/**
 * ExtJS CardPanel
 * Copyright (C) 2008 Hans-Peter Oeri <hp@oeri.ch>
 * Copyright (C) 2008 Ext JS, LLC.
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 *
 * ----------------------------------------------------------------------
 *
 * Exceptions to the GPL3 apply. See http://extjs.com/products/license.php
 *
 * ----------------------------------------------------------------------
 *
 * @author Hans-Peter Oeri <hp@oeri.ch>
 * @url https://saintcyr.oeri.ch/trac/ext-ux/
 *
 * Adapted from original ExtJS sources.
 */

Ext.namespace('Ext.ux');


/**
 * @class Ext.ux.CardPanel
 * <p>
 * A basic panel container. CardPanels can be used exactly like a
 * standard {@link Ext.Panel} for layout purposes, but also have special
 * support for containing child Components that are managed using a
 * CardLayout layout manager.</p>
 * <p>
 * Each card is simply an {@link Ext.BoxComponent Component} such as a
 * {@link Ext.Panel Panel}. However, when rendered in a CardPanel, each
 * child Component can fire additional events that are not available from
 * other Components. These are:</p>
 * <ul>
 *  <li>
 *   <b>beforeactivate</b>: Fires before this Component becomes the
 *   active card. <div class="mdetail-params"> <strong style="font-weight:
 *   normal;">Listeners will be called with the following arguments:</strong>
 *   <ul>
 *    <li>
 *     <code>newcard</code> : Panel<div class="sub-desc">The card
 *     that will be activated</div></li>
 *    <li>
 *     <code>curcard</code> : Panel<div class="sub-desc">The card
 *     that is currently active</div></li>
 *   </ul>
 *   </div>
 *  </li>
 *  <li>
 *   <b>activate</b>: Fires when this Component becomes the active
 *   card. <div class="mdetail-params"> <strong style="font-weight:
 *   normal;">Listeners will be called with the following arguments:</strong>
 *   <ul>
 *    <li>
 *     <code>card</code> : Panel<div class="sub-desc">The card that
 *     was activated</div></li>
 *   </ul>
 *   </div>
 *  </li>
 *  <li>
 *   <b>beforedeactivate</b>: Fires before this Component gets
 *   deactivated. <div class="mdetail-params"> <strong style="font-weight:
 *   normal;">Listeners will be called with the following arguments:</strong>
 *   <ul>
 *    <li>
 *     <code>curcard</code> : Panel<div class="sub-desc">The card
 *     that will be deactivated</div>
 *    </li>
 *    <li>
 *     <code>newcard</code> : Panel<div class="sub-desc">The card
 *     that will be activated</div>
 *    </li>
 *   </ul>
 *   </div>
 *  </li>
 *  <li>
 *   <b>deactivate</b>: Fires when the Component that was the active
 *   card becomes deactivated. <div class="mdetail-params"> <strong
 *   style="font-weight: normal;">Listeners will be called with the
 *   following arguments:</strong>
 *   <ul>
 *    <li>
 *     <code>card</code> : Panel<div class="sub-desc">The card that
 *     was deactivated</div>
 *    </li>
 *   </ul>
 *   </div>
 *  </li>
 * </ul>
 *
 * @extends Ext.Panel
 * @constructor
 * @param {Object} config The configuration options
 */
Ext.ux.CardPanel = Ext.extend( Ext.Panel, {

	/**
	 * @cfg {Boolean} monitorResize True to automatically monitor window resize
	 * events and rerender the layout on browser resize (defaults to true).
	 */
	monitorResize: true,

	/**
	 * @cfg {Boolean} deferredRender Internally, the CardPanel uses a
	 * {@link Ext.layout.CardLayout} to manage its cards. This property
	 * will be passed on to the layout as its
	 * {@link Ext.layout.CardLayout#deferredRender} config value,
	 * determining whether or not each card is rendered only when first
	 * accessed (defaults to true).
	 */
	deferredRender: true,

	/**
	 * @cfg {Boolean} autoCards
	 * <p>
	 * True to query the DOM for any divs with a class of 'x-card' to be
	 * automatically converted to cards and added to this panel (defaults
	 * to false). Note that the query will be executed within the scope of
	 * the container element only (so that multiple card panels from markup
	 * can be supported via this method).</p>
	 * <p>
	 * This method is only possible when the markup is structured correctly
	 * as a container with nested divs containing the class 'x-card'.</p>
	 */
	autoCards: false,

	/**
	 * @cfg {String} autoCardSelector The CSS selector used to search for cards
	 * in existing markup when {@link #autoCards} = true (defaults to
	 * 'div.x-card'). This can be any valid selector supported by
	 * {@link Ext.DomQuery#select}. Note that the query will be executed
	 * within the scope of this card panel only (so that multiple card
	 * panels from markup can be supported on a page).
	 */
	autoCardSelector:'div.x-card',

	/**
	 * @cfg {String/Number} activeItem A string id or the numeric index of the
	 * card that should be initially activated on render (defaults to none).
	 */
	activeItem: null,

	// private
	initComponent: function() {
		Ext.ux.CardPanel.superclass.initComponent.call(this);
		this.addEvents(
			/**
			 * @event beforechange Fires before the active card changes.
			 *        Handlers can return false to cancel the card change.
			 * @param {CardPanel} this
			 * @param {Panel} newCard The card being activated
			 * @param {Panel} currentCard The current active card
			 */
			'beforechange',
			/**
			 * @event change Fires after the active card has changed.
			 * @param {CardPanel} this
			 * @param {Panel} card The new active card
			 */
			'change'
		);
		this.setLayout( new Ext.layout.CardLayout( {
			deferredRender: this.deferredRender
		} ) );
		this.on( 'remove', this.onRemove, this );
	},

	// private
	render: function(){
		Ext.ux.CardPanel.superclass.render.apply( this, arguments );
		if (this.activeItem !== undefined){
			var item = this.activeItem;
			delete this.activeItem;
			this.setActiveItem(item);
		}
	},

	// private
	onRemove: function(tp, item) {
		if (item == this.activeItem) {
			this.setActiveItem(0);
		}
	},

	/**
	 * Scan the markup in this card panel for autoCards using the
	 * autoCardSelector
	 *
	 * @param {Boolean} removeExisting True to remove existing cards
	 */
	readCards: function( removeExisting ) {
		if (removeExisting === true) {
			this.items.each( function( item ) {
				this.remove( item );
			}, this );
		}

		var cards = this.el.query( this.autoCardSelector );
		for (var i = 0, len = cards.length; i < len; i++) {
			var card = cards[i];
			var title = card.getAttribute( 'title' );
			card.removeAttribute( 'title' );
			this.add({
				title: title,
				el: card
			} );
		}
	},

	/**
	 * Sets the specified card as the active card. This method fires the
	 * {@link #beforechange} event which can return false to cancel the card change.
	 *
	 * @param {String/Panel} card The id or card panel to activate
	 * @return {Boolean} success value
	 */
	setActiveItem: function( item ) {
		item = this.getComponent(item);
		var olditem = this.activeItem;

		if (olditem && olditem.fireEvent( 'beforedeactivate', olditem, item ) === false) {
			return false;
		}
		if (!item || item.fireEvent( 'beforeactivate', item, olditem ) === false) {
			return false;
		}
		if (this.fireEvent( 'beforechange', this, item, olditem ) === false) {
			return false;
		}

		if (!this.rendered) {
			this.activeItem = item;
			return true;
		}

		if (olditem != item) {
			this.activeItem = item;
			this.layout.setActiveItem( item );

			if (olditem) {
				olditem.fireEvent( 'deactivate', olditem );
			}
			item.fireEvent( 'activate', item );
			this.fireEvent( 'change', this, item );
		}

		return true;
	}

	/**
	 * @cfg {Boolean} collapsible
	 * @hide
	 */
	/**
	 * @cfg {String} header
	 * @hide
	 */
	/**
	 * @cfg {Boolean} headerAsText
	 * @hide
	 */
	/**
	 * @property header
	 * @hide
	 */
	/**
	 * @property title
	 * @hide
	 */
	/**
	 * @cfg {Array} tools
	 * @hide
	 */
	/**
	 * @cfg {Boolean} hideCollapseTool
	 * @hide
	 */
	/**
	 * @cfg {Boolean} titleCollapse
	 * @hide
	 */
	/**
	 * @cfg {Boolean} collapsed
	 * @hide
	 */
	/**
	 * @cfg {String} layout
	 * @hide
	 */
	/**
	 * @cfg {Object} layoutConfig
	 * @hide
	 */

} );

Ext.reg('ux.CardPanel', Ext.ux.CardPanel);



