/**
 * Copyright (c) 2019 CEA.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 *  Contributors:
 *     CEA - initial API and implementation and/or initial documentation
 */
package org.eclipse.sensinact.studio.ui.common.notification;

// SEE http://hexapixel.com/2009/06/30/creating-a-notification-popup-widget


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

import org.eclipse.sensinact.studio.ui.common.color.Colors;
import org.eclipse.sensinact.studio.ui.common.images.StudioImage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
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.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;

public class NotifierDialog {

    // how long the the tray popup is displayed after fading in (in milliseconds)
    private static final int   DISPLAY_TIME  = 4500;
    // how long each tick is when fading in (in ms)
    private static final int   FADE_TIMER    = 50;
    // how long each tick is when fading out (in ms)
    private static final int   FADE_IN_STEP  = 30;
    // how many tick steps we use when fading out 
    private static final int   FADE_OUT_STEP = 8;

    // how high the alpha value is when we have finished fading in 
    private static final int   FINAL_ALPHA   = 225;

    // title foreground color
    private static Color       _titleFgColor = Colors.getINSTANCE().getColor(40, 73, 97);
    // text foreground color
    private static Color       _fgColor      = _titleFgColor;

    // shell gradient background color - top
    private static Color       _bgFgGradient = Colors.getINSTANCE().getColor(226, 239, 249);
    // shell gradient background color - bottom    
    private static Color       _bgBgGradient = Colors.getINSTANCE().getColor(177, 211, 243);
    // shell border color
    private static Color       _borderColor  = Colors.getINSTANCE().getColor(40, 73, 97);

    // contains list of all active popup shells
    private static List<Shell> _activeShells = new ArrayList<Shell>();

    // image used when drawing
    private static Image       _oldImage;

    private static Shell       _shell;

