/*******************************************************************************
 * 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
 ******************************************************************************/
package org.eclipse.nebula.widgets.nattable.grid.layer;

import java.util.Collection;

import org.eclipse.nebula.widgets.nattable.columnRename.DisplayColumnRenameDialogCommandHandler;
import org.eclipse.nebula.widgets.nattable.columnRename.RenameColumnHeaderCommandHandler;
import org.eclipse.nebula.widgets.nattable.columnRename.RenameColumnHelper;
import org.eclipse.nebula.widgets.nattable.columnRename.event.RenameColumnHeaderEvent;
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
import org.eclipse.nebula.widgets.nattable.layer.IUniqueIndexLayer;
import org.eclipse.nebula.widgets.nattable.layer.LabelStack;
import org.eclipse.nebula.widgets.nattable.layer.LayerUtil;
import org.eclipse.nebula.widgets.nattable.layer.config.DefaultColumnHeaderLayerConfiguration;
import org.eclipse.nebula.widgets.nattable.layer.event.ILayerEvent;
import org.eclipse.nebula.widgets.nattable.layer.event.IStructuralChangeEvent;
import org.eclipse.nebula.widgets.nattable.layer.event.StructuralChangeEventHelper;
import org.eclipse.nebula.widgets.nattable.layer.event.StructuralDiff;
import org.eclipse.nebula.widgets.nattable.painter.layer.ILayerPainter;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
import org.eclipse.nebula.widgets.nattable.style.SelectionStyleLabels;

/**
 * Responsible for rendering, event handling etc on the column headers.
 */
public class ColumnHeaderLayer extends DimensionallyDependentLayer {

    private final SelectionLayer[] selectionLayer;

    protected RenameColumnHelper renameColumnHelper;

    /**
     * Creates a column header layer using the default configuration and painter
     *
     * @param baseLayer
     *            The base layer for this layer, typically a DataLayer.
     * @param horizontalLayerDependency
     *            The layer to link the horizontal dimension to, typically the
     *            body layer.
     * @param selectionLayer
     *            The SelectionLayer needed to respond to selection events.
     */
    public ColumnHeaderLayer(
            IUniqueIndexLayer baseLayer,
            ILayer horizontalLayerDependency,
            SelectionLayer selectionLayer) {

        this(baseLayer, horizontalLayerDependency, selectionLayer, true);
    }

    /**
     * Creates a column header layer using the default configuration and painter
     *
     * @param baseLayer
     *            The base layer for this layer, typically a DataLayer.
     * @param horizontalLayerDependency
     *            The layer to link the horizontal dimension to, typically the
     *            body layer.
     * @param selectionLayer
     *            0 to multiple SelectionLayer needed to respond to selection
     *            events.
     * @since 1.4
     */
    public ColumnHeaderLayer(
            IUniqueIndexLayer baseLayer,
            ILayer horizontalLayerDependency,
            SelectionLayer... selectionLayer) {

        this(baseLayer, horizontalLayerDependency, selectionLayer, true);
    }

    /**
     * Creates a row header layer using the default painter.
     *
     * @param baseLayer
     *            The base layer for this layer, typically a DataLayer.
     * @param horizontalLayerDependency
     *            The layer to link the horizontal dimension to, typically the
     *            body layer.
     * @param selectionLayer
     *            The SelectionLayer needed to respond to selection events.
     * @param useDefaultConfiguration
     *            Flag to configure whether to use the default configuration or
     *            not.
     */
    public ColumnHeaderLayer(
            IUniqueIndexLayer baseLayer,
            ILayer horizontalLayerDependency,
            SelectionLayer selectionLayer,
            boolean useDefaultConfiguration) {

        this(baseLayer, horizontalLayerDependency, selectionLayer, useDefaultConfiguration, null);
    }

