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

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
import org.eclipse.nebula.widgets.nattable.data.ListDataProvider;
import org.eclipse.nebula.widgets.nattable.data.convert.DefaultBooleanDisplayConverter;
import org.eclipse.nebula.widgets.nattable.data.convert.DefaultDateDisplayConverter;
import org.eclipse.nebula.widgets.nattable.dataset.person.Person;
import org.eclipse.nebula.widgets.nattable.dataset.person.Person.Gender;
import org.eclipse.nebula.widgets.nattable.dataset.person.PersonService;
import org.eclipse.nebula.widgets.nattable.examples.AbstractNatExample;
import org.eclipse.nebula.widgets.nattable.examples.runner.StandaloneNatExampleRunner;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultBodyDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultColumnHeaderDataLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultRowHeaderDataLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer;
import org.eclipse.nebula.widgets.nattable.hover.HoverLayer;
import org.eclipse.nebula.widgets.nattable.hover.config.ColumnHeaderHoverLayerConfiguration;
import org.eclipse.nebula.widgets.nattable.hover.config.RowHeaderHoverLayerConfiguration;
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
import org.eclipse.nebula.widgets.nattable.layer.LabelStack;
import org.eclipse.nebula.widgets.nattable.layer.cell.AggregateConfigLabelAccumulator;
import org.eclipse.nebula.widgets.nattable.layer.cell.ColumnLabelAccumulator;
import org.eclipse.nebula.widgets.nattable.layer.cell.IConfigLabelAccumulator;
import org.eclipse.nebula.widgets.nattable.painter.NatTableBorderOverlayPainter;
import org.eclipse.nebula.widgets.nattable.painter.cell.BackgroundImagePainter;
import org.eclipse.nebula.widgets.nattable.painter.cell.CheckBoxPainter;
import org.eclipse.nebula.widgets.nattable.painter.cell.ICellPainter;
import org.eclipse.nebula.widgets.nattable.painter.cell.TextPainter;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
import org.eclipse.nebula.widgets.nattable.style.CellStyleAttributes;
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
import org.eclipse.nebula.widgets.nattable.style.IStyle;
import org.eclipse.nebula.widgets.nattable.style.Style;
import org.eclipse.nebula.widgets.nattable.style.theme.DarkNatTableThemeConfiguration;
import org.eclipse.nebula.widgets.nattable.style.theme.DefaultNatTableThemeConfiguration;
import org.eclipse.nebula.widgets.nattable.style.theme.IThemeExtension;
import org.eclipse.nebula.widgets.nattable.style.theme.ModernNatTableThemeConfiguration;
import org.eclipse.nebula.widgets.nattable.style.theme.ThemeConfiguration;
import org.eclipse.nebula.widgets.nattable.util.GUIHelper;
import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;

/**
 * Example showing how to use {@link ThemeConfiguration}s in a NatTable. It
 * shows how to set and how to switch themes at runtime. Note that there are
 * several things that are not controllable via themes like row height, column
 * width or ILayerPainter. The later are tight connected to the ILayer
 * themselves.
 */
public class _423_ThemeStylingExample extends AbstractNatExample {

    public static final String FEMALE_LABEL = "FemaleLabel";
    public static final String MALE_LABEL = "MaleLabel";

    public static void main(String[] args) throws Exception {
        StandaloneNatExampleRunner.run(650, 400, new _423_ThemeStylingExample());
    }

    @Override
    public String getDescription() {
        return "This example shows the usage of themes for styling a NatTable and how"
                + " to switch themes at runtime.  It also shows how to deal with attributes"
                + " that are not configurable via themes like row heights, column widths and"
                + " ILayerPainter.";
    }

