/*****************************************************************************
 * Copyright (c) 2018, 2020 Dirk Fauth.
 *
 * 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:
 *      Dirk Fauth <dirk.fauth@googlemail.com> - Initial API and implementation
 *****************************************************************************/
package org.eclipse.nebula.widgets.nattable.hideshow.indicator;

import org.eclipse.nebula.widgets.nattable.hierarchical.HierarchicalTreeLayer;
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
import org.eclipse.nebula.widgets.nattable.layer.LabelStack;
import org.eclipse.nebula.widgets.nattable.layer.LayerUtil;
import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;

/**
 * Specialization of the {@link HideIndicatorOverlayPainter} that renders the
 * hide indicator in the level header columns of a
 * {@link HierarchicalTreeLayer}. The identification of the level header columns
 * is done via the cell label {@link HierarchicalTreeLayer#LEVEL_HEADER_CELL}.
 *
 * @since 1.6
 */
public class HierarchicalHideIndicatorOverlayPainter extends HideIndicatorOverlayPainter {

    protected HierarchicalTreeLayer treeLayer;

    /**
     * Creates a {@link HierarchicalHideIndicatorOverlayPainter} that renders
     * the hide indicator in the given given column header layer and the
     * {@link HierarchicalTreeLayer} level header columns.
     *
     * @param columnHeaderLayer
     *            The layer in the column header that should be used to
     *            determine the height of the hidden column indicator. Should be
     *            the top most layer in the column header region, e.g. the
     *            FilterRowHeaderComposite in case filtering is included. Can be
     *            <code>null</code> to avoid rendering of hidden column
     *            indicators.
     */
    public HierarchicalHideIndicatorOverlayPainter(ILayer columnHeaderLayer, HierarchicalTreeLayer treeLayer) {
        this(columnHeaderLayer, null, treeLayer);
    }

    /**
     * Creates a {@link HierarchicalHideIndicatorOverlayPainter} that renders
     * the hide indicator in the given header layers and the
     * {@link HierarchicalTreeLayer} level header columns.
     *
     * @param columnHeaderLayer
     *            The layer in the column header that should be used to
     *            determine the height of the hidden column indicator. Should be
     *            the top most layer in the column header region, e.g. the
     *            FilterRowHeaderComposite in case filtering is included. Can be
     *            <code>null</code> to avoid rendering of hidden column
     *            indicators.
     * @param rowHeaderLayer
     *            The layer in the row header that should be used to determine
     *            the width of the hidden row indicator. Should be the top most
     *            layer in the row header region. Can be <code>null</code> to
     *            avoid rendering of hidden row indicators.
     */
    public HierarchicalHideIndicatorOverlayPainter(ILayer columnHeaderLayer, ILayer rowHeaderLayer, HierarchicalTreeLayer treeLayer) {
        super(columnHeaderLayer, rowHeaderLayer);
        this.treeLayer = treeLayer;
    }

