YUI.add('aui-layout-builder-remove-row', function (A, NAME) {

/**
 * The Layout Remove Row Component
 *
 * @module aui-layout-remove-row
 */

var CSS_REMOVE_ROW = A.getClassName('layout', 'builder', 'remove', 'row', 'button'),
    SELECTOR_ROW = '.layout-row',
    TPL_REMOVE_ROW_BUTTON = '<button class="btn btn-default btn-xs ' + CSS_REMOVE_ROW + '" type="button">' +
        '<span class="glyphicon glyphicon-trash"></span></button>';
/**
 * A base class for Layout Remove Row.
 *
 * @class A.LayoutBuilderRemoveRow
 * @param {Object} config Object literal specifying layout configuration
 *     properties.
 * @constructor
 */
function LayoutBuilderRemoveRow() {}

LayoutBuilderRemoveRow.prototype = {
    /**
     * Construction logic executed during instantiation.
     * Lifecycle.
     *
     * @method initializer
     * @protected
     */
    initializer: function() {
        this._eventHandles.push(
            this.after('enableRemoveRowsChange', A.bind(this._afterEnableRemoveRowsChange, this)),
            this.after('layout:rowsChange', A.bind(this._afterRemoveRowRowsChange, this)),
            this.after('layoutChange', A.bind(this._afterRemoveRowLayoutChange, this)),
            this.after('layout:isColumnModeChange', A.bind(this._afterRemoveRowIsColumnModeChange, this))
        );

        this._uiSetEnableRemoveRows(this.get('enableRemoveRows'));
    },

    /**
     * Destructor implementation for the `A.LayoutBuilderRemoveRow` class. Lifecycle.
     *
     * @method destructor
     * @protected
     */
    destructor: function() {
        this._unbindRemoveRowEvents();
    },

    /**
     * Fired after `isColumnMode` changes.
     *
     * @method _afterRemoveRowIsColumnModeChange
     * @protected
     */
    _afterRemoveRowIsColumnModeChange: function() {
        this._uiSetEnableRemoveRows(this.get('enableRemoveRows'));
    },

    /**
     * Fired after `layout` attribute changes.
     *
     * @method _afterRemoveRowLayoutChange
     * @protected
     */
    _afterRemoveRowLayoutChange: function() {
        this._uiSetEnableRemoveRows(this.get('enableRemoveRows'));
    },

    /**
     * Fired after the `removable` attribute changes.
     *
     * @method _afterRemoveRowRemovableChange
     * @params {EventFacade} event
     * @protected
     */
    _afterRemoveRowRemovableChange: function(event) {
        var containerRow = event.target.get('node'),
            layoutRow = event.target,
            removeRowButton;

        removeRowButton = containerRow.one('.' + CSS_REMOVE_ROW);

        if (!event.newVal) {
            if (removeRowButton) {
                removeRowButton.remove();
            }
        }
        else {
            this._insertRemoveButtonBeforeRow(layoutRow, containerRow.one(SELECTOR_ROW));
        }
    },

    /**
     * Fired after `rows` attribute changes.
     *
     * @method _afterRemoveRowRowsChange
     * @protected
     */
    _afterRemoveRowRowsChange: function() {
        this._uiSetEnableRemoveRows(this.get('enableRemoveRows'));
    },

    /**
     * Fired after the `enableRemoveRows` attribute changes.
     *
     * @method _afterEnableRemoveRowsChange
     * @protected
     */
    _afterEnableRemoveRowsChange: function() {
        this._uiSetEnableRemoveRows(this.get('enableRemoveRows'));
    },

    /**
     * Appends one remove row button before each row.
     *
     * @method _appendButtonToRows
     * @protected
     */
    _appendButtonToRows: function() {
        var instance = this,
            layoutRow,
            rows = this._layoutContainer.all(SELECTOR_ROW);

        rows.each(function(row) {
            layoutRow = row.getData('layout-row');

            if (layoutRow.get('removable')) {
                instance._insertRemoveButtonBeforeRow(layoutRow, row);
            }
        });
    },

    /**
     * Binds the necessary events for the functionality of removing rows from layout.
     *
     * @method _bindRemoveRowEvents
     * @protected
     */
    _bindRemoveRowEvents: function() {
        var container = this.get('container');

        this._removeRowsEventHandles = [
            container.delegate('click', A.bind(this._onMouseClickRemoveRowEvent, this), '.' + CSS_REMOVE_ROW),
            this.after('layout-row:removableChange', this._afterRemoveRowRemovableChange)
        ];
    },

    /**
     * Inserts remove button before a specified row.
     *
     * @method _insertRemoveButtonBeforeRow
     * @param {A.LayoutRow} layoutRow
     * @param {Node} row
     * @protected
     */
    _insertRemoveButtonBeforeRow: function(layoutRow, row) {
        var removeRowButton;

        removeRowButton = A.Node.create(TPL_REMOVE_ROW_BUTTON);

        removeRowButton.setData('layout-row', layoutRow);
        this._layoutContainer.insertBefore(removeRowButton, row);
    },

    /**
     * Fires after click on remove row button.
     *
     * @method _onMouseClickEvent
     * @param {EventFacade} event
     * @protected
     */
    _onMouseClickRemoveRowEvent: function(event) {
        var removeRowButton = event.currentTarget,
            row = removeRowButton.getData('layout-row');

        if (this.get('clickRemoveRow')(row)){
            this.get('layout').removeRow(row);
        }
    },

    /**
     * Removes all remove row buttons.
     *
     * @method _removeRemoveButtonFromRows
     * @protected
     */
    _removeRemoveButtonFromRows: function() {
        this.get('container').all('.' + CSS_REMOVE_ROW).remove();
    },

    /**
     * Updates the UI according to the value of the `enableRemoveRows` attribute.
     *
     * @method _uiSetEnableRemoveRows
     * @param {Boolean} enableRemoveRows
     * @protected
     */
    _uiSetEnableRemoveRows: function(enableRemoveRows) {
        this._removeRemoveButtonFromRows();

        if (enableRemoveRows && this.get('layout').get('isColumnMode')) {
            this._appendButtonToRows();
            this._bindRemoveRowEvents();
        }
        else {
            this._unbindRemoveRowEvents();
        }
    },

    /**
     * Unbinds the events related to the functionality of removing rows from layout.
     *
     * @method _unbindRemoveRowEvents
     * @protected
     */
    _unbindRemoveRowEvents: function() {
        if (this._removeRowsEventHandles) {
            (new A.EventHandle(this._removeRowsEventHandles)).detach();
        }
    }
};

/**
 * Static property used to define the default attribute configuration for the
 * `A.LayoutBuilderRemoveRow`.
 *
 * @property ATTRS
 * @type {Object}
 * @static
 */
LayoutBuilderRemoveRow.ATTRS = {
    /**
     * Check if the row can be remove when remove button is clicked.  
     *
     * @attribute clickRemoveRow
     * @type {Function}
     */
    clickRemoveRow: {
        validator: A.Lang.isFunction,
        value: function() {
            return true;
        }
    },

    /**
     * Flag indicating if the feature of removing rows from layout is
     * enabled or not.
     *
     * @attribute enableRemoveRows
     * @default true
     * @type {Boolean}
     */
    enableRemoveRows: {
        validator: A.Lang.isBoolean,
        value: true
    }
};

A.LayoutBuilderRemoveRow = LayoutBuilderRemoveRow;


}, '3.1.0-deprecated.112', {"requires": ["aui-node-base", "base-build"], "skinnable": true});
