/*!
 * VisualEditor ContentEditable TableRowNode class.
 *
 * @copyright See AUTHORS.txt
 */

/**
 * ContentEditable table row node.
 *
 * @class
 * @extends ve.ce.BranchNode
 * @constructor
 * @param {ve.dm.TableRowNode} model Model to observe
 * @param {Object} [config] Configuration options
 */
ve.ce.TableRowNode = function VeCeTableRowNode() {
	// Parent constructor
	ve.ce.TableRowNode.super.apply( this, arguments );

	this.$missingCell = null;
};

/* Inheritance */

OO.inheritClass( ve.ce.TableRowNode, ve.ce.BranchNode );

/* Static Properties */

ve.ce.TableRowNode.static.name = 'tableRow';

ve.ce.TableRowNode.static.tagName = 'tr';

/* Methods */

/**
 * @inheritdoc
 */
ve.ce.TableRowNode.prototype.initialize = function () {
	// Parent method
	ve.ce.TableRowNode.super.prototype.initialize.call( this );

	ve.ce.TableCellNode.static.updateStyles( this.$element, this.model );
};

/**
 * @inheritdoc
 */
ve.ce.TableRowNode.prototype.onSetup = function () {
	// Parent method
	ve.ce.TableRowNode.super.prototype.onSetup.apply( this, arguments );

	this.setupMissingCell();
};

/**
 * @inheritdoc
 */
ve.ce.TableRowNode.prototype.onSplice = function () {
	// Parent method
	ve.ce.TableRowNode.super.prototype.onSplice.apply( this, arguments );

	// Defer call until after other changes in this cycle have been made
	setTimeout( () => {
		if ( this.getRoot() ) {
			// It's possible for this to have been removed from the model in the last tick
			// This mostly seems to happen during cell merges
			this.setupMissingCell();
		}
	} );
};

/**
 * Setup a slug for a missing cell, if this row contains fewer cells than the table
 */
ve.ce.TableRowNode.prototype.setupMissingCell = function () {
	const matrix = this.findParent( ve.ce.TableNode ).getModel().getMatrix(),
		maxColCount = matrix.getMaxColCount();

	const row = matrix.getRowNodes().indexOf( this.model );
	if ( maxColCount > matrix.getColCount( row ) ) {
		if ( !this.$missingCell ) {
			this.$missingCell = $( '<td>' )
				.prop( 'contentEditable', 'false' )
				.addClass( 've-ce-branchNode-slug ve-ce-branchNode-blockSlug ve-ce-tableNode-missingCell ve-ce-surface-interface' );
			const slugButton = new ve.ui.NoFocusButtonWidget( {
				icon: 'add',
				framed: false
			} ).on( 'click', this.onMissingCellClick.bind( this ) );
			this.$missingCell.append( slugButton.$element );
		}
		this.$element.append( this.$missingCell );
	} else {
		this.removeSlugs();
	}
};

/**
 * @inheritdoc
 */
ve.ce.TableRowNode.prototype.removeSlugs = function () {
	if ( this.$missingCell ) {
		this.$missingCell.detach();
	}
};

/**
 * Handle click events on the missing cell slug
 *
 * @param {jQuery.Event} e Click event
 */
ve.ce.TableRowNode.prototype.onMissingCellClick = function () {
	const surfaceModel = this.getRoot().getSurface().getModel(),
		documentModel = surfaceModel.getDocument(),
		tableModel = this.findParent( ve.ce.TableNode ).getModel(),
		matrix = tableModel.getMatrix();

	// Add a cell onto the end of the row
	surfaceModel.change(
		ve.dm.TransactionBuilder.static.newFromInsertion(
			documentModel, this.getModel().getRange().end,
			ve.dm.TableCellNode.static.createData()
		)
	);

	// Select the newly-inserted cell
	const row = matrix.getRowNodes().indexOf( this.model );
	const col = matrix.getColCount( row ) - 1;
	surfaceModel.setSelection(
		new ve.dm.TableSelection( tableModel.getOuterRange(), col, row )
	);
};

/* Registration */

ve.ce.nodeFactory.register( ve.ce.TableRowNode );
