// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2018 Thomas Klose & Torsten Schache, Hiperscan GmbH Dresden, Germany
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Drawing;
using Gtk;

namespace Hiperscan.GtkExtensions.Widgets
{
    public partial class ExtToolTip
    {
        internal class ToolTipData
        {
            public string Title { get; set; } = String.Empty;
            public string Message { get; set; } = String.Empty;
            public string Stock { get; set; } = String.Empty;
            public ExtToolTip Tooltip { get; set; } = null;
            public bool DoNotAction { get; set; } = false;
        }

        public static void SetDialog(Gtk.Widget parent,
                                 string stock,
                                 string title,
                                 string message,
                                 string link = null,
                                 EventHandler link_event = null)
        {
            ExtToolTip.Create(parent,
                              true,
                              stock,
                              title,
                              message,
                              link,
                              link_event);
        }


        public static void SetToolTip( Gtk.Widget widget, String title, String message, String stock )
        {
            ToolTipData data = new ToolTipData()
            {
                Title = title,
                Message = message,
                Stock = stock,
            };
            ExtToolTip.AddWidget( widget, data );
        }

        public static void UnsetToolTip( Gtk.Widget widget)
        {
            if (Widgets.ContainsKey(widget))
                Widgets.Remove(widget);
        }


        private static ExtToolTip Create(Gtk.Widget parent,
                                 bool is_dialog,
                                 string stock,
                                 string title,
                                 string message,
                                 string link = null,
                                 EventHandler link_event = null)

        {
            int x = 0;
            int y = 0;
            parent.Screen.Display.GetPointer(out x, out y);

            return new ExtToolTip(is_dialog,
                                                x,
                                                y,
                                               stock,
                                                title,
                                                message,
                                                link,
                                                link_event);
        }


        private static void AddWidget(Gtk.Widget widget, ToolTipData data)
        {
            if( ExtToolTip.Widgets.ContainsKey( widget) == false )
            {
                ExtToolTip.Widgets.Add(widget, data);
                widget.DeleteEvent  += OnWidgetDeleted;
                widget.AddEvents( (int)Gdk.EventMask.LeaveNotifyMask  );
                widget.AddEvents( (int)Gdk.EventMask.EnterNotifyMask  );

                widget.WidgetEvent += delegate(object sender, Gtk.WidgetEventArgs args)
                {
                    if( args.Event.Type == Gdk.EventType.LeaveNotify)
                    {
                        ExtToolTip.Destroy(sender as Widget);                                                                                 
                    }
                    if( args.Event.Type == Gdk.EventType.EnterNotify )
                    {
                        ExtToolTip.Show(sender as Widget);
                    }                    
                };
            }
            else
            {
                Widgets[widget] = data;
            }
        }

        private static void Show(Widget widget)
        {

            ToolTipData data = ExtToolTip.Widgets[widget];
            if (data.Tooltip != null)
                return;
            if (data.DoNotAction == false)
            {
                data.Tooltip = ExtToolTip.Create(widget,
                                          false,
                                          data.Stock,
                                          data.Title,
                                          data.Message);
            }
        }

        private static void Destroy(Widget widget)
        {
            ToolTipData data = ExtToolTip.Widgets[widget];
            if (data.Tooltip != null && data.DoNotAction == false)
            {
                data.DoNotAction = true;
                GLib.Timeout.Add(250,() =>
                {
                    data.Tooltip.Destroy();
                    data.Tooltip = null;
                    data.DoNotAction = false;
                    return false;
                });
            }
        }

        private static void OnWidgetDeleted( object sender, EventArgs args )
        {
            ExtToolTip.Widgets.Remove( (Gtk.Widget) sender );
        }

        public static uint ToolTipInterval { get; set; } = 750;
        private static Dictionary<Gtk.Widget, ToolTipData> Widgets { get; set; } = new Dictionary<Gtk.Widget, ToolTipData>();
    }
}