    @Override
    protected void paintHiddenColumnIndicator(ILayer layer, GC gc, int xOffset, int yOffset, Rectangle rectangle) {
        if (this.columnHeaderLayer != null) {
            int lineAdjustment = gc.getLineWidth() % 2;
            int height = this.columnHeaderLayer.getHeight();

            for (int col = 0; col < layer.getColumnCount(); col++) {
                LabelStack configLabels = layer.getConfigLabelsByPosition(col, this.columnHeaderLayer.getRowCount());
                if (configLabels.hasLabel(HideIndicatorConstants.COLUMN_LEFT_HIDDEN)) {
                    // ensure that the current column and the left column belong
                    // to the same level
                    int currentLevel = this.treeLayer.getLevelByColumnIndex(layer.getColumnIndexByPosition(col));
                    int leftLevel = this.treeLayer.getLevelByColumnIndex(layer.getColumnIndexByPosition(col - 1));
                    if (currentLevel == leftLevel) {
                        int x = layer.getStartXOfColumnPosition(col);
                        if (this.rowHeaderLayer == null || x >= this.rowHeaderLayer.getWidth()) {
                            int start = rectangle.y;
                            for (int i = 0; i < this.columnHeaderLayer.getRowCount(); i++) {
                                ILayerCell cell = layer.getCellByPosition(col, i);
                                int cellStart = layer.getStartXOfColumnPosition(cell.getOriginColumnPosition());
                                if (cellStart < x
                                        && ((this.rowHeaderLayer != null && x > this.rowHeaderLayer.getWidth())
                                                || (this.rowHeaderLayer == null && x > 0))) {
                                    start += layer.getRowHeightByPosition(i);
                                }
                            }
                            gc.drawLine(x - lineAdjustment, start, x - lineAdjustment, height);
                        }
                    }
                }

                if (configLabels.hasLabel(HideIndicatorConstants.COLUMN_RIGHT_HIDDEN)) {
                    // ensure that the current column and the right column
                    // belong to the same level
                    int currentLevel = this.treeLayer.getLevelByColumnIndex(layer.getColumnIndexByPosition(col));
                    int rightPos = LayerUtil.convertColumnPosition(layer, col + 1, this.treeLayer);
                    int rightIndex = layer.getColumnIndexByPosition(rightPos);

                    int rightLevel = this.treeLayer.getLevelByColumnIndex(rightIndex);
                    if (currentLevel == rightLevel || (rightIndex < 0 && !this.treeLayer.isLevelHeaderColumn(rightPos))) {
                        // render the line on the right side of the last column
                        int x = layer.getStartXOfColumnPosition(col) + layer.getColumnWidthByPosition(col);
                        // adjust the rendering for the whole line width to
                        // avoid overlapping
                        if (col == layer.getColumnCount() - 1) {
                            lineAdjustment = (gc.getLineWidth() / 2) + lineAdjustment;
                        }
                        if (this.rowHeaderLayer == null || x >= this.rowHeaderLayer.getWidth()) {
                            int start = rectangle.y;
                            for (int i = 0; i < this.columnHeaderLayer.getRowCount(); i++) {
                                ILayerCell cell = layer.getCellByPosition(col + 1, i);
                                if (cell != null
                                        && cell.getOriginColumnPosition() < cell.getColumnPosition()
                                        && x < (cell.getBounds().x + cell.getBounds().width)) {
                                    start += layer.getRowHeightByPosition(i);
                                }
                            }
                            gc.drawLine(x - lineAdjustment, start, x - lineAdjustment, height - 1);
                        }
                    }
                }
            }
        }
    }

    @Override
    protected void paintHiddenRowIndicator(ILayer layer, GC gc, int xOffset, int yOffset, Rectangle rectangle) {
        // just in case there is a composition with a row header layer and a
        // HierarchicalTreeLayer
        super.paintHiddenRowIndicator(layer, gc, xOffset, yOffset, rectangle);

        int lineAdjustment = gc.getLineWidth() % 2;

        int startRow = this.columnHeaderLayer == null ? 0 : this.columnHeaderLayer.getRowCount();
        for (int col = 0; col < layer.getColumnCount(); col++) {
            LabelStack labels = layer.getConfigLabelsByPosition(col, startRow);
            if (labels.hasLabel(HierarchicalTreeLayer.LEVEL_HEADER_CELL)) {
                for (int row = startRow; row < layer.getRowCount(); row++) {
                    // get labels for column + 1 to reach the body without
                    // the level header
                    LabelStack configLabels = layer.getConfigLabelsByPosition(col + 1, row);
                    if (configLabels.hasLabel(HideIndicatorConstants.ROW_TOP_HIDDEN)) {
                        int y = layer.getStartYOfRowPosition(row);
                        if (this.columnHeaderLayer == null || y >= this.columnHeaderLayer.getHeight()) {
                            ILayerCell cell = layer.getCellByPosition(col, row);
                            int cellStart = layer.getStartYOfRowPosition(cell.getOriginRowPosition());
                            if (cellStart == y) {
                                int startX = layer.getStartXOfColumnPosition(col);
                                gc.drawLine(
                                        startX,
                                        y - lineAdjustment,
                                        startX + layer.getColumnWidthByPosition(col),
                                        y - lineAdjustment);
                            }
                        }
                    }

                    if (configLabels.hasLabel(HideIndicatorConstants.ROW_BOTTOM_HIDDEN)) {
                        int y = layer.getStartYOfRowPosition(row) + layer.getRowHeightByPosition(row);
                        // adjust the rendering for the whole line width to
                        // avoid overlapping
                        if (row == layer.getRowCount() - 1) {
                            lineAdjustment = (gc.getLineWidth() / 2) + lineAdjustment;
                        }
                        if (this.columnHeaderLayer == null || y >= this.columnHeaderLayer.getHeight()) {
                            ILayerCell cell = layer.getCellByPosition(col, row);
                            int cellStart = layer.getStartYOfRowPosition(cell.getOriginRowPosition());
                            if (cellStart == y) {
                                int startX = layer.getStartXOfColumnPosition(col);
                                gc.drawLine(
                                        startX,
                                        y - lineAdjustment,
                                        startX + layer.getColumnWidthByPosition(col),
                                        y - lineAdjustment);
                            }
                        }
                    }
                }
            }
        }
    }
}
