/*******************************************************************************
 * 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.extension.glazedlists.groupBy;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;
import org.eclipse.nebula.widgets.nattable.painter.cell.AbstractCellPainter;
import org.eclipse.nebula.widgets.nattable.style.CellStyleAttributes;
import org.eclipse.nebula.widgets.nattable.style.CellStyleUtil;
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
import org.eclipse.nebula.widgets.nattable.style.IStyle;
import org.eclipse.nebula.widgets.nattable.util.GUIHelper;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;

/**
 * The painter that is used to render the groupBy state.
 */
public class GroupByHeaderPainter extends AbstractCellPainter {

    private static final int LEFT_INDENT = 2;
    private static final int ENDCAP_WIDTH = 8;
    private static final int X_PADDING = 4;
    private static final int Y_PADDING = 2;

    private final GroupByModel groupByModel;
    private final IDataProvider columnHeaderDataProvider;
    private final ColumnHeaderLayer columnHeaderLayer;

    private List<Rectangle> groupByCellBounds = new ArrayList<>();

    /**
     *
     * @param groupByModel
     *            The {@link GroupByModel} needed to retrieve the groupBy state.
     * @param columnHeaderDataProvider
     *            The {@link IDataProvider} needed to retrieve the column label.
     */
    public GroupByHeaderPainter(GroupByModel groupByModel, IDataProvider columnHeaderDataProvider) {
        this.groupByModel = groupByModel;
        this.columnHeaderDataProvider = columnHeaderDataProvider;
        this.columnHeaderLayer = null;
    }

    /**
     * @param groupByModel
     *            The {@link GroupByModel} needed to retrieve the groupBy state.
     * @param columnHeaderDataProvider
     *            The {@link IDataProvider} needed to retrieve the column label.
     * @param columnHeaderLayer
     *            The {@link ColumnHeaderLayer} needed to retrieve the column
     *            label in case a user renamed a column.
     * @since 1.5
     */
    public GroupByHeaderPainter(GroupByModel groupByModel,
            IDataProvider columnHeaderDataProvider, ColumnHeaderLayer columnHeaderLayer) {
        this.groupByModel = groupByModel;
        this.columnHeaderDataProvider = columnHeaderDataProvider;
        this.columnHeaderLayer = columnHeaderLayer;
    }

