/*******************************************************************************
 * Copyright (c) 2012, 2020 Original authors and others.
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Original authors and others - initial API and implementation
 *     Jonas Hugo <Jonas.Hugo@jeppesen.com>,
 *       Markus Wahl <Markus.Wahl@jeppesen.com> - Delegate markers to model if
 *         model is an IMarkerSelectionModel. Add getters and setters for marker fields
 *     neal zhang <nujiah001@126.com> - change some methods and fields visibility
 *     Dirk Fauth <dirk.fauth@googlemail.com> - Bug 446275, 453851
 ******************************************************************************/
package org.eclipse.nebula.widgets.nattable.selection;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.stream.IntStream;

import org.eclipse.collections.api.list.primitive.MutableIntList;
import org.eclipse.collections.impl.factory.primitive.IntLists;
import org.eclipse.nebula.widgets.nattable.command.ILayerCommand;
import org.eclipse.nebula.widgets.nattable.coordinate.PositionCoordinate;
import org.eclipse.nebula.widgets.nattable.coordinate.PositionCoordinateComparator;
import org.eclipse.nebula.widgets.nattable.coordinate.Range;
import org.eclipse.nebula.widgets.nattable.copy.command.CopyDataCommandHandler;
import org.eclipse.nebula.widgets.nattable.edit.command.EditSelectionCommandHandler;
import org.eclipse.nebula.widgets.nattable.fillhandle.FillHandleLayerPainter;
import org.eclipse.nebula.widgets.nattable.fillhandle.action.FillHandleDragMode;
import org.eclipse.nebula.widgets.nattable.grid.command.InitializeAutoResizeColumnsCommandHandler;
import org.eclipse.nebula.widgets.nattable.grid.command.InitializeAutoResizeRowsCommandHandler;
import org.eclipse.nebula.widgets.nattable.hideshow.command.ColumnHideCommand;
import org.eclipse.nebula.widgets.nattable.hideshow.command.MultiColumnHideCommand;
import org.eclipse.nebula.widgets.nattable.hideshow.command.MultiRowHideCommand;
import org.eclipse.nebula.widgets.nattable.hideshow.command.RowHideCommand;
import org.eclipse.nebula.widgets.nattable.hideshow.command.RowPositionHideCommand;
import org.eclipse.nebula.widgets.nattable.layer.AbstractIndexLayerTransform;
import org.eclipse.nebula.widgets.nattable.layer.IUniqueIndexLayer;
import org.eclipse.nebula.widgets.nattable.layer.LabelStack;
import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;
import org.eclipse.nebula.widgets.nattable.resize.command.ColumnResizeCommand;
import org.eclipse.nebula.widgets.nattable.resize.command.MultiColumnResizeCommand;
import org.eclipse.nebula.widgets.nattable.resize.command.MultiRowResizeCommand;
import org.eclipse.nebula.widgets.nattable.resize.command.RowResizeCommand;
import org.eclipse.nebula.widgets.nattable.search.command.SearchGridCellsCommandHandler;
import org.eclipse.nebula.widgets.nattable.selection.command.ClearAllSelectionsCommand;
import org.eclipse.nebula.widgets.nattable.selection.command.SelectAllCommand;
import org.eclipse.nebula.widgets.nattable.selection.config.DefaultSelectionLayerConfiguration;
import org.eclipse.nebula.widgets.nattable.selection.event.CellSelectionEvent;
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
import org.eclipse.nebula.widgets.nattable.style.SelectionStyleLabels;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;

/**
 * Enables selection of column, rows, cells etc. on the table. Also responds to
 * UI bindings by changing the current selection. Internally it uses the
 * {@link ISelectionModel} to track the selection state.
 *
 * @see DefaultSelectionLayerConfiguration
 * @see MoveDirectionEnum
 */
public class SelectionLayer extends AbstractIndexLayerTransform {

    public static final int MOVE_ALL = -1;
    public static final int NO_SELECTION = -1;

    public enum MoveDirectionEnum {
        UP, DOWN, LEFT, RIGHT, NONE;
    }

    protected ISelectionModel selectionModel;
    protected IUniqueIndexLayer underlyingLayer;
    protected final PositionCoordinate lastSelectedCell;
    protected final PositionCoordinate selectionAnchor;
    protected Rectangle lastSelectedRegion;

    /**
     * The region <i>selected</i> via fill handle to extend the current
     * selection for triggering a fill action. Can be <code>null</code>.
     *
     * @since 1.4
     */
    protected Rectangle fillHandleRegion;

