// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2020 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 Gtk;

namespace Hiperscan.GtkExtensions.Widgets
{
    public class LinkLabel
    {
        public event EventHandler Clicked = null;

        public LinkLabel(Gtk.Label label)
        {
            this.GtkLabel = label;
            this.FormatText(this.GtkLabel.LabelProp);
            this.FgColor = new Gdk.Color(0, 0, 255);
            this.MakeClickable();
            this.ActivateMouseOver();
        }

        private void FormatText(string text)
        {
            text = text ?? String.Empty;
            if (text.Contains("<u>") == false)
                text = "<u>" + text + "</u>";
            this.GtkLabel.Markup = text;
            this.GtkLabel.UseMarkup = true;
        }

        private void MakeClickable()
        {
            Gtk.Container parent = this.GtkLabel.Parent as Gtk.Container;

            if ((parent is Gtk.Alignment) == false)
                throw new Exception("LinkLabel: use for the widget a Gtk.Alignment as parent object.");


            parent.Remove(this.GtkLabel);
            this.GtkEventBox = new EventBox();
            this.GtkEventBox.Add(this.GtkLabel);
            parent.Add(this.GtkEventBox);

            this.GtkEventBox.AddEvents((int)Gdk.EventType.ButtonRelease);
            this.GtkEventBox.ButtonReleaseEvent += this.OnInternalButtonReleaseEvent;

            parent.ShowAll();
            this.GtkEventBox.ShowAll();
            this.GtkLabel.ShowAll();
        }

        private void ActivateMouseOver()
        {
            this.GtkEventBox.AddEvents((int)Gdk.EventType.EnterNotify);
            this.GtkEventBox.EnterNotifyEvent += (o, args) => this.SetCursor(new Gdk.Cursor(Gdk.CursorType.Hand2), EventArgs.Empty);
            this.GtkEventBox.AddEvents((int)Gdk.EventType.LeaveNotify);
            this.GtkEventBox.LeaveNotifyEvent += (o, args) => this.SetCursor(new Gdk.Cursor(Gdk.CursorType.Arrow), EventArgs.Empty);
        }

        private void SetCursor(object sender, EventArgs e)
        {
            if (this.GtkLabel.GdkWindow == null)
                return;

            if (this.GtkLabel.IsRealized == false)
                return;

            if (this.GtkLabel.Sensitive == false)
            {
                this.GtkLabel.GdkWindow.Cursor = new Gdk.Cursor(Gdk.CursorType.Arrow);
                return;
            }

            this.GtkLabel.GdkWindow.Cursor = sender as Gdk.Cursor;
        }

        private void OnInternalButtonReleaseEvent(object sender, Gtk.ButtonReleaseEventArgs e)
        {
            if (this.GtkLabel.Sensitive == false)
                return;

            if (e.Event.Button == 1)
                this.Clicked?.Invoke(this, EventArgs.Empty);
        }

        public Gdk.Color BgColor
        {
            set
            {
                this.GtkEventBox.ModifyBg(StateType.Normal, value);

            }
        }

        public Gdk.Color FgColor
        {
            set
            {
                WidgetColor.SetFontColor(this.GtkLabel, value);
            }
        }

        public string Text
        {
            set
            {
                this.FormatText(value);
            }
        }

        public string Tooltip
        {
            set
            {
                this.GtkLabel.TooltipText = value;
            }
        }

        public bool Sensitive
        {
            set
            {
                this.GtkLabel.Sensitive = value;
            }
        }

        public bool Visible
        {
            set
            {
                this.GtkLabel.Visible = value;
            }
        }

        public int Width
        {
            get
            {
                return this.GtkLabel.Allocation.Width;
            }
        }

        private Gtk.Label GtkLabel { get; set; }
        private Gtk.EventBox GtkEventBox { get; set; }
    }
}