    @Override
    public Control createExampleControl(Composite parent) {
        Composite container = new Composite(parent, SWT.NONE);
        container.setLayout(new GridLayout());

        // property names of the Person class
        String[] propertyNames = { "firstName", "lastName", "gender", "married", "birthday" };

        // mapping from property to label, needed for column header labels
        Map<String, String> propertyToLabelMap = new HashMap<>();
        propertyToLabelMap.put("firstName", "Firstname");
        propertyToLabelMap.put("lastName", "Lastname");
        propertyToLabelMap.put("gender", "Gender");
        propertyToLabelMap.put("married", "Married");
        propertyToLabelMap.put("birthday", "Birthday");

        // build the body layer stack
        // Usually you would create a new layer stack by extending
        // AbstractIndexLayerTransform and setting the ViewportLayer
        // as underlying layer. But in this case using the ViewportLayer
        // directly as body layer is also working.
        final ListDataProvider<Person> bodyDataProvider =
                new DefaultBodyDataProvider<>(PersonService.getPersons(10), propertyNames);
        final DataLayer bodyDataLayer = new DataLayer(bodyDataProvider);
        HoverLayer bodyHoverLayer = new HoverLayer(bodyDataLayer);
        SelectionLayer selectionLayer = new SelectionLayer(bodyHoverLayer);
        ViewportLayer viewportLayer = new ViewportLayer(selectionLayer);

        // add labels to provider conditional styling
        AggregateConfigLabelAccumulator labelAccumulator = new AggregateConfigLabelAccumulator();
        labelAccumulator.add(new ColumnLabelAccumulator());
        labelAccumulator.add(new IConfigLabelAccumulator() {
            @Override
            public void accumulateConfigLabels(
                    LabelStack configLabels, int columnPosition, int rowPosition) {
                Person p = bodyDataProvider.getRowObject(rowPosition);
                if (p != null) {
                    configLabels.addLabel(p.getGender().equals(Gender.FEMALE) ? FEMALE_LABEL : MALE_LABEL);
                }
            }
        });

        bodyDataLayer.setConfigLabelAccumulator(labelAccumulator);

        // build the column header layer
        IDataProvider columnHeaderDataProvider =
                new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap);
        final DataLayer columnHeaderDataLayer =
                new DefaultColumnHeaderDataLayer(columnHeaderDataProvider);
        HoverLayer columnHoverLayer =
                new HoverLayer(columnHeaderDataLayer, false);
        final ColumnHeaderLayer columnHeaderLayer =
                new ColumnHeaderLayer(columnHoverLayer, viewportLayer, selectionLayer, false);

        // add ColumnHeaderHoverLayerConfiguration to ensure that hover styling
        // and resizing is working together
        columnHeaderLayer.addConfiguration(
                new ColumnHeaderHoverLayerConfiguration(columnHoverLayer));

        // build the row header layer
        IDataProvider rowHeaderDataProvider =
                new DefaultRowHeaderDataProvider(bodyDataProvider);
        DataLayer rowHeaderDataLayer =
                new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
        HoverLayer rowHoverLayer =
                new HoverLayer(rowHeaderDataLayer, false);
        RowHeaderLayer rowHeaderLayer =
                new RowHeaderLayer(rowHoverLayer, viewportLayer, selectionLayer, false);

        // add RowHeaderHoverLayerConfiguration to ensure that hover styling and
        // resizing is working together
        rowHeaderLayer.addConfiguration(
                new RowHeaderHoverLayerConfiguration(rowHoverLayer));