    /**
     * The bottom right cell in a contiguous selection or <code>null</code> if
     * there is no selection or the selection is not contiguous. Needed to
     * identify the cell on which the fill handle should be rendered.
     *
     * @since 1.4
     */
    protected PositionCoordinate bottomRightInSelection;

    protected SelectRowCommandHandler selectRowCommandHandler;
    protected SelectCellCommandHandler selectCellCommandHandler;
    protected SelectColumnCommandHandler selectColumnCommandHandler;

    public SelectionLayer(IUniqueIndexLayer underlyingLayer) {
        this(underlyingLayer, null, true);
    }

    public SelectionLayer(IUniqueIndexLayer underlyingLayer, boolean useDefaultConfiguration) {
        this(underlyingLayer, null, useDefaultConfiguration);
    }

    public SelectionLayer(IUniqueIndexLayer underlyingLayer, ISelectionModel selectionModel, boolean useDefaultConfiguration) {
        super(underlyingLayer);
        this.underlyingLayer = underlyingLayer;

        setLayerPainter(new SelectionLayerPainter());

        setSelectionModel(selectionModel);

        this.lastSelectedCell = new PositionCoordinate(this, NO_SELECTION, NO_SELECTION);
        this.selectionAnchor = new PositionCoordinate(this, NO_SELECTION, NO_SELECTION);

        this.selectRowCommandHandler = new SelectRowCommandHandler(this);
        this.selectCellCommandHandler = new SelectCellCommandHandler(this);
        this.selectColumnCommandHandler = new SelectColumnCommandHandler(this);

        registerCommandHandlers();

        if (useDefaultConfiguration) {
            addConfiguration(new DefaultSelectionLayerConfiguration());
        }
    }

    public ISelectionModel getSelectionModel() {
        return this.selectionModel;
    }

    public void setSelectionModel(ISelectionModel selectionModel) {
        if (this.selectionModel != null) {
            unregisterEventHandler(this.selectionModel);
        }
        this.selectionModel = selectionModel != null ? selectionModel : new SelectionModel(this);
        registerEventHandler(this.selectionModel);
    }

    public void addSelection(Rectangle selection) {
        if (!selection.equals(getLastSelectedRegion())) {
            setSelectionAnchor(getLastSelectedCell().columnPosition, getLastSelectedCell().rowPosition);
            setLastSelectedRegion(selection);
        }

        this.selectionModel.addSelection(selection);
    }

    public void clear() {
        clear(true);
    }

    public void clear(boolean fireSelectionEvent) {
        this.selectionModel.clearSelection();

        boolean validLastSelectedCell = hasSelection(getLastSelectedCell());
        setLastSelectedCell(NO_SELECTION, NO_SELECTION);
        setLastSelectedRegion(new Rectangle(0, 0, 0, 0));

        setSelectionAnchor(NO_SELECTION, NO_SELECTION);

        if (validLastSelectedCell && fireSelectionEvent) {
            fireCellSelectionEvent(
                    getLastSelectedCell().columnPosition,
                    getLastSelectedCell().rowPosition,
                    false, false, false);
        }
    }

    public void clearSelection(int columnPosition, int rowPosition) {
        this.selectionModel.clearSelection(columnPosition, rowPosition);

        if (getSelectionAnchor().columnPosition == columnPosition
                && getSelectionAnchor().rowPosition == rowPosition) {
            setSelectionAnchor(NO_SELECTION, NO_SELECTION);
        }

        if (this.selectionModel.isEmpty()) {
            setLastSelectedCell(NO_SELECTION, NO_SELECTION);
            setLastSelectedRegion(new Rectangle(0, 0, 0, 0));
        }

        if (getLastSelectedCell().columnPosition == columnPosition
                && getLastSelectedCell().rowPosition == rowPosition) {
            setLastSelectedCell(NO_SELECTION, NO_SELECTION);
        }
    }

    public void clearSelection(Rectangle selection) {
        this.selectionModel.clearSelection(selection);

        // if the selection anchor is within the selection that is removed
        // it needs to be cleared also
        Point anchorPoint = new Point(
                getSelectionAnchor().columnPosition,
                getSelectionAnchor().rowPosition);
        if (selection.contains(anchorPoint)) {
            setSelectionAnchor(NO_SELECTION, NO_SELECTION);
        }

        if (this.selectionModel.isEmpty()) {
            setLastSelectedCell(NO_SELECTION, NO_SELECTION);
            setLastSelectedRegion(new Rectangle(0, 0, 0, 0));
        }

        // we need to clear the last selected cell in case the selection in that
        // rectangle is cleared
        Point lastSelectedPoint = new Point(
                getLastSelectedCell().columnPosition,
                getLastSelectedCell().rowPosition);
        if (selection.contains(lastSelectedPoint)) {
            setLastSelectedCell(NO_SELECTION, NO_SELECTION);
        }
    }