    /**
     * Creates a row header layer using the default painter.
     *
     * @param baseLayer
     *            The base layer for this layer, typically a DataLayer.
     * @param horizontalLayerDependency
     *            The layer to link the horizontal dimension to, typically the
     *            body layer.
     * @param selectionLayer
     *            0 to multiple SelectionLayer needed to respond to selection
     *            events.
     * @param useDefaultConfiguration
     *            Flag to configure whether to use the default configuration or
     *            not.
     * @since 1.4
     */
    public ColumnHeaderLayer(
            IUniqueIndexLayer baseLayer,
            ILayer horizontalLayerDependency,
            SelectionLayer[] selectionLayer,
            boolean useDefaultConfiguration) {

        this(baseLayer, horizontalLayerDependency, selectionLayer, useDefaultConfiguration, null);
    }

    /**
     * @param baseLayer
     *            The base layer for this layer, typically a DataLayer.
     * @param horizontalLayerDependency
     *            The layer to link the horizontal dimension to, typically the
     *            body layer.
     * @param selectionLayer
     *            The SelectionLayer needed to respond to selection events.
     * @param useDefaultConfiguration
     *            Flag to configure whether to use the default configuration or
     *            not.
     * @param layerPainter
     *            The painter for this layer or <code>null</code> to use the
     *            painter of the base layer.
     */
    public ColumnHeaderLayer(
            IUniqueIndexLayer baseLayer,
            ILayer horizontalLayerDependency,
            SelectionLayer selectionLayer,
            boolean useDefaultConfiguration,
            ILayerPainter layerPainter) {

        this(baseLayer, horizontalLayerDependency,
                selectionLayer != null ? new SelectionLayer[] { selectionLayer } : new SelectionLayer[] {},
                useDefaultConfiguration, layerPainter);
    }

