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

CKEDITOR.plugins.add( 'panelbutton', {
	requires: 'button',
	onLoad: function() {
		function clickFn( editor ) {
			var _ = this._;

			if ( _.state == CKEDITOR.TRISTATE_DISABLED )
				return;

			this.createPanel( editor );

			if ( _.on ) {
				_.panel.hide();
				return;
			}

			_.panel.showBlock( this._.id, this.document.getById( this._.id ), 4 );
		}

		/**
		 * @class
		 * @extends CKEDITOR.ui.button
		 * @todo class and methods
		 */
		CKEDITOR.ui.panelButton = CKEDITOR.tools.createClass( {
			base: CKEDITOR.ui.button,

			/**
			 * Creates a panelButton class instance.
			 *
			 * @constructor
			 */
			$: function( definition ) {
				// We don't want the panel definition in this object.
				var panelDefinition = definition.panel || {};
				delete definition.panel;

				this.base( definition );

				this.document = ( panelDefinition.parent && panelDefinition.parent.getDocument() ) || CKEDITOR.document;

				panelDefinition.block = {
					attributes: panelDefinition.attributes
				};
				panelDefinition.toolbarRelated = true;

				this.hasArrow = true;

				this.click = clickFn;

				this._ = {
					panelDefinition: panelDefinition
				};
			},

			statics: {
				handler: {
					create: function( definition ) {
						return new CKEDITOR.ui.panelButton( definition );
					}
				}
			},

			proto: {
				createPanel: function( editor ) {
					var _ = this._;

					if ( _.panel )
						return;

					var panelDefinition = this._.panelDefinition,
						panelBlockDefinition = this._.panelDefinition.block,
						panelParentElement = panelDefinition.parent || CKEDITOR.document.getBody(),
						panel = this._.panel = new CKEDITOR.ui.floatPanel( editor, panelParentElement, panelDefinition ),
						block = panel.addBlock( _.id, panelBlockDefinition ),
						me = this;

					panel.onShow = function() {
						if ( me.className )
							this.element.addClass( me.className + '_panel' );

						me.setState( CKEDITOR.TRISTATE_ON );

						_.on = 1;

						me.editorFocus && editor.focus();

						if ( me.onOpen )
							me.onOpen();
					};

					panel.onHide = function( preventOnClose ) {
						if ( me.className )
							this.element.getFirst().removeClass( me.className + '_panel' );

						me.setState( me.modes && me.modes[ editor.mode ] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED );

						_.on = 0;

						if ( !preventOnClose && me.onClose )
							me.onClose();
					};

					panel.onEscape = function() {
						panel.hide( 1 );
						me.document.getById( _.id ).focus();
					};

					if ( this.onBlock )
						this.onBlock( panel, block );

					block.onHide = function() {
						_.on = 0;
						me.setState( CKEDITOR.TRISTATE_OFF );
					};
				}
			}
		} );

	},
	beforeInit: function( editor ) {
		editor.ui.addHandler( CKEDITOR.UI_PANELBUTTON, CKEDITOR.ui.panelButton.handler );
	}
} );

/**
 * Button UI element.
 *
 * @readonly
 * @property {String} [='panelbutton']
 * @member CKEDITOR
 */
CKEDITOR.UI_PANELBUTTON = 'panelbutton';
