/*******************************************************************************
 * Copyright (c) 2012, 2019 Original authors and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Original authors and others - initial API and implementation
 ******************************************************************************/
package org.eclipse.nebula.widgets.nattable.hideshow;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;

import org.eclipse.nebula.widgets.nattable.coordinate.PositionUtil;
import org.eclipse.nebula.widgets.nattable.coordinate.Range;
import org.eclipse.nebula.widgets.nattable.group.ColumnGroupModel.ColumnGroup;
import org.eclipse.nebula.widgets.nattable.layer.AbstractLayerTransform;
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
import org.eclipse.nebula.widgets.nattable.layer.IUniqueIndexLayer;
import org.eclipse.nebula.widgets.nattable.layer.LayerUtil;
import org.eclipse.nebula.widgets.nattable.layer.event.ILayerEvent;
import org.eclipse.nebula.widgets.nattable.layer.event.IStructuralChangeEvent;
import org.eclipse.nebula.widgets.nattable.reorder.event.ColumnReorderEvent;

public abstract class AbstractColumnHideShowLayer extends AbstractLayerTransform implements IUniqueIndexLayer {

    private List<Integer> cachedVisibleColumnIndexOrder;
    private Map<Integer, Integer> cachedVisibleColumnIndexPositionMap;

    private Map<Integer, Integer> cachedHiddenColumnIndexToPositionMap;

    private final Map<Integer, Integer> startXCache = new HashMap<Integer, Integer>();

    public AbstractColumnHideShowLayer(IUniqueIndexLayer underlyingLayer) {
        super(underlyingLayer);
    }

    @Override
    public void handleLayerEvent(ILayerEvent event) {
        if (event instanceof ColumnReorderEvent) {
            // we need to convert the before positions in the event BEFORE the
            // local states are changed, otherwise we are not able to convert
            // the before positions as the changed layer states would return
            // incorrect values
            ColumnReorderEvent reorderEvent = (ColumnReorderEvent) event;

            Collection<Integer> fromPositions = new TreeSet<Integer>();
            for (int pos : reorderEvent.getBeforeFromColumnIndexes()) {
                fromPositions.add(getColumnPositionByIndex(pos));
            }
            Collection<Range> fromRanges = PositionUtil.getRanges(fromPositions);

            int pos = -1;
            if (!isColumnIndexHidden(reorderEvent.getBeforeToColumnIndex())) {
                pos = getColumnPositionByIndex(reorderEvent.getBeforeToColumnIndex());
            } else {
                int i = 1;
                while (pos < 0) {
                    int next = reorderEvent.getBeforeToColumnPosition() + i;
                    if (next >= this.underlyingLayer.getColumnCount()) {
                        break;
                    }
                    pos = underlyingToLocalColumnPosition(this.underlyingLayer, next);
                    i++;
                }
                if (pos >= 0) {
                    reorderEvent.setBeforeToColumnIndex(getColumnIndexByPosition(pos));
                }
            }
            if (pos >= 0) {
                reorderEvent.setConvertedBeforePositions(this, fromRanges, pos);
            }
        }

        if (event instanceof IStructuralChangeEvent) {
            IStructuralChangeEvent structuralChangeEvent = (IStructuralChangeEvent) event;
            if (structuralChangeEvent.isHorizontalStructureChanged()) {
                invalidateCache();
            }
        }
        super.handleLayerEvent(event);
    }

    // Horizontal features

    // Columns

    @Override
    public int getColumnCount() {
        return getCachedVisibleColumnIndexes().size();
    }

    @Override
    public int getColumnIndexByPosition(int columnPosition) {
        if (columnPosition < 0 || columnPosition >= getColumnCount()) {
            return -1;
        }

        Integer columnIndex = getCachedVisibleColumnIndexes().get(columnPosition);
        return (columnIndex != null) ? columnIndex : -1;
    }

    @Override
    public int getColumnPositionByIndex(int columnIndex) {
        if (this.cachedVisibleColumnIndexPositionMap == null) {
            cacheVisibleColumnIndexes();
        }

        Integer position = this.cachedVisibleColumnIndexPositionMap.get(columnIndex);
        return (position != null) ? position : -1;
    }

