/*******************************************************************************
 * 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
 *     Dirk Fauth <dirk.fauth@googlemail.com> - added ITraversalStrategy handling
 ******************************************************************************/
package org.eclipse.nebula.widgets.nattable.selection;

import org.eclipse.nebula.widgets.nattable.coordinate.PositionCoordinate;
import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;
import org.eclipse.nebula.widgets.nattable.selection.ITraversalStrategy.TraversalScope;
import org.eclipse.nebula.widgets.nattable.selection.command.MoveSelectionCommand;

/**
 * Specifies the semantics of moving the selection in the table, based on
 * selecting the adjoining cell(s).
 */
public class MoveCellSelectionCommandHandler extends MoveSelectionCommandHandler<MoveSelectionCommand> {

    protected PositionCoordinate lastSelectedCellPosition;
    protected int newSelectedColumnPosition;
    protected int newSelectedRowPosition;

    /**
     * Create a MoveCellSelectionCommandHandler for the given
     * {@link SelectionLayer}. Uses the
     * {@link ITraversalStrategy#AXIS_TRAVERSAL_STRATEGY} as default strategy
     * for selection movement.
     *
     * @param selectionLayer
     *            The {@link SelectionLayer} on which the selection should be
     *            performed.
     */
    public MoveCellSelectionCommandHandler(SelectionLayer selectionLayer) {
        super(selectionLayer);
    }

    /**
     * Create a MoveCellSelectionCommandHandler for the given
     * {@link SelectionLayer}.
     *
     * @param selectionLayer
     *            The {@link SelectionLayer} on which the selection should be
     *            performed.
     * @param traversalStrategy
     *            The strategy that should be used for selection movements. Can
     *            not be <code>null</code>.
     */
    public MoveCellSelectionCommandHandler(SelectionLayer selectionLayer, ITraversalStrategy traversalStrategy) {
        super(selectionLayer, traversalStrategy);
    }

    /**
     * Create a MoveCellSelectionCommandHandler for the given
     * {@link SelectionLayer} .
     *
     * @param selectionLayer
     *            The {@link SelectionLayer} on which the selection should be
     *            performed.
     * @param horizontalTraversalStrategy
     *            The strategy that should be used for horizontal selection
     *            movements. Can not be <code>null</code>.
     * @param verticalTraversalStrategy
     *            The strategy that should be used for vertical selection
     *            movements. Can not be <code>null</code>.
     */
    public MoveCellSelectionCommandHandler(SelectionLayer selectionLayer,
            ITraversalStrategy horizontalTraversalStrategy, ITraversalStrategy verticalTraversalStrategy) {
        super(selectionLayer, horizontalTraversalStrategy, verticalTraversalStrategy);
    }