    @Override
    public void paintCell(ILayerCell cell, GC gc, Rectangle bounds, IConfigRegistry configRegistry) {
        Color originalBackground = gc.getBackground();
        Color originalForeground = gc.getForeground();
        Font originalFont = gc.getFont();

        // get color for header background
        Color headerBgColor = configRegistry.getConfigAttribute(
                GroupByConfigAttributes.GROUP_BY_HEADER_BACKGROUND_COLOR,
                DisplayMode.NORMAL);
        if (headerBgColor != null) {
            gc.setBackground(headerBgColor);
        }
        // Draw background
        gc.fillRectangle(bounds);

        this.groupByCellBounds.clear();

        IStyle cellStyle = CellStyleUtil.getCellStyle(cell, configRegistry);
        gc.setBackground(cellStyle.getAttributeValue(CellStyleAttributes.BACKGROUND_COLOR));
        gc.setForeground(cellStyle.getAttributeValue(CellStyleAttributes.FOREGROUND_COLOR));
        gc.setFont(cellStyle.getAttributeValue(CellStyleAttributes.FONT));
        gc.setAntialias(GUIHelper.DEFAULT_ANTIALIAS);
        gc.setTextAntialias(GUIHelper.DEFAULT_TEXT_ANTIALIAS);

        List<Integer> groupByColumnIndexes = this.groupByModel.getGroupByColumnIndexes();
        if (!groupByColumnIndexes.isEmpty()) {

            int textHeight = gc.textExtent("X").y; //$NON-NLS-1$

            int x0 = bounds.x + LEFT_INDENT;
            int y0 = bounds.y + bounds.height / 2 - textHeight / 2 - Y_PADDING;
            int yHeight = Y_PADDING + textHeight + Y_PADDING;

            // Draw leftmost edge
            gc.drawLine(x0, y0, x0, y0 + yHeight);
            x0++;

            // Draw group by columns
            int lastColumnIndex = groupByColumnIndexes.size() - 1;
            for (int i = 0; i <= lastColumnIndex; i++) {
                int columnIndex = groupByColumnIndexes.get(i);

                String columnName = null;
                if (this.columnHeaderLayer != null && this.columnHeaderLayer.isColumnRenamed(columnIndex)) {
                    columnName = this.columnHeaderLayer.getRenamedColumnLabelByIndex(columnIndex);
                } else {
                    columnName = (String) this.columnHeaderDataProvider.getDataValue(columnIndex, 0);
                }
                int textWidth = gc.textExtent(columnName).x;

                this.groupByCellBounds.add(new Rectangle(x0, y0, X_PADDING + textWidth + X_PADDING, yHeight));

                gc.fillRectangle(x0, y0, X_PADDING + textWidth + X_PADDING, yHeight);
                gc.drawLine(x0, y0, x0 + X_PADDING + textWidth + X_PADDING, y0);
                gc.drawLine(x0, y0 + yHeight, x0 + X_PADDING + textWidth + X_PADDING, y0 + yHeight);

                gc.drawText(columnName, x0 + X_PADDING, y0 + Y_PADDING);

                x0 += X_PADDING + textWidth + X_PADDING;

                // Draw end cap
                if (i < lastColumnIndex) {
                    gc.fillRectangle(x0, y0, ENDCAP_WIDTH, yHeight);
                    gc.drawLine(x0, y0, x0 + ENDCAP_WIDTH, y0);
                    gc.drawLine(x0, y0 + yHeight, x0 + ENDCAP_WIDTH, y0 + yHeight);
                } else {
                    gc.fillPolygon(new int[] { x0, y0, x0 + ENDCAP_WIDTH, y0 + yHeight / 2, x0, y0 + yHeight });
                }
                gc.drawLine(x0, y0, x0 + ENDCAP_WIDTH - 1, y0 + yHeight / 2);
                gc.drawLine(x0, y0 + yHeight, x0 + ENDCAP_WIDTH - 1, y0 + yHeight / 2);

                x0 += ENDCAP_WIDTH;
            }
        } else {
            // if no grouping is applied and a hint is specified via
            // configuration, the hint is rendered
            String hint = configRegistry.getConfigAttribute(
                    GroupByConfigAttributes.GROUP_BY_HINT,
                    DisplayMode.NORMAL);
            if (hint != null) {
                // check if there is a separate styling configured for the hint
                IStyle hintStyle = configRegistry.getConfigAttribute(
                        GroupByConfigAttributes.GROUP_BY_HINT_STYLE,
                        DisplayMode.NORMAL);
                if (hintStyle != null) {
                    Color hintBackground = hintStyle.getAttributeValue(CellStyleAttributes.BACKGROUND_COLOR);
                    gc.setBackground(hintBackground != null ? hintBackground : originalBackground);
                    Color hintForeground = hintStyle.getAttributeValue(CellStyleAttributes.FOREGROUND_COLOR);
                    if (hintForeground != null) {
                        gc.setForeground(hintForeground);
                    }
                    Font hintFont = CellStyleUtil.getFont(hintStyle, configRegistry);
                    if (hintFont != null) {
                        gc.setFont(hintFont);
                    }
                } else {
                    // ensure the background is the same as the background of
                    // the groupby header region
                    gc.setBackground(originalBackground);
                }

                int textHeight = gc.textExtent("X").y; //$NON-NLS-1$
                int x0 = bounds.x + LEFT_INDENT;
                int y0 = bounds.y + bounds.height / 2 - textHeight / 2 - Y_PADDING;
                gc.drawText(hint, x0 + X_PADDING, y0);
            }
        }

        gc.setBackground(originalBackground);
        gc.setForeground(originalForeground);
        gc.setFont(originalFont);
    }

    @Override
    public int getPreferredWidth(ILayerCell cell, GC gc, IConfigRegistry configRegistry) {
        return 0;
    }

    @Override
    public int getPreferredHeight(ILayerCell cell, GC gc, IConfigRegistry configRegistry) {
        return getPreferredHeight();
    }

    public int getPreferredHeight() {
        return 30;
    }

    public int getGroupByColumnIndexAtXY(int x, int y) {
        for (int i = 0; i < this.groupByCellBounds.size(); i++) {
            Rectangle bounds = this.groupByCellBounds.get(i);
            if (bounds.contains(x, y)) {
                return this.groupByModel.getGroupByColumnIndexes().get(i);
            }
        }
        return -1;
    }

}