    public Collection<Integer> getColumnPositionsByIndexes(Collection<Integer> columnIndexes) {
        Collection<Integer> columnPositions = new HashSet<Integer>();
        for (int columnIndex : columnIndexes) {
            columnPositions.add(getColumnPositionByIndex(columnIndex));
        }
        return columnPositions;
    }

    @Override
    public int localToUnderlyingColumnPosition(int localColumnPosition) {
        int columnIndex = getColumnIndexByPosition(localColumnPosition);
        return ((IUniqueIndexLayer) getUnderlyingLayer()).getColumnPositionByIndex(columnIndex);
    }

    @Override
    public int underlyingToLocalColumnPosition(ILayer sourceUnderlyingLayer, int underlyingColumnPosition) {
        int columnIndex = getUnderlyingLayer().getColumnIndexByPosition(underlyingColumnPosition);
        int columnPosition = getColumnPositionByIndex(columnIndex);
        if (columnPosition >= 0) {
            return columnPosition;
        } else {
            Integer hiddenColumnPosition = this.cachedHiddenColumnIndexToPositionMap.get(columnIndex);
            return (hiddenColumnPosition != null) ? hiddenColumnPosition : -1;
        }
    }

    @Override
    public Collection<Range> underlyingToLocalColumnPositions(
            ILayer sourceUnderlyingLayer,
            Collection<Range> underlyingColumnPositionRanges) {
        Collection<Range> localColumnPositionRanges =
                new ArrayList<Range>(underlyingColumnPositionRanges.size());

        for (Range underlyingColumnPositionRange : underlyingColumnPositionRanges) {
            int startColumnPosition = getAdjustedUnderlyingToLocalStartPosition(
                    sourceUnderlyingLayer,
                    underlyingColumnPositionRange.start,
                    underlyingColumnPositionRange.end);
            int endColumnPosition = getAdjustedUnderlyingToLocalEndPosition(
                    sourceUnderlyingLayer,
                    underlyingColumnPositionRange.end,
                    underlyingColumnPositionRange.start);

            // teichstaedt: fixes the problem that ranges where added even if
            // the corresponding startPosition weren't found in the underlying
            // layer. Without that fix a bunch of ranges of kind Range [-1, 180]
            // which causes strange behaviour in Freeze- and other Layers were
            // returned.
            if (startColumnPosition > -1) {
                localColumnPositionRanges.add(
                        new Range(startColumnPosition, endColumnPosition));
            }
        }

        return localColumnPositionRanges;
    }

    private int getAdjustedUnderlyingToLocalStartPosition(
            ILayer sourceUnderlyingLayer,
            int startUnderlyingPosition,
            int endUnderlyingPosition) {

        int localStartColumnPosition =
                underlyingToLocalColumnPosition(
                        sourceUnderlyingLayer,
                        startUnderlyingPosition);
        int offset = 0;
        while (localStartColumnPosition < 0
                && (startUnderlyingPosition + offset < endUnderlyingPosition)) {
            localStartColumnPosition =
                    underlyingToLocalColumnPosition(
                            sourceUnderlyingLayer,
                            startUnderlyingPosition + offset++);
        }
        return localStartColumnPosition;
    }

    private int getAdjustedUnderlyingToLocalEndPosition(
            ILayer sourceUnderlyingLayer,
            int endUnderlyingPosition,
            int startUnderlyingPosition) {

        int localEndColumnPosition =
                underlyingToLocalColumnPosition(
                        sourceUnderlyingLayer,
                        endUnderlyingPosition - 1);
        int offset = 0;
        while (localEndColumnPosition < 0
                && (endUnderlyingPosition - offset > startUnderlyingPosition)) {
            localEndColumnPosition =
                    underlyingToLocalColumnPosition(
                            sourceUnderlyingLayer,
                            endUnderlyingPosition - offset++);
        }
        return localEndColumnPosition + 1;
    }

    // Width

    @Override
    public int getWidth() {
        if (getColumnCount() == 0) {
            return 0;
        }

        int lastColumnPosition = getColumnCount() - 1;
        return getStartXOfColumnPosition(lastColumnPosition)
                + getColumnWidthByPosition(lastColumnPosition);
    }