    @Override
    protected void moveLastSelectedLeft(ITraversalStrategy traversalStrategy, boolean withShiftMask, boolean withControlMask) {
        if (this.selectionLayer.hasColumnSelection()) {
            this.lastSelectedCellPosition = this.selectionLayer.getCellPositionToMoveFrom(withShiftMask, withControlMask);
            ILayerCell lastSelectedCell = this.selectionLayer.getCellByPosition(
                    this.lastSelectedCellPosition.columnPosition,
                    this.lastSelectedCellPosition.rowPosition);
            if (lastSelectedCell != null) {
                int stepSize = traversalStrategy.getStepCount();
                this.newSelectedColumnPosition = (stepSize >= 0) ? (lastSelectedCell.getOriginColumnPosition() - stepSize) : 0;

                this.newSelectedRowPosition = this.lastSelectedCellPosition.rowPosition;

                ILayerCell newSelected = this.selectionLayer.getCellByPosition(
                        this.newSelectedColumnPosition,
                        this.newSelectedRowPosition);
                if (newSelected != null) {
                    this.newSelectedColumnPosition = newSelected.getOriginColumnPosition();
                }

                // boolean flag to stop traversal if calculated target is
                // invalid needed to avoid endless loop if there are no further
                // valid traversal targets
                boolean stopTraversalOnInvalid = false;

                if (this.newSelectedColumnPosition < 0) {
                    if (traversalStrategy.getTraversalScope().equals(TraversalScope.AXIS)) {
                        if (!traversalStrategy.isCycle()) {
                            // on axis scope with no cycle, stop moving
                            this.newSelectedColumnPosition = 0;
                            stopTraversalOnInvalid = true;
                        } else {
                            // on axis scope with cycle, move to end
                            while (this.newSelectedColumnPosition < 0) {
                                this.newSelectedColumnPosition = this.newSelectedColumnPosition + this.selectionLayer.getColumnCount();
                            }
                        }
                    } else if (traversalStrategy.getTraversalScope().equals(TraversalScope.TABLE)) {
                        // on table scope, move to end
                        int rowMove = 0;
                        while (this.newSelectedColumnPosition < 0) {
                            this.newSelectedColumnPosition = this.newSelectedColumnPosition + this.selectionLayer.getColumnCount();
                            rowMove++;
                        }
                        this.newSelectedRowPosition = this.newSelectedRowPosition - rowMove;
                        if (this.newSelectedRowPosition < 0) {
                            if (traversalStrategy.isCycle()) {
                                // at the top and cycle so go to bottom
                                this.newSelectedRowPosition = this.newSelectedRowPosition + this.selectionLayer.getRowCount();
                            } else {
                                // at the top and no cycle so stop moving
                                this.newSelectedColumnPosition = 0;
                                this.newSelectedRowPosition = 0;
                                stopTraversalOnInvalid = true;
                            }
                        }
                    }
                }

                if (positionMoved()) {
                    // check if calculated target is valid, otherwise move to
                    // adjacent
                    if (!traversalStrategy.isValidTarget(lastSelectedCell,
                            this.selectionLayer.getCellByPosition(this.newSelectedColumnPosition, this.newSelectedRowPosition))) {

                        // for MOVE_ALL we need to go backwards to find the last
                        // valid position
                        if (stepSize == SelectionLayer.MOVE_ALL) {
                            for (int i = this.newSelectedColumnPosition; i < this.selectionLayer.getColumnCount(); i++) {
                                ILayerCell newPosition = this.selectionLayer.getCellByPosition(i, this.newSelectedRowPosition);
                                if (traversalStrategy.isValidTarget(lastSelectedCell, newPosition)) {
                                    this.newSelectedColumnPosition = i;

                                    if (!withShiftMask) {
                                        this.selectionLayer.clear(false);
                                    }

                                    this.selectionLayer.selectCell(
                                            this.newSelectedColumnPosition,
                                            this.newSelectedRowPosition,
                                            withShiftMask,
                                            withControlMask);
                                    this.selectionLayer.fireCellSelectionEvent(
                                            this.newSelectedColumnPosition,
                                            this.newSelectedRowPosition,
                                            true,
                                            withShiftMask,
                                            withControlMask);

                                    break;
                                }
                            }
                        } else {
                            if (!stopTraversalOnInvalid) {
                                moveLastSelectedLeft(
                                        createIncrementalStrategy(traversalStrategy),
                                        withShiftMask, withControlMask);
                            } else {
                                // since the calculated target is invalid and
                                // invalid traversal movement should stop, the
                                // new selected position is the last valid one
                                this.newSelectedColumnPosition = this.lastSelectedCellPosition.columnPosition;
                                this.newSelectedRowPosition = this.lastSelectedCellPosition.rowPosition;
                            }
                        }
                    } else {
                        if (stepSize == SelectionLayer.MOVE_ALL && !withShiftMask) {
                            this.selectionLayer.clear(false);
                        }

                        this.selectionLayer.selectCell(
                                this.newSelectedColumnPosition,
                                this.newSelectedRowPosition,
                                withShiftMask,
                                withControlMask);
                        this.selectionLayer.fireCellSelectionEvent(
                                this.newSelectedColumnPosition,
                                this.newSelectedRowPosition,
                                true,
                                withShiftMask,
                                withControlMask);
                    }
                }
            }
        }
    }

