/*******************************************************************************
 * Copyright (c) 2009, 2019 Ericsson.
 *
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License 2.0 which
 * accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *   Alvaro Sanchez-Leon - Initial API and implementation
 *   Patrick Tasse - Refactoring
 *******************************************************************************/

package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseTrackListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.ColorDialog;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Scale;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.tracecompass.internal.tmf.ui.Activator;
import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants;
import org.eclipse.tracecompass.internal.tmf.ui.Messages;
import org.eclipse.tracecompass.internal.tmf.ui.util.TimeGraphStyleUtil;
import org.eclipse.tracecompass.tmf.core.model.StyleProperties;
import org.eclipse.tracecompass.tmf.ui.colors.ColorUtils;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.StateItem;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEventStyleStrings;

import com.google.common.collect.Collections2;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;

/**
 * Legend for the colors used in the time graph view
 *
 * @version 1.0
 * @author Alvaro Sanchez-Leon
 * @author Patrick Tasse
 */
public class TimeGraphLegend extends TitleAreaDialog {

    private static final ImageDescriptor RESET_IMAGE = Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_RESET_BUTTON);
    private final ITimeGraphPresentationProvider fProvider;
    private final LocalResourceManager fResourceManager = new LocalResourceManager(JFaceResources.getResources());
    private Composite fInnerComposite;

    /**
     * Open the time graph legend window
     *
     * @param parent
     *            The parent shell
     * @param provider
     *            The presentation provider
     */
    public static void open(Shell parent, ITimeGraphPresentationProvider provider) {
        (new TimeGraphLegend(parent, provider)).open();
    }

    /**
     * Standard constructor
     *
     * @param parent
     *            The parent shell
     * @param provider
     *            The presentation provider
     */
    public TimeGraphLegend(Shell parent, ITimeGraphPresentationProvider provider) {
        super(parent);
        fProvider = provider;
        this.setShellStyle(getShellStyle() | SWT.RESIZE);
    }

    /**
     * Gets the Presentation Provider
     *
     * @return the presentation provider
     * @since 3.3
     */
    protected final ITimeGraphPresentationProvider getPresentationProvider() {
        return fProvider;
    }

    @Override
    protected Control createDialogArea(Composite parent) {
        Composite composite = (Composite) super.createDialogArea(parent);

        addStateGroups(composite);

        setTitle(Messages.TmfTimeLegend_LEGEND);
        setDialogHelpAvailable(false);
        setHelpAvailable(false);

        // Set the minimum size to avoid 0-sized legends from user resize
        parent.getShell().setMinimumSize(150, 150);

        composite.addDisposeListener((e) -> {
            fResourceManager.dispose();
        });
        return composite;
    }

    @Override
    protected Point getInitialSize() {
        Point initialSize = super.getInitialSize();
        Composite innerComposite = fInnerComposite;
        /*
         * If shell initial size is taller than available area, use 2 columns.
         */
        if (initialSize.y > Display.getDefault().getClientArea().height && innerComposite != null) {
            // Needed to make sure resize listener gets the right shell size
            getShell().layout();
            getGridLayouts(innerComposite).forEach(gl -> gl.numColumns = 2);
            initialSize = super.getInitialSize();
            // Needed to make sure vertical scroll bar appears
            Display.getDefault().asyncExec(() -> innerComposite.getParent().layout());
        }
        return initialSize;
    }

    /**
     * Creates a states group
     *
     * @param composite
     *            the parent composite
     * @since 3.3
     */
    private void addStateGroups(Composite composite) {

        StateItem[] stateTable = fProvider.getStateTable();
        if (stateTable == null) {
            return;
        }
        List<StateItem> stateItems = Arrays.asList(stateTable);
        Collection<StateItem> linkStates = Collections2.filter(stateItems, TimeGraphLegend::isLinkState);

        ScrolledComposite sc = new ScrolledComposite(composite, SWT.V_SCROLL | SWT.H_SCROLL);
        sc.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        sc.setExpandHorizontal(true);
        sc.setExpandVertical(true);
        sc.setLayout(GridLayoutFactory.swtDefaults().margins(200, 0).create());

        Composite innerComposite = new Composite(sc, SWT.NONE);
        fInnerComposite = innerComposite;
        GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
        innerComposite.setLayoutData(gd);
        innerComposite.setLayout(new GridLayout());
        innerComposite.addControlListener(new ControlAdapter() {
            @Override
            public void controlResized(ControlEvent e) {
                /*
                 * Find the highest number of columns that fits in the new width
                 */
                Point size = innerComposite.getSize();
                List<GridLayout> gridLayouts = getGridLayouts(innerComposite);
                Point minSize = new Point(0, 0);
                for (int columns = 8; columns > 0; columns--) {
                    final int numColumns = columns;
                    gridLayouts.forEach(gl -> gl.numColumns = numColumns);
                    minSize = innerComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT);
                    if (minSize.x <= size.x) {
                        break;
                    }
                }
                sc.setMinSize(0, minSize.y);
            }
        });

        sc.setContent(innerComposite);

        createStatesGroup(innerComposite);
        createLinkGroup(linkStates, innerComposite);

        sc.setMinSize(0, innerComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
    }

    /**
     * Creates a states group
     *
     * @param composite
     *            the parent composite
     * @since 3.3
     */
    protected void createStatesGroup(Composite composite) {
        String stateTypeName = fProvider.getStateTypeName();
        StringBuilder buffer = new StringBuilder();
        if (!stateTypeName.isEmpty()) {
            buffer.append(stateTypeName);
            buffer.append(" "); //$NON-NLS-1$
        }
        buffer.append(Messages.TmfTimeLegend_StateTypeName);

        StateItem[] stateTable = fProvider.getStateTable();
        List<StateItem> stateItems = stateTable != null ? Arrays.asList(stateTable) : Collections.emptyList();
        Multimap<String, StateItem> groupedStateItems = LinkedHashMultimap.create();
        for (StateItem stateItem : stateItems) {
            if (!isLinkState(stateItem)) {
                Object group = stateItem.getStyleMap().get(StyleProperties.STYLE_GROUP);
                if (group instanceof String) {
                    groupedStateItems.put((String) group, stateItem);
                } else {
                    groupedStateItems.put(buffer.toString(), stateItem);
                }
            }
        }

        for (String groupName : groupedStateItems.keySet()) {
            Collection<StateItem> groupItems = groupedStateItems.get(groupName);
            createGroup(composite, groupName, groupItems);
        }
    }

    private static List<GridLayout> getGridLayouts(Composite innerComposite) {
        List<GridLayout> gridLayouts = new ArrayList<>();
        if (innerComposite == null) {
            return gridLayouts;
        }
        Arrays.asList(innerComposite.getChildren()).forEach(control -> {
            if (control instanceof Composite) {
                Layout layout = ((Composite) control).getLayout();
                if (layout instanceof GridLayout) {
                    gridLayouts.add((GridLayout) layout);
                }
            }
        });
        return gridLayouts;
    }
    private void createLinkGroup(Collection<StateItem> linkStates, Composite composite) {
        if (linkStates.isEmpty()) {
            return;
        }
        createGroup(composite, fProvider.getLinkTypeName(), linkStates);
    }

    private void createGroup(Composite parent, String name, Collection<StateItem> stateItems) {
        Group group = new Group(parent, SWT.NONE);
        group.setText(name);
        group.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false));
        GridLayout layout = new GridLayout(1, true);
        layout.marginWidth = 10;
        layout.marginBottom = 10;
        group.setLayout(layout);

        for (StateItem stateItem : stateItems) {
            new LegendEntry(group, stateItem);
        }
    }

    /**
     * Test whether a state item is a link state or not
     *
     * @param si
     *            The state item
     * @return True if the state item is a link state, false otherwise
     * @since 4.0
     */
    protected static boolean isLinkState(StateItem si) {
        Object itemType = si.getStyleMap().getOrDefault(ITimeEventStyleStrings.itemTypeProperty(), ITimeEventStyleStrings.stateType());
        return itemType instanceof String && ((String) itemType).equals(ITimeEventStyleStrings.linkType());
    }

    @Override
    protected void configureShell(Shell shell) {
        super.configureShell(shell);
        shell.setText(Messages.TmfTimeLegend_LEGEND);
    }

    @Override
    protected void createButtonsForButtonBar(Composite parent) {
        createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
                true);
    }

    /**
     * Widget for a legend entry has a color chooser, a label, a width and a reset
     * button
     *
     * @author Matthew Khouzam
     * @since 3.3
     */
    protected class LegendEntry extends Composite {
        /**
         * ID to identify a control as part of a given entry
         */
        private static final String LEGEND_ENTRY_KEY = "legend.entry.key"; //$NON-NLS-1$
        private final Swatch fBar;
        private final Scale fScale;
        private final Button fReset;

        /**
         * Constructor
         *
         * @param parent
         *            parent composite
         * @param si
         *            the state item
         */
        public LegendEntry(Composite parent, StateItem si) {
            super(parent, SWT.NONE);
            String fillColorKey = TimeGraphStyleUtil.getPreferenceName(fProvider, si, StyleProperties.BACKGROUND_COLOR);
            String heightFactorKey = TimeGraphStyleUtil.getPreferenceName(fProvider, si, StyleProperties.HEIGHT);
            IPreferenceStore store = TimeGraphStyleUtil.getStore();
            TimeGraphStyleUtil.loadValue(fProvider, si);
            String name = si.getStateString();
            setLayout(GridLayoutFactory.swtDefaults().numColumns(4).create());
            fBar = new Swatch(this, si.getStateColor());
            fBar.setData(LEGEND_ENTRY_KEY, name);
            fBar.setToolTipText(Messages.TimeGraphLegend_swatchClick);
            fBar.addMouseListener(new MouseAdapter() {

                @Override
                public void mouseUp(MouseEvent e) {
                    Shell shell = new Shell();
                    ColorDialog cd = new ColorDialog(shell, SWT.NONE);
                    cd.setRGB(fBar.fColor.getRGB());
                    RGB color = cd.open();
                    if (color != null) {
                        store.setValue(fillColorKey, ColorUtils.toHexColor(color.red, color.green, color.blue));
                        fBar.setColor(color);
                        si.setStateColor(color);
                        fProvider.refresh();
                        fReset.setEnabled(true);
                    }
                }
            });
            fBar.addMouseTrackListener(new MouseTrackListener() {

                @Override
                public void mouseHover(MouseEvent e) {
                    // Do nothing
                }

                @Override
                public void mouseExit(MouseEvent e) {
                    Shell shell = parent.getShell();
                    Cursor old = shell.getCursor();
                    shell.setCursor(new Cursor(e.display, SWT.CURSOR_ARROW));
                    if (old != null) {
                        old.dispose();
                    }
                }

                @Override
                public void mouseEnter(MouseEvent e) {
                    Shell shell = parent.getShell();
                    Cursor old = shell.getCursor();
                    shell.setCursor(new Cursor(e.display, SWT.CURSOR_HAND));
                    if (old != null) {
                        old.dispose();
                    }
                }
            });

            fBar.setLayoutData(GridDataFactory.swtDefaults().hint(30, 20).create());
            CLabel label = new CLabel(this, SWT.NONE) {
                @Override
                protected String shortenText(GC gc, String t, int w) {
                    String text = super.shortenText(gc, t, w);
                    setToolTipText(t.equals(text) ? null : t);
                    return text;
                }
            };
            label.setData(LEGEND_ENTRY_KEY, name);
            label.setText(name);
            label.setLayoutData(GridDataFactory.fillDefaults().hint(160, SWT.DEFAULT).align(SWT.FILL, SWT.CENTER).grab(true, false).create());
            fScale = new Scale(this, SWT.NONE);
            fScale.setMaximum(100);
            fScale.setMinimum(1);
            fScale.setSelection((int) (100 * si.getStateHeightFactor()));
            fScale.setToolTipText(Messages.TimeGraphLegend_widthTooltip);
            fScale.setData(LEGEND_ENTRY_KEY, name);
            fScale.addSelectionListener(new SelectionListener() {

                @Override
                public void widgetSelected(SelectionEvent e) {
                    float newWidth = fScale.getSelection() * 0.01f;
                    store.setValue(heightFactorKey, newWidth);
                    si.getStyleMap().put(StyleProperties.HEIGHT, newWidth);
                    fProvider.refresh();
                    fReset.setEnabled(true);
                }

                @Override
                public void widgetDefaultSelected(SelectionEvent e) {
                    // do nothing
                }
            });
            fScale.setLayoutData(GridDataFactory.swtDefaults().hint(120, SWT.DEFAULT).create());
            fReset = new Button(this, SWT.FLAT);
            fReset.setData(LEGEND_ENTRY_KEY, name);
            fReset.addSelectionListener(new SelectionListener() {

                @Override
                public void widgetSelected(SelectionEvent e) {
                    si.reset();
                    store.setToDefault(heightFactorKey);
                    store.setToDefault(fillColorKey);
                    fBar.setColor(si.getStateColor());
                    fScale.setSelection((int) (100 * si.getStateHeightFactor()));
                    fProvider.refresh();
                    fReset.setEnabled(false);
                }

                @Override
                public void widgetDefaultSelected(SelectionEvent e) {
                    // do nothing
                }
            });
            fReset.setToolTipText(Messages.TimeGraphLegend_resetTooltip);
            fReset.setImage(RESET_IMAGE.createImage());
            fReset.setLayoutData(GridDataFactory.swtDefaults().align(SWT.END, SWT.CENTER).create());
            if (store.getString(fillColorKey).equals(store.getDefaultString(fillColorKey)) &&
                    store.getFloat(heightFactorKey) == store.getDefaultFloat(heightFactorKey)) {
                fReset.setEnabled(false);
            }
        }

        @Override
        public void dispose() {
            fReset.getImage().dispose();
            super.dispose();
        }
    }

    private class Swatch extends Canvas {
        private Color fColor;

        public Swatch(Composite parent, RGB rgb) {
            super(parent, SWT.FLAT);

            fColor = fResourceManager.createColor(rgb);
            setForeground(fColor);
            addListener(SWT.Paint, event -> draw(event.gc));
        }

        public void setColor(RGB rgb) {
            if (rgb != null) {
                fColor = fResourceManager.createColor(rgb);
                setForeground(fColor);
                redraw();
            }
        }

        private void draw(GC gc) {
            Rectangle r = getClientArea();
            gc.setBackground(fColor);
            gc.fillRectangle(r);
            gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
            gc.setLineWidth(2);
            gc.drawRectangle(1, 1, r.width - 2, r.height - 2);
        }
    }
}
