/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/

/**
 * Contains UI features related to an editor instance.
 * @constructor
 * @param {CKEDITOR.editor} editor The editor instance.
 * @example
 */
CKEDITOR.ui = function( editor )
{
	if ( editor.ui )
		return editor.ui;

	/**
	 * Object used to hold private stuff.
	 * @private
	 */
	this._ =
	{
		handlers : {},
		items : {},
		editor : editor
	};

	return this;
};

// PACKAGER_RENAME( CKEDITOR.ui )

CKEDITOR.ui.prototype =
{
	/**
	 * Adds a UI item to the items collection. These items can be later used in
	 * the open.
	 * @param {String} name The UI item name.
	 * @param {Object} type The item type.
	 * @param {Object} definition The item definition. The properties of this
	 *		object depend on the item type.
	 * @example
	 * // Add a new button named "MyBold".
	 * editorInstance.ui.add( 'MyBold', CKEDITOR.UI_BUTTON,
	 *     {
	 *         label : 'My Bold',
	 *         command : 'bold'
	 *     });
	 */
	add : function( name, type, definition )
	{
		this._.items[ name ] =
		{
			type : type,
			// The name of {@link CKEDITOR.command} which associate with this UI.
			command : definition.command || null,
			args : Array.prototype.slice.call( arguments, 2 )
		};
	},

	/**
	 * Gets a UI object.
	 * @param {String} name The UI item hame.
	 * @example
	 */
	create : function( name )
	{
		var item	= this._.items[ name ],
			handler	= item && this._.handlers[ item.type ],
			command = item && item.command && this._.editor.getCommand( item.command );

		var result = handler && handler.create.apply( this, item.args );

		// Allow overrides from skin ui definitions..
		item && ( result = CKEDITOR.tools.extend( result, this._.editor.skin[ item.type ], true ) );

		// Add reference inside command object.
		if ( command )
			command.uiItems.push( result );

		return result;
	},

	/**
	 * Adds a handler for a UI item type. The handler is responsible for
	 * transforming UI item definitions in UI objects.
	 * @param {Object} type The item type.
	 * @param {Object} handler The handler definition.
	 * @example
	 */
	addHandler : function( type, handler )
	{
		this._.handlers[ type ] = handler;
	}
};

CKEDITOR.event.implementOn( CKEDITOR.ui );

/**
 * (Virtual Class) Do not call this constructor. This class is not really part
 *		of the API. It just illustrates the features of hanlder objects to be
 *		passed to the {@link CKEDITOR.ui.prototype.addHandler} function.
 * @name CKEDITOR.ui.handlerDefinition
 * @constructor
 * @example
 */

 /**
 * Transforms an item definition into an UI item object.
 * @name CKEDITOR.handlerDefinition.prototype.create
 * @function
 * @param {Object} definition The item definition.
 * @example
 * editorInstance.ui.addHandler( CKEDITOR.UI_BUTTON,
 *     {
 *         create : function( definition )
 *         {
 *             return new CKEDITOR.ui.button( definition );
 *         }
 *     });
 */

/**
 * Internal event fired when a new UI element is ready
 * @name CKEDITOR.ui#ready
 * @event
 * @param {Object} element The new element
 */