    @Override
    protected void moveLastSelectedRight(final ITraversalStrategy traversalStrategy, boolean withShiftMask, boolean withControlMask) {
        if (this.selectionLayer.hasColumnSelection()) {
            this.lastSelectedCellPosition = this.selectionLayer.getCellPositionToMoveFrom(withShiftMask, withControlMask);
            ILayerCell lastSelectedCell = this.selectionLayer.getCellByPosition(
                    this.lastSelectedCellPosition.columnPosition,
                    this.lastSelectedCellPosition.rowPosition);
            if (lastSelectedCell != null) {
                int stepSize = traversalStrategy.getStepCount();
                this.newSelectedColumnPosition = (stepSize >= 0)
                        ? (lastSelectedCell.getOriginColumnPosition() + lastSelectedCell.getColumnSpan() - 1 + stepSize)
                        : (this.selectionLayer.getColumnCount() - 1);

                this.newSelectedRowPosition = this.lastSelectedCellPosition.rowPosition;

                ILayerCell newSelected = this.selectionLayer.getCellByPosition(
                        this.newSelectedColumnPosition,
                        this.newSelectedRowPosition);
                if (newSelected != null) {
                    // if cell has column spanning, ensure that the whole cell
                    // is displayed
                    this.newSelectedColumnPosition = newSelected.getOriginColumnPosition() + newSelected.getColumnSpan() - 1;
                }

                // boolean flag to stop traversal if calculated target is
                // invalid needed to avoid endless loop if there are no further
                // valid traversal targets
                boolean stopTraversalOnInvalid = false;

                if (this.newSelectedColumnPosition >= this.selectionLayer.getColumnCount()) {
                    if (traversalStrategy.getTraversalScope().equals(TraversalScope.AXIS)) {
                        if (!traversalStrategy.isCycle()) {
                            // on axis scope with no cycle, stop moving
                            this.newSelectedColumnPosition = this.selectionLayer.getColumnCount() - 1;
                            stopTraversalOnInvalid = true;
                        } else {
                            // on axis scope with cycle, start over at table
                            // beginning
                            while (this.newSelectedColumnPosition >= this.selectionLayer.getColumnCount()) {
                                this.newSelectedColumnPosition = this.newSelectedColumnPosition - this.selectionLayer.getColumnCount();
                            }
                        }
                    } else if (traversalStrategy.getTraversalScope().equals(TraversalScope.TABLE)) {
                        // on table scope, start over at table beginning
                        int rowMove = 0;
                        while (this.newSelectedColumnPosition >= this.selectionLayer.getColumnCount()) {
                            this.newSelectedColumnPosition = this.newSelectedColumnPosition - this.selectionLayer.getColumnCount();
                            rowMove++;
                        }
                        this.newSelectedRowPosition = this.newSelectedRowPosition + rowMove;
                        if (this.newSelectedRowPosition >= this.selectionLayer.getRowCount()) {
                            if (traversalStrategy.isCycle()) {
                                // at the bottom and cycle so go to top
                                this.newSelectedRowPosition = this.newSelectedRowPosition - this.selectionLayer.getRowCount();
                            } else {
                                // at the bottom and no cycle so stop moving
                                this.newSelectedColumnPosition = this.selectionLayer.getColumnCount() - 1;
                                this.newSelectedRowPosition = this.selectionLayer.getRowCount() - 1;
                                stopTraversalOnInvalid = true;
                            }
                        }
                    }
                }

                if (positionMoved()) {
                    // check if calculated target is valid, otherwise move to
                    // adjacent
                    if (!traversalStrategy.isValidTarget(lastSelectedCell,
                            this.selectionLayer.getCellByPosition(this.newSelectedColumnPosition, this.newSelectedRowPosition))) {

                        // for MOVE_ALL we need to go backwards to find the last
                        // valid position
                        if (stepSize == SelectionLayer.MOVE_ALL) {
                            for (int i = this.newSelectedColumnPosition; i >= 0; i--) {
                                ILayerCell newPosition = this.selectionLayer.getCellByPosition(i, this.newSelectedRowPosition);
                                if (traversalStrategy.isValidTarget(lastSelectedCell, newPosition)) {
                                    this.newSelectedColumnPosition = i;

                                    if (!withShiftMask) {
                                        this.selectionLayer.clear(false);
                                    }

                                    this.selectionLayer.selectCell(
                                            this.newSelectedColumnPosition,
                                            this.newSelectedRowPosition,
                                            withShiftMask,
                                            withControlMask);
                                    this.selectionLayer.fireCellSelectionEvent(
                                            this.newSelectedColumnPosition,
                                            this.newSelectedRowPosition,
                                            true,
                                            withShiftMask,
                                            withControlMask);

                                    break;
                                }
                            }
                        } else {
                            if (!stopTraversalOnInvalid) {
                                moveLastSelectedRight(
                                        createIncrementalStrategy(traversalStrategy),
                                        withShiftMask, withControlMask);
                            } else {
                                // since the calculated target is invalid and
                                // invalid traversal movement should stop, the
                                // new selected position is the last valid one
                                this.newSelectedColumnPosition = this.lastSelectedCellPosition.columnPosition;
                                this.newSelectedRowPosition = this.lastSelectedCellPosition.rowPosition;
                            }
                        }
                    } else {
                        if (stepSize == SelectionLayer.MOVE_ALL && !withShiftMask) {
                            this.selectionLayer.clear(false);
                        }

                        this.selectionLayer.selectCell(
                                this.newSelectedColumnPosition,
                                this.newSelectedRowPosition,
                                withShiftMask,
                                withControlMask);
                        this.selectionLayer.fireCellSelectionEvent(
                                this.newSelectedColumnPosition,
                                this.newSelectedRowPosition,
                                true,
                                withShiftMask,
                                withControlMask);
                    }
                }
            }
        }
    }