        // build the corner layer
        IDataProvider cornerDataProvider =
                new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider);
        DataLayer cornerDataLayer =
                new DataLayer(cornerDataProvider);
        final CornerLayer cornerLayer =
                new CornerLayer(cornerDataLayer, rowHeaderLayer, columnHeaderLayer);

        // build the grid layer
        final GridLayer gridLayer = new GridLayer(
                viewportLayer, columnHeaderLayer, rowHeaderLayer, cornerLayer);

        final NatTable natTable = new NatTable(container, gridLayer);
        GridDataFactory.fillDefaults().grab(true, true).applyTo(natTable);

        // adding a full border
        natTable.addOverlayPainter(new NatTableBorderOverlayPainter(natTable.getConfigRegistry()));

        Composite buttonPanel = new Composite(container, SWT.NONE);
        buttonPanel.setLayout(new GridLayout(3, true));
        GridDataFactory.fillDefaults().grab(true, false).applyTo(buttonPanel);

        final ThemeConfiguration defaultTheme = new DefaultNatTableThemeConfiguration();
        final ThemeConfiguration modernTheme = new ModernNatTableThemeConfiguration();
        final ThemeConfiguration darkTheme = new DarkNatTableThemeConfiguration();

        final ThemeConfiguration conditionalDefaultTheme = new DefaultNatTableThemeConfiguration();
        conditionalDefaultTheme.addThemeExtension(new ConditionalStylingThemeExtension());
        final ThemeConfiguration conditionalModernTheme = new ModernNatTableThemeConfiguration();
        conditionalModernTheme.addThemeExtension(new ConditionalStylingThemeExtension());
        final ThemeConfiguration conditionalDarkTheme = new DarkNatTableThemeConfiguration();
        conditionalDarkTheme.addThemeExtension(new ConditionalStylingThemeExtension());

        final ThemeConfiguration hoverTheme = new HoverThemeConfiguration();
        final ThemeConfiguration fontTheme = new FontStylingThemeConfiguration();

        Button defaultThemeButton = new Button(buttonPanel, SWT.PUSH);
        defaultThemeButton.setText("NatTable Default Theme");
        defaultThemeButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                natTable.setTheme(defaultTheme);

                // reset to default state
                cleanupNonThemeSettings(gridLayer, bodyDataLayer, columnHeaderDataLayer);
            }
        });

        Button modernThemeButton = new Button(buttonPanel, SWT.PUSH);
        modernThemeButton.setText("NatTable Modern Theme");
        modernThemeButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                natTable.setTheme(modernTheme);

                // reset to default state
                cleanupNonThemeSettings(gridLayer, bodyDataLayer, columnHeaderDataLayer);
            }
        });

        Button darkThemeButton = new Button(buttonPanel, SWT.PUSH);
        darkThemeButton.setText("NatTable Dark Theme");
        darkThemeButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                natTable.setTheme(darkTheme);

                // reset to default state
                cleanupNonThemeSettings(gridLayer, bodyDataLayer, columnHeaderDataLayer);
            }
        });

        Button conditionalThemeButton = new Button(buttonPanel, SWT.PUSH);
        conditionalThemeButton.setText("Conditional Default Theme");
        conditionalThemeButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                natTable.setTheme(conditionalDefaultTheme);

                // reset to default state
                cleanupNonThemeSettings(gridLayer, bodyDataLayer, columnHeaderDataLayer);
            }
        });

        Button conditionalModernThemeButton = new Button(buttonPanel, SWT.PUSH);
        conditionalModernThemeButton.setText("Conditional Modern Theme");
        conditionalModernThemeButton
                .addSelectionListener(new SelectionAdapter() {
                    @Override
                    public void widgetSelected(SelectionEvent e) {
                        natTable.setTheme(conditionalModernTheme);

                        // reset to default state
                        cleanupNonThemeSettings(gridLayer, bodyDataLayer, columnHeaderDataLayer);
                    }
                });

        Button conditionalDarkThemeButton = new Button(buttonPanel, SWT.PUSH);
        conditionalDarkThemeButton.setText("Conditional Dark Theme");
        conditionalDarkThemeButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                natTable.setTheme(conditionalDarkTheme);

                // reset to default state
                cleanupNonThemeSettings(gridLayer, bodyDataLayer, columnHeaderDataLayer);
            }
        });

        Button hoverThemeButton = new Button(buttonPanel, SWT.PUSH);
        hoverThemeButton.setText("Hover Theme");
        hoverThemeButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                natTable.setTheme(hoverTheme);

                // reset to default state
                cleanupNonThemeSettings(gridLayer, bodyDataLayer, columnHeaderDataLayer);
            }
        });

        Button fontThemeButton = new Button(buttonPanel, SWT.PUSH);
        fontThemeButton.setText("Increased Font Theme");
        fontThemeButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                natTable.setTheme(fontTheme);

                // we are simply increasing the default width and height in this
                // example we could also register TextPainters that calculate
                // their height by content but they are not able to shrink again
                columnHeaderDataLayer.setDefaultRowHeight(30);
                columnHeaderDataLayer.setDefaultColumnWidth(130);
                bodyDataLayer.setDefaultRowHeight(30);
                bodyDataLayer.setDefaultColumnWidth(130);
            }
        });

        return container;
    }

    /**
     * Resets row heights and column widths to default settings.
     */
    private void cleanupNonThemeSettings(GridLayer gridLayer,
            DataLayer bodyDataLayer, DataLayer columnHeaderDataLayer) {

        columnHeaderDataLayer.setDefaultRowHeight(20);
        columnHeaderDataLayer.setDefaultColumnWidth(100);
        bodyDataLayer.setDefaultRowHeight(20);
        bodyDataLayer.setDefaultColumnWidth(100);
    }

    /**
     * ThemeConfiguration that adds hover styling. Note that the stylings are
     * only interpreted because the HoverLayer is involved in the layer stacks.
     */
    class HoverThemeConfiguration extends DefaultNatTableThemeConfiguration {
        {
            this.bodyHoverBgColor = GUIHelper.COLOR_YELLOW;
            this.bodyHoverSelectionBgColor = GUIHelper.COLOR_GREEN;

            this.rHeaderHoverBgColor = GUIHelper.COLOR_RED;
            this.rHeaderHoverSelectionBgColor = GUIHelper.COLOR_BLUE;

            Image bgImage = GUIHelper.getImageByURL("columnHeaderBg",
                    getClass().getResource("/org/eclipse/nebula/widgets/nattable/examples/resources/column_header_bg.png"));

            Image hoverBgImage = GUIHelper.getImageByURL("hoverColumnHeaderBg",
                    getClass().getResource("/org/eclipse/nebula/widgets/nattable/examples/resources/hovered_column_header_bg.png"));

            Image selectedBgImage = GUIHelper.getImageByURL("selectedColumnHeaderBg",
                    getClass().getResource("/org/eclipse/nebula/widgets/nattable/examples/resources/selected_column_header_bg.png"));

            Image selectedHoveredBgImage = GUIHelper.getImageByURL("selectedHoverColumnHeaderBg",
                    getClass().getResource("/org/eclipse/nebula/widgets/nattable/examples/resources/selected_hovered_column_header_bg.png"));

            TextPainter txtPainter = new TextPainter(false, false);

            ICellPainter bgImagePainter =
                    new BackgroundImagePainter(txtPainter, bgImage);

            this.cHeaderCellPainter = bgImagePainter;
            this.cornerCellPainter = bgImagePainter;

            this.cHeaderSelectionCellPainter =
                    new BackgroundImagePainter(txtPainter, selectedBgImage);
            this.cHeaderHoverCellPainter =
                    new BackgroundImagePainter(txtPainter, hoverBgImage);
            this.cHeaderHoverSelectionCellPainter =
                    new BackgroundImagePainter(txtPainter, selectedHoveredBgImage);

            this.renderCornerGridLines = true;
            this.renderColumnHeaderGridLines = true;
        }
    }

    /**
     * IThemeExtension that adds conditional styling. As it is implemented as
     * theme extension, it can be added to any ThemeConfiguration without the
     * need for inheritance.
     */
    class ConditionalStylingThemeExtension implements IThemeExtension {

        @Override
        public void registerStyles(IConfigRegistry configRegistry) {
            // add custom styling
            IStyle femaleStyle = new Style();
            femaleStyle.setAttributeValue(
                    CellStyleAttributes.BACKGROUND_COLOR,
                    GUIHelper.COLOR_YELLOW);
            femaleStyle.setAttributeValue(
                    CellStyleAttributes.FOREGROUND_COLOR,
                    GUIHelper.COLOR_BLACK);
            configRegistry.registerConfigAttribute(
                    CellConfigAttributes.CELL_STYLE,
                    femaleStyle,
                    DisplayMode.NORMAL, FEMALE_LABEL);

            // add custom painter
            configRegistry.registerConfigAttribute(
                    CellConfigAttributes.CELL_PAINTER,
                    new CheckBoxPainter(),
                    DisplayMode.NORMAL,
                    ColumnLabelAccumulator.COLUMN_LABEL_PREFIX + "3");

            // add custom converter
            configRegistry.registerConfigAttribute(
                    CellConfigAttributes.DISPLAY_CONVERTER,
                    new DefaultBooleanDisplayConverter(),
                    DisplayMode.NORMAL,
                    ColumnLabelAccumulator.COLUMN_LABEL_PREFIX + "3");

            DateFormat formatter = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.getDefault());
            String pattern = ((SimpleDateFormat) formatter).toPattern();

            configRegistry.registerConfigAttribute(
                    CellConfigAttributes.DISPLAY_CONVERTER,
                    new DefaultDateDisplayConverter(pattern),
                    DisplayMode.NORMAL,
                    ColumnLabelAccumulator.COLUMN_LABEL_PREFIX + "4");
        }

        @Override
        public void unregisterStyles(IConfigRegistry configRegistry) {
            // unregister custom styling
            configRegistry.unregisterConfigAttribute(
                    CellConfigAttributes.CELL_STYLE,
                    DisplayMode.NORMAL,
                    FEMALE_LABEL);

            configRegistry.unregisterConfigAttribute(
                    CellConfigAttributes.CELL_PAINTER,
                    DisplayMode.NORMAL,
                    ColumnLabelAccumulator.COLUMN_LABEL_PREFIX + "3");

            configRegistry.unregisterConfigAttribute(
                    CellConfigAttributes.DISPLAY_CONVERTER,
                    DisplayMode.NORMAL,
                    ColumnLabelAccumulator.COLUMN_LABEL_PREFIX + "3");

            configRegistry.unregisterConfigAttribute(
                    CellConfigAttributes.DISPLAY_CONVERTER,
                    DisplayMode.NORMAL,
                    ColumnLabelAccumulator.COLUMN_LABEL_PREFIX + "4");
        }

    }

    /**
     * ThemeConfiguration that sets different fonts which has impact on the row
     * heights and columns widths. The automatic resizing is done via specially
     * configured TextPainter instances.
     */
    class FontStylingThemeConfiguration extends ModernNatTableThemeConfiguration {
        {
            this.defaultFont = GUIHelper.getFont(new FontData("Arial", 15, SWT.NORMAL));
            this.defaultSelectionFont = GUIHelper.getFont(new FontData("Arial", 15, SWT.NORMAL));

            this.cHeaderFont = GUIHelper.getFont(new FontData("Arial", 18, SWT.NORMAL));
            this.cHeaderSelectionFont = GUIHelper.getFont(new FontData("Arial", 18, SWT.NORMAL));

            this.rHeaderFont = GUIHelper.getFont(new FontData("Arial", 18, SWT.NORMAL));
            this.rHeaderSelectionFont = GUIHelper.getFont(new FontData("Arial", 18, SWT.NORMAL));

            this.renderCornerGridLines = true;
            this.renderColumnHeaderGridLines = true;
        }
    }
}
