/*******************************************************************************
 * Copyright (c) 2011, 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:
 *   Francois Chouinard - Initial API and implementation
 *   Bernd Hufmann - Changed to updated histogram data model
 *   Francois Chouinard - Reformat histogram labels on format change
 *   Patrick Tasse - Support selection range
 *   Xavier Raynaud - Support multi-trace coloring
 *******************************************************************************/

package org.eclipse.tracecompass.tmf.ui.views.histogram;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseTrackListener;
import org.eclipse.swt.events.MouseWheelListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.tracecompass.internal.tmf.ui.views.histogram.HistogramTimeAdapter;
import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
import org.eclipse.tracecompass.tmf.core.signal.TmfTimestampFormatUpdateSignal;
import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimePreferencesConstants;
import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimePreferences;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampDelta;
import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentSignal;
import org.eclipse.tracecompass.tmf.ui.viewers.TmfAbstractToolTipHandler;
import org.eclipse.tracecompass.tmf.ui.views.FormatTimeUtils;
import org.eclipse.tracecompass.tmf.ui.views.FormatTimeUtils.Resolution;
import org.eclipse.tracecompass.tmf.ui.views.FormatTimeUtils.TimeFormat;
import org.eclipse.tracecompass.tmf.ui.views.ITmfTimeAligned;
import org.eclipse.tracecompass.tmf.ui.views.TmfView;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.ITimeDataProvider;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphColorScheme;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphScale;

/**
 * Re-usable histogram widget.
 *
 * It has the following features:
 * <ul>
 * <li>Y-axis labels displaying min/max count values
 * <li>X-axis labels displaying time range
 * <li>a histogram displaying the distribution of values over time (note that
 * the histogram might not necessarily fill the whole canvas)
 * </ul>
 * The widget also has 1 'marker' to identify:
 * <ul>
 * <li>a blue dashed line over the bar that contains the currently selected event
 * </ul>
 * Clicking on the histogram will select the current event at the mouse
 * location.
 * <p>
 * Once the histogram is selected, there is some limited keyboard support:
 * <ul>
 * <li>Home: go to the first histogram bar
 * <li>End: go to the last histogram bar
 * <li>Left: go to the previous histogram
 * <li>Right: go to the next histogram bar
 * </ul>
 * Finally, when the mouse hovers over the histogram, a tool tip showing the
 * following information about the corresponding histogram bar time range:
 * <ul>
 * <li>start of the time range
 * <li>end of the time range
 * <li>number of events in that time range
 * </ul>
 *
 * @version 1.1
 * @author Francois Chouinard
 */
public abstract class Histogram implements ControlListener, PaintListener, KeyListener, MouseListener, MouseMoveListener, MouseTrackListener, IHistogramModelListener {

    // ------------------------------------------------------------------------
    // Constants
    // ------------------------------------------------------------------------

    private static final int TIME_SCALE_HEIGHT = 27;

    // Histogram colors