    /**
     *
     * @param baseLayer
     *            The base layer for this layer, typically a DataLayer.
     * @param horizontalLayerDependency
     *            The layer to link the horizontal dimension to, typically the
     *            body layer.
     * @param selectionLayer
     *            0 to multiple SelectionLayer needed to respond to selection
     *            events.
     * @param useDefaultConfiguration
     *            Flag to configure whether to use the default configuration or
     *            not.
     * @param layerPainter
     *            The painter for this layer or <code>null</code> to use the
     *            painter of the base layer.
     * @since 1.4
     */
    public ColumnHeaderLayer(
            IUniqueIndexLayer baseLayer,
            ILayer horizontalLayerDependency,
            SelectionLayer[] selectionLayer,
            boolean useDefaultConfiguration,
            ILayerPainter layerPainter) {

        super(baseLayer, horizontalLayerDependency, baseLayer);

        if (selectionLayer == null) {
            this.selectionLayer = new SelectionLayer[] {};
        } else {
            this.selectionLayer = selectionLayer;
        }

        this.layerPainter = layerPainter;

        this.renameColumnHelper = new RenameColumnHelper(this);
        registerPersistable(this.renameColumnHelper);

        for (SelectionLayer sl : this.selectionLayer) {
            sl.addLayerListener(new ColumnHeaderSelectionListener(this));
        }
        registerCommandHandlers();

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

    @Override
    public String getDisplayModeByPosition(int columnPosition, int rowPosition) {
        String displayMode = super.getDisplayModeByPosition(columnPosition, rowPosition);
        if (this.selectionLayer.length > 0) {
            int selectionLayerColumnPosition = LayerUtil.convertColumnPosition(this, columnPosition, this.selectionLayer[0]);
            for (SelectionLayer sl : this.selectionLayer) {
                if (sl.isColumnPositionSelected(selectionLayerColumnPosition)) {
                    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);

        if (this.selectionLayer.length > 0) {
            final int selectionLayerColumnPosition = LayerUtil.convertColumnPosition(this, columnPosition, this.selectionLayer[0]);
            boolean fullySelected = true;
            for (SelectionLayer sl : this.selectionLayer) {
                if (!sl.isColumnPositionFullySelected(selectionLayerColumnPosition)) {
                    fullySelected = false;
                    break;
                }
            }

            if (fullySelected) {
                labelStack.addLabel(SelectionStyleLabels.COLUMN_FULLY_SELECTED_STYLE);
            }
        }

        return labelStack;
    }

    @Override
    public Object getDataValueByPosition(int columnPosition, int rowPosition) {
        int columnIndex = getColumnIndexByPosition(columnPosition);
        if (isColumnRenamed(columnIndex)) {
            return getRenamedColumnLabelByIndex(columnIndex);
        }
        return super.getDataValueByPosition(columnPosition, rowPosition);
    }

    // Configuration

    @Override
    protected void registerCommandHandlers() {
        registerCommandHandler(new RenameColumnHeaderCommandHandler(this));
        registerCommandHandler(new DisplayColumnRenameDialogCommandHandler(this));
    }

    // Column header renaming

    @Override
    public void handleLayerEvent(ILayerEvent event) {
        if (event instanceof IStructuralChangeEvent) {
            IStructuralChangeEvent structuralChangeEvent = (IStructuralChangeEvent) event;
            if (structuralChangeEvent.isHorizontalStructureChanged()) {
                Collection<StructuralDiff> columnDiffs = structuralChangeEvent.getColumnDiffs();

                if (columnDiffs != null && !columnDiffs.isEmpty()
                        && !StructuralChangeEventHelper.isReorder(columnDiffs)) {
                    this.renameColumnHelper.handleStructuralChanges(columnDiffs);
                }
            }
        }
        super.handleLayerEvent(event);
    }

    /**
     * @param columnPosition
     *            the column position for which the original label is requested
     * @return column header as defined by the data source
     */
    public String getOriginalColumnLabel(int columnPosition) {
        Object dataValue = super.getDataValueByPosition(columnPosition, 0);
        return dataValue != null ? dataValue.toString() : ""; //$NON-NLS-1$
    }

    /**
     * @param columnPosition
     *            the column position for which the renamed label is requested
     * @return renamed column header if the column has been renamed, NULL
     *         otherwise
     */
    public String getRenamedColumnLabel(int columnPosition) {
        int index = getColumnIndexByPosition(columnPosition);
        return getRenamedColumnLabelByIndex(index);
    }

    /**
     * @param columnIndex
     *            the column index for which the renamed label is requested
     * @return renamed column header if the column has been renamed, NULL
     *         otherwise
     */
    public String getRenamedColumnLabelByIndex(int columnIndex) {
        return this.renameColumnHelper.getRenamedColumnLabel(columnIndex);
    }

    /**
     * @param columnIndex
     *            the column index that should be checked
     * @return <code>true</code> if the column at the given index has been given
     *         a custom name by the user.
     */
    public boolean isColumnRenamed(int columnIndex) {
        return this.renameColumnHelper.isColumnRenamed(columnIndex);
    }

    public boolean renameColumnPosition(int columnPosition, String customColumnName) {
        boolean renamed = this.renameColumnHelper.renameColumnPosition(columnPosition, customColumnName);
        if (renamed) {
            fireLayerEvent(new RenameColumnHeaderEvent(this, columnPosition));
        }
        return renamed;
    }

    public boolean renameColumnIndex(int columnIndex, String customColumnName) {
        boolean renamed = this.renameColumnHelper.renameColumnIndex(columnIndex, customColumnName);
        if (renamed) {
            // search for the bottom layer in the horizontal dependency to
            // create the event for index and correct layer
            ILayer baseLayer = getHorizontalLayerDependency();
            while (baseLayer.getUnderlyingLayerByPosition(0, 0) != null) {
                baseLayer = baseLayer.getUnderlyingLayerByPosition(0, 0);
            }

            baseLayer.fireLayerEvent(new RenameColumnHeaderEvent(baseLayer, columnIndex));
        }
        return renamed;
    }

}