    // X

    @Override
    public int getColumnPositionByX(int x) {
        return LayerUtil.getColumnPositionByX(this, x);
    }

    @Override
    public int getStartXOfColumnPosition(int localColumnPosition) {
        Integer cachedStartX = this.startXCache.get(localColumnPosition);
        if (cachedStartX != null) {
            return cachedStartX.intValue();
        }

        IUniqueIndexLayer underlyingLayer = (IUniqueIndexLayer) getUnderlyingLayer();
        int underlyingPosition = localToUnderlyingColumnPosition(localColumnPosition);
        if (underlyingPosition < 0) {
            return -1;
        }
        int underlyingStartX = underlyingLayer.getStartXOfColumnPosition(underlyingPosition);
        if (underlyingStartX < 0) {
            return -1;
        }

        for (Integer hiddenIndex : getHiddenColumnIndexes()) {
            int hiddenPosition = underlyingLayer.getColumnPositionByIndex(hiddenIndex);
            if (hiddenPosition <= underlyingPosition) {
                underlyingStartX -= underlyingLayer.getColumnWidthByPosition(hiddenPosition);
            }
        }

        this.startXCache.put(localColumnPosition, underlyingStartX);
        return underlyingStartX;
    }

    // Vertical features

    // Rows

    @Override
    public int getRowPositionByIndex(int rowIndex) {
        return ((IUniqueIndexLayer) getUnderlyingLayer()).getRowPositionByIndex(rowIndex);
    }

    // Hide/show

    /**
     * Will check if the column at the specified index is hidden or not. Checks
     * this layer and also the sublayers for the visibility. Note: As the
     * {@link ColumnGroup}s are created index based, this method only works
     * correctly with indexes rather than positions.
     *
     * @param columnIndex
     *            The column index of the column whose visibility state should
     *            be checked.
     * @return <code>true</code> if the column at the specified index is hidden,
     *         <code>false</code> if it is visible.
     */
    public abstract boolean isColumnIndexHidden(int columnIndex);

    /**
     * Will collect and return all indexes of the columns that are hidden in
     * this layer. Note: It is not intended that it also collects the column
     * indexes of underlying layers. This would cause issues on calculating
     * positions as every layer is responsible for those calculations itself.
     *
     * @return Collection of all column indexes that are hidden in this layer.
     */
    public abstract Collection<Integer> getHiddenColumnIndexes();

    // Cache

    /**
     * Invalidate the cache to ensure that information is rebuild.
     */
    protected void invalidateCache() {
        this.cachedVisibleColumnIndexOrder = null;
        this.cachedVisibleColumnIndexPositionMap = null;
        this.startXCache.clear();
    }

    private List<Integer> getCachedVisibleColumnIndexes() {
        if (this.cachedVisibleColumnIndexOrder == null) {
            cacheVisibleColumnIndexes();
        }
        return this.cachedVisibleColumnIndexOrder;
    }

    private void cacheVisibleColumnIndexes() {
        this.cachedVisibleColumnIndexOrder = new ArrayList<Integer>();
        this.cachedVisibleColumnIndexPositionMap = new HashMap<Integer, Integer>();
        this.cachedHiddenColumnIndexToPositionMap = new HashMap<Integer, Integer>();
        this.startXCache.clear();

        ILayer underlyingLayer = getUnderlyingLayer();
        int columnPosition = 0;
        for (int parentColumnPosition = 0; parentColumnPosition < underlyingLayer.getColumnCount(); parentColumnPosition++) {
            int columnIndex = underlyingLayer.getColumnIndexByPosition(parentColumnPosition);

            if (!isColumnIndexHidden(columnIndex)) {
                this.cachedVisibleColumnIndexOrder.add(columnIndex);
                this.cachedVisibleColumnIndexPositionMap.put(columnIndex, columnPosition);
                columnPosition++;
            } else {
                this.cachedHiddenColumnIndexToPositionMap.put(columnIndex, columnPosition);
            }
        }
    }

}