    // System colors, they do not need to be disposed
    private final Color fSelectionForegroundColor = Display.getCurrent().getSystemColor(SWT.COLOR_BLUE);
    private final Color fSelectionBackgroundColor = Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);

    // Application colors, they need to be disposed
    private final Color[] fHistoBarColors = new Color[] { new Color(Display.getDefault(), 90, 90, 255), // blue
            new Color(Display.getDefault(), 0, 240, 0), // green
            new Color(Display.getDefault(), 255, 0, 0), // red
            new Color(Display.getDefault(), 0, 255, 255), // cyan
            new Color(Display.getDefault(), 255, 80, 255), // magenta
            new Color(Display.getDefault(), 200, 200, 0), // yellow
            new Color(Display.getDefault(), 200, 150, 0), // brown
            new Color(Display.getDefault(), 150, 255, 150), // light green
            new Color(Display.getDefault(), 200, 80, 80), // dark red
            new Color(Display.getDefault(), 30, 150, 150), // dark cyan
            new Color(Display.getDefault(), 200, 200, 255), // light blue
            new Color(Display.getDefault(), 0, 120, 0), // dark green
            new Color(Display.getDefault(), 255, 150, 150), // lighter red
            new Color(Display.getDefault(), 140, 80, 140), // dark magenta
            new Color(Display.getDefault(), 150, 100, 50), // brown
            new Color(Display.getDefault(), 255, 80, 80), // light red
            new Color(Display.getDefault(), 200, 200, 200), // light grey
            new Color(Display.getDefault(), 255, 200, 80), // orange
            new Color(Display.getDefault(), 255, 255, 80), // pale yellow
            new Color(Display.getDefault(), 255, 200, 200), // pale red
            new Color(Display.getDefault(), 255, 200, 255), // pale magenta
            new Color(Display.getDefault(), 255, 255, 200), // pale pale yellow
            new Color(Display.getDefault(), 200, 255, 255), // pale pale blue
    };
    private final Color fTimeRangeColor = new Color(Display.getCurrent(), 255, 128, 0);
    private final Color fLostEventColor = new Color(Display.getCurrent(), 208, 62, 120);

    // Drag states
    /**
     * No drag in progress
     */
    protected static final int DRAG_NONE = 0;
    /**
     * Drag the selection
     */
    protected static final int DRAG_SELECTION = 1;
    /**
     * Drag the time range
     */
    protected static final int DRAG_RANGE = 2;
    /**
     * Drag the zoom range
     */
    protected static final int DRAG_ZOOM = 3;

    // ------------------------------------------------------------------------
    // Attributes
    // ------------------------------------------------------------------------

    /**
     * The parent TMF view.
     */
    protected TmfView fParentView;

    private Composite fComposite;
    private Font fFont;

    // Histogram text fields
    private Label fMaxNbEventsLabel;

    /**
     * Histogram drawing area
     */
    protected Canvas fCanvas;

    /**
     * The histogram data model.
     */
    protected final @NonNull HistogramDataModel fDataModel;

    /**
     * The histogram data model scaled to current resolution and screen width.
     */
    protected HistogramScaledData fScaledData;

    /**
     * The current event value
     */
    protected long fCurrentEventTime = 0L;

    /**
     * The current selection begin time
     */
    private long fSelectionBegin = 0L;

    /**
     * The current selection end time
     */
    private long fSelectionEnd = 0L;

    /**
     * The drag state
     *
     * @see #DRAG_NONE
     * @see #DRAG_SELECTION
     * @see #DRAG_RANGE
     * @see #DRAG_ZOOM
     */
    protected int fDragState = DRAG_NONE;

    /**
     * The button that started a mouse drag, or 0 if no drag in progress
     */
    protected int fDragButton = 0;

    /**
     * The bucket display offset
     */
    private int fOffset = 0;

    /**
     * show the traces or not
     */
    static boolean showTraces = true;


    private boolean fSendTimeAlignSignals = false;

    private IStatusLineManager fStatusLineManager;

    private TimeGraphScale fTimeLineScale;
    private TimeGraphColorScheme fColorScheme;
    private TmfAbstractToolTipHandler fToolTipHandler = new TmfAbstractToolTipHandler() {

        @Override
        protected void fill(Control control, MouseEvent event, Point pt) {
            if ((fDataModel.getNbEvents() != 0 || fDataModel.getStartTime() < fDataModel.getEndTime()) &&
                    fScaledData != null && event.x >= 0 && event.x - fOffset < fScaledData.fWidth) {
                fillTooltip(event.x - fOffset);
            }
            fCanvas.setToolTipText(null);
        }

        private void fillTooltip(final int index) {
            long startTime = fScaledData.getBucketStartTime(index);
            /*
             * negative values are possible if time values came into the model
             * in decreasing order
             */
            if (startTime < 0) {
                startTime = 0;
            }
            final long endTime = fScaledData.getBucketEndTime(index);
            final int nbEvents = (index >= 0) ? fScaledData.fData[index].getNbEvents() : 0;
            int selectionBeginBucket = Math.min(fScaledData.fSelectionBeginBucket, fScaledData.fSelectionEndBucket);
            int selectionEndBucket = Math.max(fScaledData.fSelectionBeginBucket, fScaledData.fSelectionEndBucket);
            if (selectionBeginBucket <= index && index <= selectionEndBucket && fSelectionBegin != fSelectionEnd) {
                long start = Math.abs(fSelectionEnd - fSelectionBegin);
                TmfTimestampDelta delta = new TmfTimestampDelta(start, ITmfTimestamp.NANOSECOND_SCALE);
                addItem(null, Messages.Histogram_selectionSpanToolTip, delta.toString());
            }
            addItem(null, ToolTipString.fromString(Messages.Histogram_bucketRangeToolTip),
                    ToolTipString.fromTimestamp(NLS.bind(Messages.Histogram_timeRange,
                            TmfTimestamp.fromNanos(startTime).toString(), TmfTimestamp.fromNanos(endTime).toString()), startTime));
            addItem(null, Messages.Histogram_eventCountToolTip, Long.toString(nbEvents));
            if (!HistogramScaledData.hideLostEvents) {
                final int nbLostEvents = (index >= 0) ? fScaledData.fLostEventsData[index] : 0;
                addItem(null, Messages.Histogram_lostEventCountToolTip, Long.toString(nbLostEvents));
            }
        }
    };

    // ------------------------------------------------------------------------
    // Construction
    // ------------------------------------------------------------------------

    /**
     * Constructor.
     *
     * @param view
     *            A reference to the parent TMF view.
     * @param parent
     *            A parent composite
     */
    public Histogram(final TmfView view, final Composite parent) {
        this(view, parent, false);
    }

    /**
     * Full constructor.
     *
     * @param view
     *            A reference to the parent TMF view.
     * @param parent
     *            A parent composite
     * @param sendTimeAlignSignals
     *            Flag to send time alignment signals or not
     * @since 1.0
     */
    public Histogram(final TmfView view, final Composite parent, final boolean sendTimeAlignSignals) {
        fParentView = view;
        fSendTimeAlignSignals = sendTimeAlignSignals;
        fColorScheme = new TimeGraphColorScheme();
        fDataModel = new HistogramDataModel();
        fDataModel.addHistogramListener(this);
        fComposite = createWidget(parent);
        clear();

        fCanvas.addControlListener(this);
        fCanvas.addPaintListener(this);
        fCanvas.addKeyListener(this);
        fCanvas.addMouseListener(this);
        fCanvas.addMouseTrackListener(this);
        fCanvas.addMouseMoveListener(this);
        fToolTipHandler.activateHoverHelp(fCanvas);
        TmfSignalManager.register(this);
    }

    /**
     * Dispose resources and unregisters listeners.
     */
    public void dispose() {
        TmfSignalManager.deregister(this);
        fLostEventColor.dispose();
        for (Color c : fHistoBarColors) {
            c.dispose();
        }
        fTimeRangeColor.dispose();
        fFont.dispose();
        fDataModel.removeHistogramListener(this);
        fDataModel.dispose();
    }

    private Composite createWidget(final Composite parent) {

        fFont = adjustFont(parent);

        // --------------------------------------------------------------------
        // Define the histogram
        // --------------------------------------------------------------------

        final Composite composite = new Composite(parent, SWT.FILL);
        composite.setLayout(GridLayoutFactory.fillDefaults().numColumns(2).create());

        // Use all the horizontal space
        composite.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());

        // Y-axis max event
        fMaxNbEventsLabel = new Label(composite, SWT.RIGHT);
        fMaxNbEventsLabel.setFont(fFont);
        fMaxNbEventsLabel.setText("0"); //$NON-NLS-1$
        fMaxNbEventsLabel.setLayoutData(GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.TOP).create());

        // Histogram itself
        Composite canvasComposite = new Composite(composite, SWT.BORDER);
        canvasComposite.setLayout(GridLayoutFactory.fillDefaults().spacing(0, 0).create());
        canvasComposite.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).span(1, 1).create());
        fCanvas = new Canvas(canvasComposite, SWT.DOUBLE_BUFFERED);
        fCanvas.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
        fCanvas.addDisposeListener(e -> {
            Object image = fCanvas.getData(IMAGE_KEY);
            if (image instanceof Image) {
                ((Image) image).dispose();
            }
        });

        fTimeLineScale = new TimeGraphScale(canvasComposite, fColorScheme, SWT.BOTTOM);
        fTimeLineScale.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create());
        fTimeLineScale.setHeight(TIME_SCALE_HEIGHT);
        fTimeLineScale.setTimeProvider(new HistogramTimeAdapter(fDataModel));

        updateTimeFormat();

        return composite;
    }

    private static Font adjustFont(final Composite composite) {
        // Reduce font size for a more pleasing rendering
        final int fontSizeAdjustment = -2;
        final Font font = composite.getFont();
        final FontData fontData = font.getFontData()[0];
        return new Font(font.getDevice(), fontData.getName(), fontData.getHeight() + fontSizeAdjustment, fontData.getStyle());
    }

    /**
     * Assign the status line manager
     *
     * @param statusLineManager
     *            The status line manager, or null to disable status line
     *            messages
     * @since 4.0
     */
    public void setStatusLineManager(IStatusLineManager statusLineManager) {
        if (fStatusLineManager != null && statusLineManager == null) {
            fStatusLineManager.setMessage(""); //$NON-NLS-1$
        }
        fStatusLineManager = statusLineManager;
    }

    // ------------------------------------------------------------------------
    // Accessors
    // ------------------------------------------------------------------------

    /**
     * Returns the start time (equal first bucket time)
     *
     * @return the start time.
     */
    public long getStartTime() {
        return fDataModel.getFirstBucketTime();
    }

    /**
     * Returns the end time.
     *
     * @return the end time.
     */
    public long getEndTime() {
        return fDataModel.getEndTime();
    }

    /**
     * Returns the time limit (end of last bucket)
     *
     * @return the time limit.
     */
    public long getTimeLimit() {
        return fDataModel.getTimeLimit();
    }

    /**
     * Returns a data model reference.
     *
     * @return data model.
     */
    public HistogramDataModel getDataModel() {
        return fDataModel;
    }

    /**
     * Set the max number events to be displayed
     *
     * @param maxNbEvents
     *            the maximum number of events
     */
    void setMaxNbEvents(long maxNbEvents) {
        fMaxNbEventsLabel.setText(Long.toString(maxNbEvents));
        fMaxNbEventsLabel.getParent().layout();
        fCanvas.redraw();
    }

    /**
     * Return <code>true</code> if the traces must be displayed in the
     * histogram, <code>false</code> otherwise.
     *
     * @return whether the traces should be displayed
     */
    public boolean showTraces() {
        return showTraces && fDataModel.getNbTraces() < getMaxNbTraces();
    }

    /**
     * Returns the maximum number of traces the histogram can display with
     * separate colors. If there is more traces, histogram will use only one
     * color to display them.
     *
     * @return the maximum number of traces the histogram can display.
     */
    public int getMaxNbTraces() {
        return fHistoBarColors.length;
    }

    /**
     * Returns the color used to display the trace at the given index.
     *
     * @param traceIndex
     *            a trace index
     * @return a {@link Color}
     */
    public Color getTraceColor(int traceIndex) {
        return fHistoBarColors[traceIndex % fHistoBarColors.length];
    }

    // ------------------------------------------------------------------------
    // Operations
    // ------------------------------------------------------------------------
    /**
     * Updates the time range.
     *
     * @param startTime
     *            A start time
     * @param endTime
     *            A end time.
     */
    public void updateTimeRange(long startTime, long endTime) {
        if (fDragState == DRAG_NONE) {
            ((HistogramView) fParentView).updateTimeRange(startTime, endTime);
        }
    }

    /**
     * Clear the histogram and reset the data
     */
    public void clear() {
        fDataModel.clear();
        if (fDragState == DRAG_SELECTION) {
            updateSelectionTime();
        }
        fDragState = DRAG_NONE;
        fDragButton = 0;
        synchronized (fDataModel) {
            fScaledData = null;
        }
    }

    /**
     * Sets the current selection time range and refresh the display
     *
     * @param beginTime
     *            The begin time of the current selection
     * @param endTime
     *            The end time of the current selection
     */
    public void setSelection(final long beginTime, final long endTime) {
        fSelectionBegin = (beginTime > 0) ? beginTime : 0;
        fSelectionEnd = (endTime > 0) ? endTime : 0;
        fDataModel.setSelectionNotifyListeners(beginTime, endTime);
    }

    /**
     * Computes the timestamp of the bucket at [offset]
     *
     * @param offset
     *            offset from the left on the histogram
     * @return the start timestamp of the corresponding bucket
     */
    public synchronized long getTimestamp(final int offset) {
        HistogramScaledData scaledData = fScaledData;
        if (scaledData != null) {
            return scaledData.fFirstBucketTime + Math.round(scaledData.fBucketDuration * offset);
        }
        return 0;
    }

    /**
     * Computes the offset of the timestamp in the histogram
     *
     * @param timestamp
     *            the timestamp
     * @return the offset of the corresponding bucket (-1 if invalid)
     */
    public synchronized int getOffset(final long timestamp) {
        if (timestamp < fDataModel.getFirstBucketTime() || timestamp > fDataModel.getEndTime()) {
            return -1;
        }
        return (int) ((timestamp - fDataModel.getFirstBucketTime()) / fScaledData.fBucketDuration);
    }

    /**
     * Set the bucket display offset
     *
     * @param offset
     *            the bucket display offset
     */
    protected void setOffset(final int offset) {
        fOffset = offset;
    }

    /**
     * Move the currently selected bar cursor.
     *
     * @param keyCode
     *            the SWT key code
     */
    protected void moveCursor(final int keyCode) {

        int index;
        switch (keyCode) {

        case SWT.HOME:
            fScaledData.fSelectionBeginBucket = 0;
            break;

        case SWT.END:
            fScaledData.fSelectionBeginBucket = fScaledData.fWidth - 1;
            break;

        case SWT.ARROW_RIGHT: {
            long prevStartTime = getTimestamp(fScaledData.fSelectionBeginBucket);
            index = Math.max(0, Math.min(fScaledData.fWidth - 1, fScaledData.fSelectionBeginBucket + 1));
            while (index < fScaledData.fWidth && (fScaledData.fData[index].isEmpty() || prevStartTime == getTimestamp(index))) {
                prevStartTime = getTimestamp(index);
                index++;
            }
            if (index >= fScaledData.fWidth) {
                index = fScaledData.fWidth - 1;
            }
            fScaledData.fSelectionBeginBucket = index;
            break;
        }

        case SWT.ARROW_LEFT: {
            long prevEndTime = getTimestamp(fScaledData.fSelectionBeginBucket + 1);
            index = Math.max(0, Math.min(fScaledData.fWidth - 1, fScaledData.fSelectionBeginBucket - 1));
            while (index >= 0 && (fScaledData.fData[index].isEmpty() || prevEndTime == getTimestamp(index + 1))) {
                prevEndTime = getTimestamp(index + 1);
                index--;
            }
            if (index <= 0) {
                index = 0;
            }
            fScaledData.fSelectionBeginBucket = index;
            break;
        }

        default:
            return;
        }

        fScaledData.fSelectionEndBucket = fScaledData.fSelectionBeginBucket;
        fSelectionBegin = getTimestamp(fScaledData.fSelectionBeginBucket);
        fSelectionEnd = fSelectionBegin;
        updateSelectionTime();
    }

    /**
     * Refresh the histogram display
     */
    @Override
    public void modelUpdated() {
        if (!fCanvas.isDisposed() && fCanvas.getDisplay() != null) {
            fCanvas.getDisplay().asyncExec(() ->  {
                    if (!fCanvas.isDisposed()) {
                        // Retrieve and normalize the data
                        final int canvasWidth = fCanvas.getBounds().width;
                        final int canvasHeight = fCanvas.getBounds().height;
                        if (canvasWidth <= 0 || canvasHeight <= 0) {
                            return;
                        }
                        fDataModel.setSelection(fSelectionBegin, fSelectionEnd);
                        fScaledData = fDataModel.scaleTo(canvasWidth, canvasHeight, 1);
                        synchronized (fDataModel) {
                            if (fScaledData != null) {
                                fCanvas.redraw();
                                HistogramTimeAdapter adapter = (HistogramTimeAdapter) fTimeLineScale.getTimeProvider();
                                adapter.setTimeSpace(canvasWidth);
                                // Display histogram and update X-,Y-axis labels
                                long maxNbEvents = HistogramScaledData.hideLostEvents ? fScaledData.fMaxValue : fScaledData.fMaxCombinedValue;
                                String old = fMaxNbEventsLabel.getText();
                                fMaxNbEventsLabel.setText(Long.toString(maxNbEvents));
                                // The Y-axis area might need to be re-sized
                                GridData gd = (GridData) fMaxNbEventsLabel.getLayoutData();
                                gd.widthHint = Math.max(gd.widthHint, fMaxNbEventsLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT).x);
                                fMaxNbEventsLabel.getParent().layout();
                                if (old.length() < fMaxNbEventsLabel.getText().length()) {
                                    if ((fSendTimeAlignSignals) && (fParentView instanceof ITmfTimeAligned)) {
                                        TmfSignalManager.dispatchSignal(new TmfTimeViewAlignmentSignal(this, ((ITmfTimeAligned) fParentView).getTimeViewAlignmentInfo(), true));
                                    }
                                }
                            }
                            fTimeLineScale.redraw();
                        }
                }
            });
        }
    }

    /**
     * Add a mouse wheel listener to the histogram
     *
     * @param listener
     *            the mouse wheel listener
     */
    public void addMouseWheelListener(MouseWheelListener listener) {
        fCanvas.addMouseWheelListener(listener);
    }

    /**
     * Remove a mouse wheel listener from the histogram
     *
     * @param listener
     *            the mouse wheel listener
     */
    public void removeMouseWheelListener(MouseWheelListener listener) {
        fCanvas.removeMouseWheelListener(listener);
    }

    /**
     * Add a key listener to the histogram
     *
     * @param listener
     *            the key listener
     */
    public void addKeyListener(KeyListener listener) {
        fCanvas.addKeyListener(listener);
    }

    /**
     * Remove a key listener from the histogram
     *
     * @param listener
     *            the key listener
     */
    public void removeKeyListener(KeyListener listener) {
        fCanvas.removeKeyListener(listener);
    }

    // ------------------------------------------------------------------------
    // Helper functions
    // ------------------------------------------------------------------------

    private void updateSelectionTime() {
        ((HistogramView) fParentView).updateSelectionTime(fSelectionBegin, fSelectionEnd);
    }

    // ------------------------------------------------------------------------
    // PaintListener
    // ------------------------------------------------------------------------
    /**
     * Image key string for the canvas.
     */
    protected final String IMAGE_KEY = "double-buffer-image"; //$NON-NLS-1$

    @Override
    public void paintControl(final PaintEvent event) {

        // Get the geometry
        final int canvasWidth = fCanvas.getBounds().width;
        final int canvasHeight = fCanvas.getBounds().height;

        // Make sure we have something to draw upon
        if (canvasWidth <= 0 || canvasHeight <= 0) {
            return;
        }

        // Retrieve image; re-create only if necessary
        Image image = (Image) fCanvas.getData(IMAGE_KEY);
        if (image == null || image.getBounds().width != canvasWidth || image.getBounds().height != canvasHeight) {
            if (image != null) {
                image.dispose();
            }
            image = new Image(event.display, canvasWidth, canvasHeight);
            fCanvas.setData(IMAGE_KEY, image);
        }

        // Draw the histogram on its canvas
        final GC imageGC = new GC(image);
        formatImage(imageGC, image);
        event.gc.drawImage(image, 0, 0);
        imageGC.dispose();
        fTimeLineScale.redraw();
    }

    private void formatImage(final GC imageGC, final Image image) {

        if (fScaledData == null) {
            return;
        }

        final HistogramScaledData scaledData = new HistogramScaledData(fScaledData);

        try {
            final int height = image.getBounds().height;

            // Clear the drawing area
            imageGC.setBackground(fTimeLineScale.getColorScheme().getColor(TimeGraphColorScheme.BACKGROUND));
            imageGC.fillRectangle(0, 0, image.getBounds().width + 1, image.getBounds().height + 1);

            // Draw the histogram bars
            final int limit = scaledData.fWidth;
            double factor = HistogramScaledData.hideLostEvents ? scaledData.fScalingFactor : scaledData.fScalingFactorCombined;
            final boolean showTracesColors = showTraces();
            for (int i = 0; i < limit; i++) {
                HistogramBucket hb = scaledData.fData[i];
                int totalNbEvents = hb.getNbEvents();
                int value = (int) Math.ceil(totalNbEvents * factor);
                int x = i + fOffset;

                /*
                 * in Linux, the last pixel in a line is not drawn, so draw lost
                 * events first, one pixel too far
                 */
                if (!HistogramScaledData.hideLostEvents) {
                    imageGC.setForeground(fLostEventColor);
                    final int lostEventValue = (int) Math.ceil(scaledData.fLostEventsData[i] * factor);
                    if (lostEventValue != 0) {
                        /*
                         * drawing a line is inclusive, so we should remove 1
                         * from y2 but we don't because Linux
                         */
                        imageGC.drawLine(x, height - value - lostEventValue, x, height - value);
                    }
                }

                // then draw normal events second, to overwrite that extra pixel
                if (!hb.isEmpty()) {
                    if (showTracesColors) {
                        for (int traceIndex = 0; traceIndex < hb.getNbTraces(); traceIndex++) {
                            int nbEventsForTrace = hb.getNbEvent(traceIndex);
                            if (nbEventsForTrace > 0) {
                                Color c = fHistoBarColors[traceIndex % fHistoBarColors.length];
                                imageGC.setForeground(c);
                                imageGC.drawLine(x, height - value, x, height);
                                totalNbEvents -= nbEventsForTrace;
                                value = (int) Math.ceil(totalNbEvents * scaledData.fScalingFactor);
                            }
                        }
                    } else {
                        Color c = fHistoBarColors[0];
                        imageGC.setForeground(c);
                        imageGC.drawLine(x, height - value, x, height);
                    }
                }
            }

            // Draw the selection bars
            int alpha = imageGC.getAlpha();
            imageGC.setAlpha(100);
            imageGC.setForeground(fSelectionForegroundColor);
            imageGC.setBackground(fSelectionBackgroundColor);
            final int beginBucket = scaledData.fSelectionBeginBucket + fOffset;
            if (beginBucket >= 0 && beginBucket < limit) {
                imageGC.drawLine(beginBucket, 0, beginBucket, height);
            }
            final int endBucket = scaledData.fSelectionEndBucket + fOffset;
            if (endBucket >= 0 && endBucket < limit && endBucket != beginBucket) {
                imageGC.drawLine(endBucket, 0, endBucket, height);
            }
            if (Math.abs(endBucket - beginBucket) > 1) {
                if (endBucket > beginBucket) {
                    imageGC.fillRectangle(beginBucket + 1, 0, endBucket - beginBucket - 1, height);
                } else {
                    imageGC.fillRectangle(endBucket + 1, 0, beginBucket - endBucket - 1, height);
                }
            }
            imageGC.setAlpha(alpha);
        } catch (final Exception e) {
            // Do nothing
        }
    }

    /**
     * Draw a time range window
     *
     * @param imageGC
     *            the GC
     * @param rangeStartTime
     *            the range start time
     * @param rangeDuration
     *            the range duration
     */
    protected void drawTimeRangeWindow(GC imageGC, long rangeStartTime, long rangeDuration) {

        if (fScaledData == null) {
            return;
        }

        // Map times to histogram coordinates
        double bucketSpan = fScaledData.fBucketDuration;
        long startTime = Math.min(rangeStartTime, rangeStartTime + rangeDuration);
        double rangeWidth = (Math.abs(rangeDuration) / bucketSpan);

        int left = (int) ((startTime - fDataModel.getFirstBucketTime()) / bucketSpan);
        int right = (int) (left + rangeWidth);
        int center = (left + right) / 2;
        int height = fCanvas.getSize().y;
        int arc = Math.min(15, (int) rangeWidth);

        // Draw the selection window
        imageGC.setForeground(fTimeRangeColor);
        imageGC.setLineWidth(1);
        imageGC.setLineStyle(SWT.LINE_SOLID);
        imageGC.drawRoundRectangle(left, 0, (int) rangeWidth, height - 1, arc, arc);

        // Fill the selection window
        imageGC.setBackground(fTimeRangeColor);
        imageGC.setAlpha(35);
        imageGC.fillRoundRectangle(left + 1, 1, (int) rangeWidth - 1, height - 2, arc, arc);
        imageGC.setAlpha(255);

        // Draw the cross hair
        imageGC.setForeground(fTimeRangeColor);
        imageGC.setLineWidth(1);
        imageGC.setLineStyle(SWT.LINE_SOLID);

        int chHalfWidth = ((rangeWidth < 60) ? (int) ((rangeWidth * 2) / 3) : 40) / 2;
        imageGC.drawLine(center - chHalfWidth, height / 2, center + chHalfWidth, height / 2);
        imageGC.drawLine(center, (height / 2) - chHalfWidth, center, (height / 2) + chHalfWidth);
    }

    /**
     * Get the offset of the point area, relative to the histogram canvas
     * We consider the point area to be from where the first point could
     * be drawn to where the last point could be drawn.
     *
     * @return the offset in pixels
     *
     * @since 1.0
     */
    public int getPointAreaOffset() {
        Point absCanvas = fCanvas.toDisplay(0, 0);
        Point viewPoint = fComposite.getParent().toDisplay(0, 0);
        return absCanvas.x - viewPoint.x;
    }

    /**
     * Get the width of the point area. We consider the point area to be from
     * where the first point could be drawn to where the last point could be
     * drawn. The point area differs from the plot area because there might be a
     * gap between where the plot area start and where the fist point is drawn.
     * This also matches the width that the use can select.
     *
     * @return the width in pixels
     *
     * @since 1.0
     */
    public int getPointAreaWidth() {
        if (!fCanvas.isDisposed()) {
            // Retrieve and normalize the data
            return fCanvas.getBounds().width;
        }
        return 0;
    }

    // ------------------------------------------------------------------------
    // KeyListener
    // ------------------------------------------------------------------------

    @Override
    public void keyPressed(final KeyEvent event) {
        moveCursor(event.keyCode);
    }

    @Override
    public void keyReleased(final KeyEvent event) {
        // do nothing
    }

    // ------------------------------------------------------------------------
    // MouseListener
    // ------------------------------------------------------------------------

    @Override
    public void mouseDoubleClick(final MouseEvent event) {
        // do nothing
    }

    @Override
    public void mouseDown(final MouseEvent event) {
        if (fScaledData != null && event.button == 1 && fDragState == DRAG_NONE &&
                (fDataModel.getNbEvents() != 0 || fDataModel.getStartTime() < fDataModel.getEndTime())) {
            fDragState = DRAG_SELECTION;
            fDragButton = event.button;
            if ((event.stateMask & SWT.MODIFIER_MASK) == SWT.SHIFT) {
                if (Math.abs(event.x - fScaledData.fSelectionBeginBucket) < Math.abs(event.x - fScaledData.fSelectionEndBucket)) {
                    fScaledData.fSelectionBeginBucket = fScaledData.fSelectionEndBucket;
                    fSelectionBegin = fSelectionEnd;
                }
                fSelectionEnd = getTimestamp(event.x);
                fScaledData.fSelectionEndBucket = event.x;
            } else {
                fSelectionBegin = Math.min(getTimestamp(event.x), getEndTime());
                fScaledData.fSelectionBeginBucket = event.x;
                fSelectionEnd = fSelectionBegin;
                fScaledData.fSelectionEndBucket = fScaledData.fSelectionBeginBucket;
            }
            updateStatusLine(fSelectionBegin, fSelectionEnd, getTimestamp(event.x));
            fCanvas.redraw();
            fTimeLineScale.redraw();
        }
    }

    @Override
    public void mouseUp(final MouseEvent event) {
        if (fDragState == DRAG_SELECTION && event.button == fDragButton) {
            fDragState = DRAG_NONE;
            fDragButton = 0;
            updateSelectionTime();
        }
        updateStatusLine(fSelectionBegin, fSelectionEnd, getTimestamp(event.x));
    }

    // ------------------------------------------------------------------------
    // MouseMoveListener
    // ------------------------------------------------------------------------

    @Override
    public void mouseMove(MouseEvent event) {
        if (fDragState == DRAG_SELECTION && (fDataModel.getNbEvents() != 0 || fDataModel.getStartTime() < fDataModel.getEndTime())) {
            fSelectionEnd = Math.max(getStartTime(), Math.min(getEndTime(), getTimestamp(event.x)));
            fScaledData.fSelectionEndBucket = Math.max(0, Math.min(fScaledData.fWidth - 1, event.x));
            fCanvas.redraw();
            fTimeLineScale.redraw();
        }
        updateStatusLine(fSelectionBegin, fSelectionEnd, getTimestamp(event.x));
    }

    // ------------------------------------------------------------------------
    // MouseTrackListener
    // ------------------------------------------------------------------------

    @Override
    public void mouseEnter(final MouseEvent event) {
        updateStatusLine(fSelectionBegin, fSelectionEnd, getTimestamp(event.x));
    }

    @Override
    public void mouseExit(final MouseEvent event) {
        updateStatusLine(fSelectionBegin, fSelectionEnd, -1);
    }

    @Override
    public void mouseHover(final MouseEvent event) {
        // do nothing
    }

    private void updateStatusLine(long startTime, long endTime, long cursorTime) {
        ITimeDataProvider timeProvider = fTimeLineScale.getTimeProvider();
        if (timeProvider.getTime0() == timeProvider.getTime1()) {
            return;
        }
        TimeFormat timeFormat = timeProvider.getTimeFormat().convert();
        boolean isCalendar = timeFormat == TimeFormat.CALENDAR;

        StringBuilder message = new StringBuilder();
        String spaces = "     "; //$NON-NLS-1$
        if (cursorTime >= 0) {
            message.append("T: "); //$NON-NLS-1$
            if (isCalendar) {
                message.append(FormatTimeUtils.formatDate(cursorTime) + ' ');
            }
            message.append(FormatTimeUtils.formatTime(cursorTime, timeFormat, Resolution.NANOSEC));
            message.append(spaces);
        }

        if (startTime == endTime) {
            message.append("T1: "); //$NON-NLS-1$
            if (isCalendar) {
                message.append(FormatTimeUtils.formatDate(startTime) + ' ');
            }
            message.append(FormatTimeUtils.formatTime(startTime, timeFormat, Resolution.NANOSEC));
        } else {
            message.append("T1: "); //$NON-NLS-1$
            if (isCalendar) {
                message.append(FormatTimeUtils.formatDate(startTime) + ' ');
            }
            message.append(FormatTimeUtils.formatTime(startTime, timeFormat, Resolution.NANOSEC));
            message.append(spaces);
            message.append("T2: "); //$NON-NLS-1$
            if (isCalendar) {
                message.append(FormatTimeUtils.formatDate(endTime) + ' ');
            }
            message.append(FormatTimeUtils.formatTime(endTime, timeFormat, Resolution.NANOSEC));
            message.append(spaces);
            message.append("\u0394: " + FormatTimeUtils.formatDelta(endTime - startTime, timeFormat, Resolution.NANOSEC)); //$NON-NLS-1$
        }

        fStatusLineManager.setMessage(message.toString());
    }

    // ------------------------------------------------------------------------
    // ControlListener
    // ------------------------------------------------------------------------

    @Override
    public void controlMoved(final ControlEvent event) {
        fDataModel.complete();
    }

    @Override
    public void controlResized(final ControlEvent event) {
        fDataModel.complete();
    }

    // ------------------------------------------------------------------------
    // Signal Handlers
    // ------------------------------------------------------------------------

    /**
     * Format the timestamp and update the display
     *
     * @param signal
     *            the incoming signal
     */
    @TmfSignalHandler
    public void timestampFormatUpdated(TmfTimestampFormatUpdateSignal signal) {
        updateTimeFormat();
        fTimeLineScale.redraw();
        fComposite.layout();
    }

    private void updateTimeFormat() {
        HistogramTimeAdapter timeProvider = (HistogramTimeAdapter) fTimeLineScale.getTimeProvider();
        String datime = TmfTimePreferences.getPreferenceMap().get(ITmfTimePreferencesConstants.DATIME);
        if (ITmfTimePreferencesConstants.TIME_ELAPSED_FMT.equals(datime)) {
            timeProvider.setTimeFormat(TimeFormat.RELATIVE);
        } else {
            timeProvider.setTimeFormat(TimeFormat.CALENDAR);
        }
    }
}