    @Override
    protected void moveLastSelectedUp(ITraversalStrategy traversalStrategy, boolean withShiftMask, boolean withControlMask) {
        if (this.selectionLayer.hasRowSelection()) {
            this.lastSelectedCellPosition = this.selectionLayer.getCellPositionToMoveFrom(withShiftMask, withControlMask);
            ILayerCell lastSelectedCell = this.selectionLayer.getCellByPosition(
                    this.lastSelectedCellPosition.columnPosition,
                    this.lastSelectedCellPosition.rowPosition);
            if (lastSelectedCell != null) {
                int stepSize = traversalStrategy.getStepCount();
                this.newSelectedColumnPosition = this.lastSelectedCellPosition.columnPosition;

                this.newSelectedRowPosition = (stepSize >= 0) ? lastSelectedCell.getOriginRowPosition() - stepSize : 0;

                ILayerCell newSelected = this.selectionLayer.getCellByPosition(
                        this.newSelectedColumnPosition,
                        this.newSelectedRowPosition);
                if (newSelected != null) {
                    this.newSelectedRowPosition = newSelected.getOriginRowPosition();
                }

                // boolean flag to stop traversal if calculated target is
                // invalid needed to avoid endless loop if there are no further
                // valid traversal targets
                boolean stopTraversalOnInvalid = false;

                if (this.newSelectedRowPosition < 0) {
                    if (traversalStrategy.getTraversalScope().equals(TraversalScope.AXIS)) {
                        if (!traversalStrategy.isCycle()) {
                            // on axis scope with no cycle, stop moving
                            this.newSelectedRowPosition = 0;
                            stopTraversalOnInvalid = true;
                        } else {
                            // on axis scope with cycle, move to bottom
                            while (this.newSelectedRowPosition < 0) {
                                this.newSelectedRowPosition = this.newSelectedRowPosition + this.selectionLayer.getRowCount();
                            }
                        }
                    } else if (traversalStrategy.getTraversalScope().equals(TraversalScope.TABLE)) {
                        // on table scope, move to bottom
                        int columnMove = 0;
                        while (this.newSelectedRowPosition < 0) {
                            this.newSelectedRowPosition = this.newSelectedRowPosition + this.selectionLayer.getRowCount();
                            columnMove++;
                        }
                        this.newSelectedColumnPosition = this.newSelectedColumnPosition - columnMove;
                        if (this.newSelectedColumnPosition < 0) {
                            if (traversalStrategy.isCycle()) {
                                // at the beginning and cycle so go to end
                                this.newSelectedColumnPosition = this.newSelectedColumnPosition + this.selectionLayer.getColumnCount();
                            } else {
                                // at the top and no cycle so stop moving
                                this.newSelectedColumnPosition = 0;
                                this.newSelectedRowPosition = 0;
                                stopTraversalOnInvalid = true;
                            }
                        }
                    }
                }

                if (positionMoved()) {
                    // check if calculated target is valid, otherwise move to
                    // adjacent
                    if (!traversalStrategy.isValidTarget(lastSelectedCell,
                            this.selectionLayer.getCellByPosition(this.newSelectedColumnPosition, this.newSelectedRowPosition))) {

                        // for MOVE_ALL we need to go backwards to find the last
                        // valid position
                        if (stepSize == SelectionLayer.MOVE_ALL) {
                            for (int i = this.newSelectedRowPosition; i < this.selectionLayer.getRowCount(); i++) {
                                ILayerCell newPosition = this.selectionLayer.getCellByPosition(this.newSelectedColumnPosition, i);
                                if (traversalStrategy.isValidTarget(lastSelectedCell, newPosition)) {
                                    this.newSelectedRowPosition = i;

                                    if (!withShiftMask) {
                                        this.selectionLayer.clear(false);
                                    }

                                    this.selectionLayer.selectCell(
                                            this.newSelectedColumnPosition,
                                            this.newSelectedRowPosition,
                                            withShiftMask,
                                            withControlMask);
                                    this.selectionLayer.fireCellSelectionEvent(
                                            this.newSelectedColumnPosition,
                                            this.newSelectedRowPosition,
                                            true,
                                            withShiftMask,
                                            withControlMask);

                                    break;
                                }
                            }
                        } else {
                            if (!stopTraversalOnInvalid) {
                                moveLastSelectedUp(
                                        createIncrementalStrategy(traversalStrategy),
                                        withShiftMask, withControlMask);
                            } else {
                                // since the calculated target is invalid and
                                // invalid traversal movement should stop, the
                                // new selected position is the last valid one
                                this.newSelectedColumnPosition = this.lastSelectedCellPosition.columnPosition;
                                this.newSelectedRowPosition = this.lastSelectedCellPosition.rowPosition;
                            }
                        }
                    } else {
                        if (stepSize == SelectionLayer.MOVE_ALL && !withShiftMask) {
                            this.selectionLayer.clear(false);
                        }

                        this.selectionLayer.selectCell(
                                this.newSelectedColumnPosition,
                                this.newSelectedRowPosition,
                                withShiftMask,
                                withControlMask);
                        this.selectionLayer.fireCellSelectionEvent(
                                this.newSelectedColumnPosition,
                                this.newSelectedRowPosition,
                                true,
                                withShiftMask,
                                withControlMask);
                    }
                }
            }
        }
    }