    public void selectAll() {
        Rectangle selection = new Rectangle(0, 0, getColumnCount(), getRowCount());
        PositionCoordinate lastSelected = getLastSelectedCell();
        if (lastSelected.columnPosition == SelectionLayer.NO_SELECTION
                || lastSelected.columnPosition >= getColumnCount()
                || lastSelected.rowPosition == SelectionLayer.NO_SELECTION
                || lastSelected.rowPosition >= getRowCount()) {
            // search for the first visible column
            // typically this is 0/0 but when using 0 sized columns for hiding
            // columns, this leads to missing repainting
            int column = 0;
            for (; column < getColumnCount(); column++) {
                if (getColumnWidthByPosition(column) > 0) {
                    break;
                }
            }
            int row = 0;
            for (; row < getRowCount(); row++) {
                if (getRowHeightByPosition(row) > 0) {
                    break;
                }
            }
            setLastSelectedCell(column, row);
        }
        addSelection(selection);
        fireCellSelectionEvent(
                getLastSelectedCell().columnPosition,
                getLastSelectedCell().rowPosition,
                false,
                false,
                false);
    }

    // Cell features

    public boolean isCellPositionSelected(int columnPosition, int rowPosition) {
        return this.selectionModel.isCellPositionSelected(columnPosition, rowPosition);
    }

    public void setSelectedCell(int columnPosition, int rowPosition) {
        selectCell(columnPosition, rowPosition, false, false);
    }

    /**
     * When extending a selected area via modifier keys, we need to move from
     * the last selected cell. If we are not extending a selection we need to
     * move from the <i>selection anchor</i>.
     *
     * @param withShiftMask
     *            <code>true</code> if the shift mask is active,
     *            <code>false</code> if not.
     * @param withControlMask
     *            <code>true</code> if the shift mask is active,
     *            <code>false</code> if not.
     * @return The cell position coordinate related to this SelectionLayer, from
     *         where to move from.
     */
    protected PositionCoordinate getCellPositionToMoveFrom(boolean withShiftMask, boolean withControlMask) {
        return (!withShiftMask && !withControlMask) ? getSelectionAnchor() : getLastSelectedCellPosition();
    }

    public PositionCoordinate[] getSelectedCellPositions() {
        int[] selectedColumnPositions = getSelectedColumnPositions();
        Set<Range> selectedRowPositions = getSelectedRowPositions();

        List<PositionCoordinate> selectedCells = new LinkedList<>();

        for (int columnPositionIndex = 0; columnPositionIndex < selectedColumnPositions.length; columnPositionIndex++) {
            final int columnPosition = selectedColumnPositions[columnPositionIndex];

            for (Range rowIndexRange : selectedRowPositions) {
                for (int rowPositionIndex = rowIndexRange.start; rowPositionIndex < rowIndexRange.end; rowPositionIndex++) {
                    if (this.selectionModel.isCellPositionSelected(columnPosition, rowPositionIndex)) {
                        selectedCells.add(new PositionCoordinate(this, columnPosition, rowPositionIndex));
                    }
                }
            }
        }
        Collections.sort(selectedCells, new PositionCoordinateComparator());
        return selectedCells.toArray(new PositionCoordinate[0]);
    }

    /**
     * Retrieves the ILayerCells out of the SelectionLayer that are currently
     * marked as selected in the SelectionModel. Takes spanning into account.
     *
     * @return The selected ILayerCells
     */
    public Collection<ILayerCell> getSelectedCells() {
        Set<ILayerCell> selectedCells = new LinkedHashSet<>();

        PositionCoordinate[] selectedCoords = getSelectedCellPositions();
        for (PositionCoordinate coord : selectedCoords) {
            selectedCells.add(getCellByPosition(coord.columnPosition, coord.rowPosition));
        }

        return selectedCells;
    }

    /**
     * Calculates the selected cells - taking into account Shift and Ctrl key
     * presses.
     */
    public void selectCell(int columnPosition, int rowPosition, boolean withShiftMask, boolean withControlMask) {
        this.selectCellCommandHandler.selectCell(columnPosition, rowPosition, withShiftMask, withControlMask);
    }