    /**
     * Creates and shows a notification dialog with a specific title, message and a
     * 
     * @param title
     * @param message
     * @param type
     */
    public static void notify(String title, String message) {
        _shell = new Shell(Display.getDefault().getActiveShell(), SWT.NO_FOCUS | SWT.NO_TRIM);
        _shell.setLayout(new FillLayout());
        _shell.setForeground(_fgColor);
        _shell.setBackgroundMode(SWT.INHERIT_DEFAULT);
        _shell.addListener(SWT.Dispose, new Listener() {
            @Override
            public void handleEvent(Event event) {
                _activeShells.remove(_shell);
            }
        });

        final Composite inner = new Composite(_shell, SWT.NONE);

        GridLayout gl = new GridLayout(2, false);
        gl.marginLeft = 5;
        gl.marginTop = 0;
        gl.marginRight = 5;
        gl.marginBottom = 5;

        inner.setLayout(gl);
        _shell.addListener(SWT.Resize, new Listener() {

            @Override
            public void handleEvent(Event e) {
                try {
                    // get the size of the drawing area
                    Rectangle rect = _shell.getClientArea();
                    // create a new image with that size
                    Image newImage = new Image(Display.getDefault(), Math.max(1, rect.width), rect.height);
                    // create a GC object we can use to draw with
                    GC gc = new GC(newImage);

                    // fill background
                    gc.setForeground(_bgFgGradient);
                    gc.setBackground(_bgBgGradient);
                    gc.fillGradientRectangle(rect.x, rect.y, rect.width, rect.height, true);

                    // draw shell edge
                    gc.setLineWidth(2);
                    gc.setForeground(_borderColor);
                    gc.drawRectangle(rect.x + 1, rect.y + 1, rect.width - 2, rect.height - 2);
                    // remember to dipose the GC object!
                    gc.dispose();

                    // now set the background image on the shell
                    _shell.setBackgroundImage(newImage);

                    // remember/dispose old used iamge
                    if (_oldImage != null) {
                        _oldImage.dispose();
                    }
                    _oldImage = newImage;
                } catch (Exception err) {
                    err.printStackTrace();
                }
            }
        });

        GC gc = new GC(_shell);

        String lines[] = message.split("\n");
        Point longest = null;
        int typicalHeight = gc.stringExtent("X").y;

        for (String line : lines) {
            Point extent = gc.stringExtent(line);
            if (longest == null) {
                longest = extent;
                continue;
            }

            if (extent.x > longest.x) {
                longest = extent;
            }
        }
        gc.dispose();

        int minHeight = typicalHeight * lines.length;

        CLabel imgLabel = new CLabel(inner, SWT.NONE);
        imgLabel.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.HORIZONTAL_ALIGN_BEGINNING));
        imgLabel.setImage(StudioImage.OK.getImage()); // TODO customize here !!!

        CLabel titleLabel = new CLabel(inner, SWT.NONE);
        titleLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER));
        titleLabel.setText(title);
        titleLabel.setForeground(_titleFgColor);
        Font f = titleLabel.getFont();
        FontData fd = f.getFontData()[0];
        fd.setStyle(SWT.BOLD);
        fd.height = 11;
        titleLabel.setFont(FontCache.getFont(fd));

        Label text = new Label(inner, SWT.WRAP);
        Font tf = text.getFont();
        FontData tfd = tf.getFontData()[0];
        tfd.setStyle(SWT.BOLD);
        tfd.height = 8;
        text.setFont(FontCache.getFont(tfd));
        GridData gd = new GridData(GridData.FILL_BOTH);
        gd.horizontalSpan = 2;
        text.setLayoutData(gd);
        text.setForeground(_fgColor);
        text.setText(message);

        minHeight = 100;

        _shell.setSize(350, minHeight);

        if (Display.getDefault().getActiveShell() == null || Display.getDefault().getActiveShell().getMonitor() == null) { return; }

        Rectangle clientArea = Display.getDefault().getActiveShell().getMonitor().getClientArea();

        int startX = clientArea.x + clientArea.width - 352;
        int startY = clientArea.y + clientArea.height - 102;

        // move other shells up
        if (!_activeShells.isEmpty()) {
            List<Shell> modifiable = new ArrayList<Shell>(_activeShells);
            Collections.reverse(modifiable);
            for (Shell shell : modifiable) {
                Point curLoc = shell.getLocation();
                shell.setLocation(curLoc.x, curLoc.y - 100);
                if (curLoc.y - 100 < 0) {
                    _activeShells.remove(shell);
                    shell.dispose();
                }
            }
        }

        _shell.setLocation(startX, startY);
        _shell.setAlpha(0);
        _shell.setVisible(true);

        _activeShells.add(_shell);

        fadeIn(_shell);
    }

    private static void fadeIn(final Shell _shell) {
        Runnable run = new Runnable() {

            @Override
            public void run() {
                try {
                    if (_shell == null || _shell.isDisposed()) { return; }

                    int cur = _shell.getAlpha();
                    cur += FADE_IN_STEP;

                    if (cur > FINAL_ALPHA) {
                        _shell.setAlpha(FINAL_ALPHA);
                        startTimer(_shell);
                        return;
                    }

                    _shell.setAlpha(cur);
                    Display.getDefault().timerExec(FADE_TIMER, this);
                } catch (Exception err) {
                    err.printStackTrace();
                }
            }

        };
        Display.getDefault().timerExec(FADE_TIMER, run);
    }

    private static void startTimer(final Shell _shell) {
        Runnable run = new Runnable() {

            @Override
            public void run() {
                try {
                    if (_shell == null || _shell.isDisposed()) { return; }

                    fadeOut(_shell);
                } catch (Exception err) {
                    err.printStackTrace();
                }
            }

        };
        Display.getDefault().timerExec(DISPLAY_TIME, run);

    }

    private static void fadeOut(final Shell _shell) {
        final Runnable run = new Runnable() {

            @Override
            public void run() {
                try {
                    if (_shell == null || _shell.isDisposed()) { return; }

                    if (_oldImage != null) {
                        _oldImage.dispose();
                    }
                    _shell.dispose();
                    _activeShells.remove(_shell);
                    return;
                    
                } catch (Exception err) {
                    err.printStackTrace();
                }
            }

        };
        Display.getDefault().timerExec(FADE_TIMER, run);
    }
}