    @Override
    protected void moveLastSelectedDown(ITraversalStrategy traversalStrategy, boolean withShiftMask, boolean withControlMask) {
        if (this.selectionLayer.hasRowSelection()) {
            this.lastSelectedCellPosition = this.selectionLayer.getCellPositionToMoveFrom(withShiftMask, withControlMask);
            ILayerCell lastSelectedCell = this.selectionLayer.getCellByPosition(
                    this.lastSelectedCellPosition.columnPosition,
                    this.lastSelectedCellPosition.rowPosition);
            if (lastSelectedCell != null) {
                int stepSize = traversalStrategy.getStepCount();
                this.newSelectedColumnPosition = this.lastSelectedCellPosition.columnPosition;

                this.newSelectedRowPosition = (stepSize >= 0)
                        ? lastSelectedCell.getOriginRowPosition() + lastSelectedCell.getRowSpan() - 1 + stepSize
                        : this.selectionLayer.getRowCount() - 1;

                ILayerCell newSelected = this.selectionLayer.getCellByPosition(
                        this.newSelectedColumnPosition,
                        this.newSelectedRowPosition);
                if (newSelected != null) {
                    // if cell has row spanning, ensure that the whole cell is
                    // displayed
                    this.newSelectedRowPosition = newSelected.getOriginRowPosition() + newSelected.getRowSpan() - 1;
                }

                // boolean flag to stop traversal if calculated target is
                // invalid needed to avoid endless loop if there are no further
                // valid traversal targets
                boolean stopTraversalOnInvalid = false;

                if (this.newSelectedRowPosition >= this.selectionLayer.getRowCount()) {
                    if (traversalStrategy.getTraversalScope().equals(TraversalScope.AXIS)) {
                        if (!traversalStrategy.isCycle()) {
                            // on axis scope with no cycle, stop moving
                            this.newSelectedRowPosition = this.selectionLayer.getRowCount() - 1;
                            stopTraversalOnInvalid = true;
                        } else {
                            // on axis scope with cycle, move to top
                            while (this.newSelectedRowPosition >= this.selectionLayer.getRowCount()) {
                                this.newSelectedRowPosition = this.newSelectedRowPosition - this.selectionLayer.getRowCount();
                            }
                        }
                    } else if (traversalStrategy.getTraversalScope().equals(TraversalScope.TABLE)) {
                        // on table scope, move to top
                        int columnMove = 0;
                        while (this.newSelectedRowPosition >= this.selectionLayer.getRowCount()) {
                            this.newSelectedRowPosition = this.newSelectedRowPosition - this.selectionLayer.getRowCount();
                            columnMove++;
                        }
                        this.newSelectedColumnPosition = this.newSelectedColumnPosition + columnMove;
                        if (this.newSelectedColumnPosition >= this.selectionLayer.getColumnCount()) {
                            if (traversalStrategy.isCycle()) {
                                // at the end and cycle so go to beginning
                                this.newSelectedColumnPosition = this.newSelectedColumnPosition - this.selectionLayer.getColumnCount();
                            } else {
                                // at the end and no cycle so stop moving
                                this.newSelectedColumnPosition = this.selectionLayer.getColumnCount() - 1;
                                this.newSelectedRowPosition = this.selectionLayer.getRowCount() - 1;
                                stopTraversalOnInvalid = true;
                            }
                        }
                    }
                }

                if (positionMoved()) {
                    // check if calculated target is valid, otherwise move to
                    // adjacent
                    int targetColumnPosition = newSelected != null ? newSelected.getColumnPosition() : this.newSelectedColumnPosition;
                    int targetRowPosition = newSelected != null ? newSelected.getRowPosition() : this.newSelectedRowPosition;

                    if (!traversalStrategy.isValidTarget(lastSelectedCell,
                            this.selectionLayer.getCellByPosition(targetColumnPosition, targetRowPosition))) {

                        // for MOVE_ALL we need to go backwards to find the last
                        // valid position
                        if (stepSize == SelectionLayer.MOVE_ALL) {
                            for (int i = this.newSelectedRowPosition; i >= 0; i--) {
                                ILayerCell newPosition = this.selectionLayer.getCellByPosition(this.newSelectedColumnPosition, i);
                                if (traversalStrategy.isValidTarget(lastSelectedCell, newPosition)) {
                                    this.newSelectedRowPosition = i;

                                    if (!withShiftMask) {
                                        this.selectionLayer.clear(false);
                                    }

                                    this.selectionLayer.selectCell(
                                            this.newSelectedColumnPosition,
                                            this.newSelectedRowPosition,
                                            withShiftMask,
                                            withControlMask);
                                    this.selectionLayer.fireCellSelectionEvent(
                                            this.newSelectedColumnPosition,
                                            this.newSelectedRowPosition,
                                            true,
                                            withShiftMask,
                                            withControlMask);

                                    break;
                                }
                            }
                        } else {
                            if (!stopTraversalOnInvalid) {
                                moveLastSelectedDown(
                                        createIncrementalStrategy(traversalStrategy),
                                        withShiftMask, withControlMask);
                            } else {
                                // since the calculated target is invalid and
                                // invalid traversal movement should stop, the
                                // new selected position is the last valid one
                                this.newSelectedColumnPosition = this.lastSelectedCellPosition.columnPosition;
                                this.newSelectedRowPosition = this.lastSelectedCellPosition.rowPosition;
                            }
                        }
                    } else {
                        if (stepSize == SelectionLayer.MOVE_ALL && !withShiftMask) {
                            this.selectionLayer.clear(false);
                        }

                        this.selectionLayer.selectCell(
                                this.newSelectedColumnPosition,
                                this.newSelectedRowPosition,
                                withShiftMask,
                                withControlMask);
                        this.selectionLayer.fireCellSelectionEvent(
                                this.newSelectedColumnPosition,
                                this.newSelectedRowPosition,
                                true,
                                withShiftMask,
                                withControlMask);
                    }
                }
            }
        }
    }