    public void selectRegion(int startColumnPosition, int startRowPosition, int regionWidth, int regionHeight) {
        if (getLastSelectedRegion() == null) {
            setLastSelectedRegion(new Rectangle(
                    startColumnPosition,
                    startRowPosition,
                    regionWidth,
                    regionHeight));
        } else {
            setLastSelectedRegion(
                    startColumnPosition,
                    startRowPosition,
                    regionWidth,
                    regionHeight);
        }
        this.selectionModel.addSelection(new Rectangle(
                getLastSelectedRegion().x,
                getLastSelectedRegion().y,
                getLastSelectedRegion().width,
                getLastSelectedRegion().height));
    }

    protected void setLastSelectedRegion(Rectangle region) {
        if (this.selectionModel instanceof IMarkerSelectionModel) {
            ((IMarkerSelectionModel) this.selectionModel).setLastSelectedRegion(region);
        } else {
            // if the given region is null or the current lastSelectedRegion is
            // null, simply set the reference
            if (region == null || this.lastSelectedRegion == null) {
                this.lastSelectedRegion = region;
            } else {
                // we are modifying the values of the current lastSelectedRegion
                // instead of setting a new reference because of reference
                // issues in other places
                this.lastSelectedRegion.x = region.x;
                this.lastSelectedRegion.y = region.y;
                this.lastSelectedRegion.width = region.width;
                this.lastSelectedRegion.height = region.height;
            }
        }
    }

    protected void setLastSelectedRegion(
            int startColumnPosition, int startRowPosition,
            int regionWidth, int regionHeight) {
        if (this.selectionModel instanceof IMarkerSelectionModel) {
            ((IMarkerSelectionModel) this.selectionModel).setLastSelectedRegion(
                    startColumnPosition,
                    startRowPosition,
                    regionWidth,
                    regionHeight);
        } else {
            this.lastSelectedRegion.x = startColumnPosition;
            this.lastSelectedRegion.y = startRowPosition;
            this.lastSelectedRegion.width = regionWidth;
            this.lastSelectedRegion.height = regionHeight;
        }
    }

    // Selection anchor

    public PositionCoordinate getSelectionAnchor() {
        if (this.selectionModel instanceof IMarkerSelectionModel) {
            Point coordinate = ((IMarkerSelectionModel) this.selectionModel).getSelectionAnchor();
            return new PositionCoordinate(this, coordinate.x, coordinate.y);
        } else {
            return this.selectionAnchor;
        }
    }

    public void moveSelectionAnchor(int startColumnPositionInRegion, int startRowPosition) {
        setSelectionAnchor(startColumnPositionInRegion, startRowPosition);
    }

    void setSelectionAnchor(int columnPosition, int rowPosition) {
        if (this.selectionModel instanceof IMarkerSelectionModel) {
            ((IMarkerSelectionModel) this.selectionModel).setSelectionAnchor(
                    new Point(columnPosition, rowPosition));
        } else {
            this.selectionAnchor.columnPosition = columnPosition;
            this.selectionAnchor.rowPosition = rowPosition;
        }
    }

    // Last selected

    public PositionCoordinate getLastSelectedCellPosition() {
        PositionCoordinate coordinate = getLastSelectedCell();
        if (hasSelection(coordinate)) {
            return coordinate;
        } else {
            return null;
        }
    }

    PositionCoordinate getLastSelectedCell() {
        if (this.selectionModel instanceof IMarkerSelectionModel) {
            Point coordinate = ((IMarkerSelectionModel) this.selectionModel).getLastSelectedCell();
            return new PositionCoordinate(this, coordinate.x, coordinate.y);
        } else {
            return this.lastSelectedCell;
        }
    }

    static boolean hasSelection(PositionCoordinate coordinate) {
        return coordinate.columnPosition != NO_SELECTION
                && coordinate.rowPosition != NO_SELECTION;
    }

