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

CKEDITOR.dialog.add( 'cellProperties', function( editor ) {
	var langTable = editor.lang.table,
		langCell = langTable.cell,
		langCommon = editor.lang.common,
		validate = CKEDITOR.dialog.validate,
		widthPattern = /^(\d+(?:\.\d+)?)(px|%)$/,
		spacer = { type: 'html', html: '&nbsp;' },
		hiddenSpacer,
		rtl = editor.lang.dir == 'rtl',
		colorDialog = editor.plugins.colordialog;

	// Returns a function, which runs regular "setup" for all selected cells to find out
	// whether the initial value of the field would be the same for all cells. If so,
	// the value is displayed just as if a regular "setup" was executed. Otherwise,
	// i.e. when there are several cells of different value of the property, a field
	// gets empty value.
	//
	// * @param {Function} setup Setup function which returns a value instead of setting it.
	// * @returns {Function} A function to be used in dialog definition.
	function setupCells( setup ) {
		return function( cells ) {
			var fieldValue = setup( cells[ 0 ] );

			// If one of the cells would have a different value of the
			// property, set the empty value for a field.
			for ( var i = 1; i < cells.length; i++ ) {
				if ( setup( cells[ i ] ) !== fieldValue ) {
					fieldValue = null;
					break;
				}
			}

			// Setting meaningful or empty value only makes sense
			// when setup returns some value. Otherwise, a *default* value
			// is used for that field.
			if ( typeof fieldValue != 'undefined' ) {
				this.setValue( fieldValue );

				// The only way to have an empty select value in Firefox is
				// to set a negative selectedIndex.
				if ( CKEDITOR.env.gecko && this.type == 'select' && !fieldValue )
					this.getInputElement().$.selectedIndex = -1;
			}
		};
	}

	// Reads the unit of width property of the table cell.
	//
	// * @param {CKEDITOR.dom.element} cell An element representing table cell.
	// * @returns {String} A unit of width: 'px', '%' or undefined if none.
	function getCellWidthType( cell ) {
		var match = widthPattern.exec(
			cell.getStyle( 'width' ) || cell.getAttribute( 'width' ) );

		if ( match )
			return match[ 2 ];
	}

	return {
		title: langCell.title,
		minWidth: CKEDITOR.env.ie && CKEDITOR.env.quirks ? 450 : 410,
		minHeight: CKEDITOR.env.ie && ( CKEDITOR.env.ie7Compat || CKEDITOR.env.quirks ) ? 230 : 220,
		contents: [ {
			id: 'info',
			label: langCell.title,
			accessKey: 'I',
			elements: [ {
				type: 'hbox',
				widths: [ '40%', '5%', '40%' ],
				children: [ {
					type: 'vbox',
					padding: 0,
					children: [ 


					hiddenSpacer = {
						type: 'html',
						id: 'hiddenSpacer',
						html: '&nbsp;',
						style: 'display: none'
					},
					spacer,
					{
						type: 'select',
						id: 'hAlign',
						label: langCell.hAlign,
						'default': '',
						items: [
							[ langCommon.notSet, '' ],
							[ langCommon.left, 'left' ],
							[ langCommon.center, 'center' ],
							[ langCommon.right, 'right' ]						
						],
						setup: setupCells( function( element ) {
							var alignAttr = element.getAttribute( 'align' ),
							textAlignStyle = element.getStyle( 'text-align' );

							return textAlignStyle || alignAttr || '';
						} ),
						commit: function( selectedCell ) {
							var value = this.getValue();

							if ( value ) {
								selectedCell.setStyle( 'text-align', value );
                                selectedCell.setAttribute('class', value + 'align');                                
                            }
							else {
								selectedCell.removeStyle( 'text-align' );
								selectedCell.removeAttribute( 'align' );
							}	
						}
					},
 ]
				},
				spacer,
				{
					type: 'vbox',
					padding: 0,
					children: [ {
						type: 'select',
						id: 'cellType',
						label: langCell.cellType,
						'default': 'td',
						items: [
							[ langCell.data, 'td' ],
							[ langCell.header, 'th' ]
						],
						setup: setupCells( function( selectedCell ) {
							return selectedCell.getName();
						} ),
						commit: function( selectedCell ) {
							selectedCell.renameNode( this.getValue() );
						}
					},
					spacer,
					{
						type: 'text',
						id: 'rowSpan',
						label: langCell.rowSpan,
						'default': '',
						validate: validate.integer( langCell.invalidRowSpan ),
						setup: setupCells( function( selectedCell ) {
							var attrVal = parseInt( selectedCell.getAttribute( 'rowSpan' ), 10 );
							if ( attrVal && attrVal != 1 )
								return attrVal;
						} ),
						commit: function( selectedCell ) {
							var value = parseInt( this.getValue(), 10 );
							if ( value && value != 1 )
								selectedCell.setAttribute( 'rowSpan', this.getValue() );
							else
								selectedCell.removeAttribute( 'rowSpan' );
						}
					},
					{
						type: 'text',
						id: 'colSpan',
						label: langCell.colSpan,
						'default': '',
						validate: validate.integer( langCell.invalidColSpan ),
						setup: setupCells( function( element ) {
							var attrVal = parseInt( element.getAttribute( 'colSpan' ), 10 );
							if ( attrVal && attrVal != 1 )
								return attrVal;
						} ),
						commit: function( selectedCell ) {
							var value = parseInt( this.getValue(), 10 );
							if ( value && value != 1 )
								selectedCell.setAttribute( 'colSpan', this.getValue() );
							else
								selectedCell.removeAttribute( 'colSpan' );
						}
					},
           ]
				} ]
			} ]
		} ],
		onShow: function() {
			this.cells = CKEDITOR.plugins.tabletools.getSelectedCells( this._.editor.getSelection() );
			this.setupContent( this.cells );
		},
		onOk: function() {
			var selection = this._.editor.getSelection(),
				bookmarks = selection.createBookmarks();

			var cells = this.cells;
			for ( var i = 0; i < cells.length; i++ )
				this.commitContent( cells[ i ] );

			this._.editor.forceNextSelectionCheck();
			selection.selectBookmarks( bookmarks );
			this._.editor.selectionChange();
		},
		onLoad: function() {
			var saved = {};

			// Prevent from changing cell properties when the field's value
			// remains unaltered, i.e. when selected multiple cells and dialog loaded
			// only the properties of the first cell (https://dev.ckeditor.com/ticket/11439).
			this.foreach( function( field ) {
				if ( !field.setup || !field.commit )
					return;

				// Save field's value every time after "setup" is called.
				field.setup = CKEDITOR.tools.override( field.setup, function( orgSetup ) {
					return function() {
						orgSetup.apply( this, arguments );
						saved[ field.id ] = field.getValue();
					};
				} );

				// Compare saved value with actual value. Update cell only if value has changed.
				field.commit = CKEDITOR.tools.override( field.commit, function( orgCommit ) {
					return function() {
						if ( saved[ field.id ] !== field.getValue() )
							orgCommit.apply( this, arguments );
					};
				} );
			} );
		}
	};
} );