    /**
     * Creates a {@link ITraversalStrategy} that wraps the given base strategy
     * but returning the step count + 1. Used to perform incremental movement in
     * case the base strategy specifies logic to determine whether a target cell
     * is a valid move target or not.
     *
     * @param baseStrategy
     *            The {@link ITraversalStrategy} to wrap.
     * @return A {@link ITraversalStrategy} that wraps the given base strategy
     *         using the given step count.
     */
    protected ITraversalStrategy createIncrementalStrategy(final ITraversalStrategy baseStrategy) {
        return new ITraversalStrategy() {

            @Override
            public TraversalScope getTraversalScope() {
                return baseStrategy.getTraversalScope();
            }

            @Override
            public boolean isCycle() {
                return baseStrategy.isCycle();
            }

            @Override
            public int getStepCount() {
                return baseStrategy.getStepCount() + 1;
            }

            @Override
            public boolean isValidTarget(ILayerCell from, ILayerCell to) {
                return baseStrategy.isValidTarget(from, to);
            }

        };
    }

    /**
     *
     * @return <code>true</code> if the selection moved in any direction,
     *         <code>false</code> if the selection stays at the same position
     */
    protected boolean positionMoved() {
        return (this.newSelectedColumnPosition != this.lastSelectedCellPosition.columnPosition
                || this.newSelectedRowPosition != this.lastSelectedCellPosition.rowPosition);
    }

    @Override
    public Class<MoveSelectionCommand> getCommandClass() {
        return MoveSelectionCommand.class;
    }

}