    /**
     * Test if all cells in a given region are selected.
     *
     * @param region
     *            The region that should be checked.
     * @return <code>true</code> if all cells in a region are selected,
     *         <code>false</code> if at least one cell in the region is not
     *         selected.
     *
     * @since 1.6
     */
    public boolean allCellsSelectedInRegion(Rectangle region) {
        if (region.height == Integer.MAX_VALUE) {
            // if the region is for a full column selection, simplify the check
            // for better performance and correctness
            for (int col = region.x; col < (region.x + region.width); col++) {
                if (!isColumnPositionFullySelected(col)) {
                    return false;
                }
            }
        } else if (region.width == Integer.MAX_VALUE) {
            // if the region is for a full row selection, simplify the check
            // for better performance and correctness
            for (int row = region.y; row < (region.y + region.height); row++) {
                if (!isRowPositionFullySelected(row)) {
                    return false;
                }
            }
        } else {
            for (int col = region.x; col < (region.x + region.width); col++) {
                for (int row = region.y; row < (region.y + region.height); row++) {
                    if (!isCellPositionSelected(col, row)) {
                        return false;
                    }
                }
            }
        }
        return true;
    }

    public void setLastSelectedCell(int columnPosition, int rowPosition) {
        if (this.selectionModel instanceof IMarkerSelectionModel) {
            ((IMarkerSelectionModel) this.selectionModel).setLastSelectedCell(
                    new Point(columnPosition, rowPosition));
        } else {
            this.lastSelectedCell.columnPosition = columnPosition;
            this.lastSelectedCell.rowPosition = rowPosition;
        }
    }

    public Rectangle getLastSelectedRegion() {
        if (this.selectionModel instanceof IMarkerSelectionModel) {
            return ((IMarkerSelectionModel) this.selectionModel).getLastSelectedRegion();
        } else {
            return this.lastSelectedRegion;
        }
    }

    // Column features

    public boolean hasColumnSelection() {
        return getLastSelectedCell().columnPosition != NO_SELECTION;
    }

    public int[] getSelectedColumnPositions() {
        return this.selectionModel.getSelectedColumnPositions();
    }

    public boolean isColumnPositionSelected(int columnPosition) {
        return this.selectionModel.isColumnPositionSelected(columnPosition);
    }

    public int[] getFullySelectedColumnPositions() {
        return this.selectionModel.getFullySelectedColumnPositions(getRowCount());
    }

    public boolean isColumnPositionFullySelected(int columnPosition) {
        return this.selectionModel.isColumnPositionFullySelected(columnPosition, getRowCount());
    }

    public void selectColumn(
            int columnPosition, int rowPosition,
            boolean withShiftMask, boolean withControlMask) {
        this.selectColumnCommandHandler.selectColumn(
                columnPosition, rowPosition,
                withShiftMask, withControlMask);
    }

    // Row features

    public boolean hasRowSelection() {
        return getLastSelectedCell().rowPosition != NO_SELECTION;
    }

    public int getSelectedRowCount() {
        return this.selectionModel.getSelectedRowCount();
    }

    public Set<Range> getSelectedRowPositions() {
        return this.selectionModel.getSelectedRowPositions();
    }

    public boolean isRowPositionSelected(int rowPosition) {
        return this.selectionModel.isRowPositionSelected(rowPosition);
    }

    public int[] getFullySelectedRowPositions() {
        return this.selectionModel.getFullySelectedRowPositions(getColumnCount());
    }

    public boolean isRowPositionFullySelected(int rowPosition) {
        return this.selectionModel.isRowPositionFullySelected(rowPosition, getColumnCount());
    }

    public void selectRow(
            int columnPosition, int rowPosition,
            boolean withShiftMask, boolean withControlMask) {
        this.selectRowCommandHandler.selectRows(
                columnPosition,
                new int[] { rowPosition },
                withShiftMask,
                withControlMask,
                rowPosition);
    }

    // ILayer methods

    @Override
    public String getDisplayModeByPosition(int columnPosition, int rowPosition) {
        String displayMode = super.getDisplayModeByPosition(columnPosition, rowPosition);
        if (isCellPositionSelected(columnPosition, rowPosition)) {
            if (DisplayMode.HOVER.equals(displayMode)) {
                return DisplayMode.SELECT_HOVER;
            }
            return DisplayMode.SELECT;
        }
        return displayMode;
    }

    @Override
    public LabelStack getConfigLabelsByPosition(int columnPosition, int rowPosition) {
        LabelStack labelStack = super.getConfigLabelsByPosition(columnPosition, rowPosition);

        ILayerCell cell = getCellByPosition(columnPosition, rowPosition);
        if (cell != null) {
            Rectangle cellRectangle = new Rectangle(
                    cell.getOriginColumnPosition(),
                    cell.getOriginRowPosition(),
                    cell.getColumnSpan(),
                    cell.getRowSpan());

            PositionCoordinate anchor = getSelectionAnchor();
            if (cellRectangle.contains(anchor.columnPosition, anchor.rowPosition)) {
                labelStack.addLabelOnTop(SelectionStyleLabels.SELECTION_ANCHOR_STYLE);
            }

            if (this.bottomRightInSelection != null
                    && cellRectangle.contains(
                            this.bottomRightInSelection.columnPosition,
                            this.bottomRightInSelection.rowPosition)) {
                labelStack.addLabel(SelectionStyleLabels.FILL_HANDLE_CELL);
            }

            if (this.fillHandleRegion != null
                    && this.fillHandleRegion.contains(cell.getColumnPosition(), cell.getRowPosition())) {
                labelStack.addLabel(SelectionStyleLabels.FILL_HANDLE_REGION);
            }
        }
        return labelStack;
    }

    // Command handling

    @Override
    protected void registerCommandHandlers() {
        registerCommandHandler(this.selectCellCommandHandler);
        registerCommandHandler(this.selectRowCommandHandler);
        registerCommandHandler(this.selectColumnCommandHandler);
        registerCommandHandler(new SelectRegionCommandHandler(this));

        registerCommandHandler(new EditSelectionCommandHandler(this));
        registerCommandHandler(new InitializeAutoResizeColumnsCommandHandler(this));
        registerCommandHandler(new InitializeAutoResizeRowsCommandHandler(this));
        registerCommandHandler(new CopyDataCommandHandler(this));
        registerCommandHandler(new SearchGridCellsCommandHandler(this));
    }

    @Override
    public boolean doCommand(ILayerCommand command) {
        if (command instanceof SelectAllCommand
                && command.convertToTargetLayer(this)) {
            selectAll();
            return true;
        } else if (command instanceof ClearAllSelectionsCommand
                && command.convertToTargetLayer(this)) {
            clear();
            return true;
        } else if (command instanceof ColumnHideCommand
                && command.convertToTargetLayer(this)) {
            return handleColumnHideCommand((ColumnHideCommand) command);
        } else if (command instanceof MultiColumnHideCommand
                && command.convertToTargetLayer(this)) {
            return handleMultiColumnHideCommand((MultiColumnHideCommand) command);
        } else if (command instanceof RowHideCommand
                && command.convertToTargetLayer(this)) {
            return handleRowHideCommand((RowHideCommand) command);
        } else if (command instanceof MultiRowHideCommand
                && command.convertToTargetLayer(this)) {
            return handleMultiRowHideCommand((MultiRowHideCommand) command);
        } else if (command instanceof RowPositionHideCommand
                && command.convertToTargetLayer(this)) {
            return handleRowPositionHideCommand((RowPositionHideCommand) command);
        } else if (command instanceof ColumnResizeCommand
                && command.convertToTargetLayer(this)) {
            return handleColumnResizeCommand((ColumnResizeCommand) command);
        } else if (command instanceof RowResizeCommand
                && command.convertToTargetLayer(this)) {
            return handleRowResizeCommand((RowResizeCommand) command);
        }
        return super.doCommand(command);
    }

    public void fireCellSelectionEvent(int columnPosition, int rowPosition,
            boolean forcingEntireCellIntoViewport, boolean withShiftMask,
            boolean withControlMask) {

        int column = columnPosition;
        int row = rowPosition;
        if (columnPosition >= 0 && rowPosition >= 0) {
            ILayerCell cell = getCellByPosition(columnPosition, rowPosition);
            if (cell != null) {
                column = cell.getOriginColumnPosition();
                row = cell.getOriginRowPosition();
            }
        }
        final CellSelectionEvent selectionEvent =
                new CellSelectionEvent(this,
                        column,
                        row,
                        withShiftMask,
                        withControlMask);
        fireLayerEvent(selectionEvent);
    }

    // command transformations

    /**
     * Will check if there are fully selected column positions. If there is at
     * least one fully selected column position, the {@link ColumnHideCommand}
     * will be consumed and a {@link MultiColumnHideCommand} will be created and
     * executed further down the layer stack, that contains all fully selected
     * column positions. Otherwise the given command will be executed further.
     * <br>
     *
     * This is necessary because neither the ColumnHideShowLayer nor the action
     * that caused the execution of the {@link ColumnHideCommand} is aware of
     * the presence of the {@link SelectionLayer}. Without this transformation,
     * only the column on which the action was called will be hidden instead of
     * all selected ones.
     *
     * @param command
     *            The {@link ColumnHideCommand} to process
     * @return <code>true</code> if the command has been handled,
     *         <code>false</code> otherwise
     */
    protected boolean handleColumnHideCommand(ColumnHideCommand command) {
        if (isColumnPositionFullySelected(command.getColumnPosition())) {
            return handleMultiColumnHideCommand(new MultiColumnHideCommand(this, getFullySelectedColumnPositions()));
        } else {
            return super.doCommand(command);
        }
    }

    /**
     * Previous to processing the given {@link MultiColumnHideCommand} down the
     * layer stack, the fully selected column positions selection state will be
     * cleared. This is necessary so the selection also disappears for the
     * selected columns. Otherwise after hiding the selection will be showed for
     * different columns.
     *
     * @param command
     *            The {@link MultiColumnHideCommand} to process
     * @return <code>true</code> if the command has been handled,
     *         <code>false</code> otherwise
     */
    protected boolean handleMultiColumnHideCommand(MultiColumnHideCommand command) {
        for (int columnPosition : command.getColumnPositionsArray()) {
            if (isColumnPositionFullySelected(columnPosition)) {
                Rectangle selection = new Rectangle(
                        columnPosition,
                        0,
                        1,
                        Integer.MAX_VALUE);
                clearSelection(selection);
            }
        }
        return super.doCommand(command);
    }

    /**
     * Will check if there are fully selected row positions. If there is at
     * least one fully selected row position, the {@link RowHideCommand} will be
     * consumed and a {@link MultiRowHideCommand} will be created and executed
     * further down the layer stack, that contains all fully selected row
     * positions. Otherwise the given command will be executed further.<br>
     *
     * This is necessary because neither the RowHideShowLayer nor the action
     * that caused the execution of the {@link RowHideCommand} is aware of the
     * presence of the {@link SelectionLayer}. Without this transformation, only
     * the row on which the action was called will be hidden instead of all
     * selected ones.
     *
     * @param command
     *            The {@link RowHideCommand} to process
     * @return <code>true</code> if the command has been handled,
     *         <code>false</code> otherwise
     */
    protected boolean handleRowHideCommand(RowHideCommand command) {
        if (isRowPositionFullySelected(command.getRowPosition())) {
            return handleMultiRowHideCommand(new MultiRowHideCommand(this, getFullySelectedRowPositions()));
        } else {
            return super.doCommand(command);
        }
    }

    /**
     * Previous to processing the given {@link MultiRowHideCommand} down the
     * layer stack, the fully selected row positions selection state will be
     * cleared. This is necessary so the selection also disappears for the
     * selected rows. Otherwise after hiding the selection will be showed for
     * different rows.
     *
     * @param command
     *            The {@link MultiRowHideCommand} to process
     * @return <code>true</code> if the command has been handled,
     *         <code>false</code> otherwise
     */
    protected boolean handleMultiRowHideCommand(MultiRowHideCommand command) {
        for (int rowPosition : command.getRowPositionsArray()) {
            if (isRowPositionFullySelected(rowPosition)) {
                Rectangle selection = new Rectangle(
                        0,
                        rowPosition,
                        Integer.MAX_VALUE,
                        1);
                clearSelection(selection);
            }
        }
        return super.doCommand(command);
    }

    /**
     * First inspects the cell at the position contained in the
     * {@link RowPositionHideCommand} and calculates all rows for that cell,
     * taking the spanning into account. If the cell itself is selected, than
     * also all other selected cells in the column position will be handled for
     * hiding.
     *
     * @param command
     *            The {@link RowPositionHideCommand} to process.
     * @return <code>true</code> if the command has been handled,
     *         <code>false</code> otherwise
     *
     * @since 1.6
     */
    protected boolean handleRowPositionHideCommand(RowPositionHideCommand command) {
        ILayerCell cell = getCellByPosition(command.getColumnPosition(), command.getRowPosition());
        // first consider spanning
        MutableIntList positions = IntLists.mutable.ofAll(
                IntStream.range(cell.getOriginRowPosition(), (cell.getOriginRowPosition() + cell.getRowSpan())));

        // then consider selection
        if (isCellPositionSelected(cell.getColumnPosition(), cell.getOriginRowPosition())) {
            // if the cell for which the command was triggered is selected, then
            // also take other selected cells into account
            PositionCoordinate[] selectedCellPositions = getSelectedCellPositions();
            for (PositionCoordinate coord : selectedCellPositions) {
                // only consider selections in the same column
                if (coord.getColumnPosition() == command.getColumnPosition()) {
                    positions.add(coord.getRowPosition());
                }
            }
        }

        return doCommand(new MultiRowHideCommand(this, positions.distinct().toSortedArray()));
    }

    /**
     * Will check if there are fully selected column positions. If there is at
     * least one fully selected column position, the {@link ColumnResizeCommand}
     * will be consumed and a {@link MultiColumnResizeCommand} will be created
     * and executed further down the layer stack, that contains all fully
     * selected column positions. Otherwise the given command will be executed
     * further.<br>
     *
     * This is necessary because neither the underlying layers are not aware of
     * the presence of the {@link SelectionLayer}. Without this transformation,
     * only the column on which the action was called will be resized instead of
     * all selected ones.
     *
     * @param command
     *            The {@link ColumnResizeCommand} to process
     * @return <code>true</code> if the command has been handled,
     *         <code>false</code> otherwise
     */
    protected boolean handleColumnResizeCommand(ColumnResizeCommand command) {
        if (isColumnPositionFullySelected(command.getColumnPosition())) {
            return super.doCommand(
                    new MultiColumnResizeCommand(this,
                            this.selectionModel.getFullySelectedColumnPositions(getRowCount()),
                            command.getNewColumnWidth(),
                            command.downScaleValue()));
        } else {
            return super.doCommand(command);
        }
    }

    /**
     * Will check if there are fully selected row positions. If there is at
     * least one fully selected row position, the {@link RowResizeCommand} will
     * be consumed and a {@link MultiRowResizeCommand} will be created and
     * executed further down the layer stack, that contains all fully selected
     * row positions. Otherwise the given command will be executed further.<br>
     *
     * This is necessary because neither the underlying layers are not aware of
     * the presence of the {@link SelectionLayer}. Without this transformation,
     * only the row on which the action was called will be resized instead of
     * all selected ones.
     *
     * @param command
     *            The {@link RowResizeCommand} to process
     * @return <code>true</code> if the command has been handled,
     *         <code>false</code> otherwise
     */
    protected boolean handleRowResizeCommand(RowResizeCommand command) {
        if (isRowPositionFullySelected(command.getRowPosition())) {
            return super.doCommand(
                    new MultiRowResizeCommand(this,
                            this.selectionModel.getFullySelectedRowPositions(getColumnCount()),
                            command.getNewHeight(),
                            command.downScaleValue()));
        } else {
            return super.doCommand(command);
        }
    }

    /**
     * Set the region that is currently <i>selected</i> via fill handle to
     * extend the current active selection for triggering a fill action.
     *
     * @param region
     *            The region <i>selected</i> via fill handle.
     *
     * @see FillHandleDragMode
     * @see FillHandleLayerPainter
     *
     * @since 1.4
     */
    public void setFillHandleRegion(Rectangle region) {
        this.fillHandleRegion = region;
    }

    /**
     * Returns the region that is currently <i>selected</i> via fill handle to
     * extend the current active selection. Used to perform actions on drag
     * &amp; drop of the fill handle.
     *
     * @return The region <i>selected</i> via fill handle or <code>null</code>.
     *
     * @since 1.4
     */
    public Rectangle getFillHandleRegion() {
        return this.fillHandleRegion;
    }

    /**
     * Marks the bottom right cell in a contiguous selection within the
     * {@link SelectionLayer}. Also removes the markup in case there is no
     * selection or the selection is not contiguous.
     *
     * @since 1.4
     */
    public void markFillHandleCell() {
        ILayerCell bottomRight = SelectionUtils.getBottomRightCellInSelection(this);
        if (bottomRight != null) {
            this.bottomRightInSelection = new PositionCoordinate(
                    this,
                    bottomRight.getColumnPosition(),
                    bottomRight.getRowPosition());
        } else {
            this.bottomRightInSelection = null;
        }
    }

    /**
     * @since 1.4
     */
    @Override
    public Collection<String> getProvidedLabels() {
        Collection<String> labels = super.getProvidedLabels();

        labels.add(SelectionStyleLabels.SELECTION_ANCHOR_STYLE);
        labels.add(SelectionStyleLabels.SELECTION_ANCHOR_GRID_LINE_STYLE);
        labels.add(SelectionStyleLabels.COLUMN_FULLY_SELECTED_STYLE);
        labels.add(SelectionStyleLabels.ROW_FULLY_SELECTED_STYLE);
        labels.add(SelectionStyleLabels.FILL_HANDLE_REGION);
        labels.add(SelectionStyleLabels.FILL_HANDLE_CELL);
        labels.add(SelectionStyleLabels.COPY_BORDER_STYLE);

        return labels;
    }
}
