// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2021 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 Gtk;
using Cairo;
using Hiperscan.Spectroscopy.IdentModule;
using Hiperscan.GtkExtensions.Widgets;
using Hiperscan.Unix;

namespace Hiperscan.Extensions.ApoIdent.Widgets
{
    public class BAKMarking
    {
        public BAKMarking(Gtk.HBox parent)
        {
            this.Parent = parent;
            this.RedArea = (this.Parent.Children[0] as Gtk.Alignment).Children[0] as Gtk.DrawingArea;
            this.YellowArea = (this.Parent.Children[1] as Gtk.Alignment).Children[0] as Gtk.DrawingArea;
            this.BlueArea = (this.Parent.Children[2] as Gtk.Alignment).Children[0] as Gtk.DrawingArea;
            this.OrangeArea = (this.Parent.Children[3] as Gtk.Alignment).Children[0] as Gtk.DrawingArea;

            this.BackgroudColor = ApoIdentColors.WHITE;

            this.RedArea.ExposeEvent += this.OnExpose;
            this.RedArea.QueueDraw();
            this.RedArea.Parent.NoShowAll = true;
            this.RedArea.TooltipText = Catalog.GetString("Protective gloves\nProtective goggles\nBreathing protection");

            this.YellowArea.ExposeEvent += this.OnExpose;
            this.YellowArea.QueueDraw();
            this.YellowArea.Parent.NoShowAll = true;
            this.YellowArea.TooltipText = Catalog.GetString("Protective gloves");

            this.BlueArea.ExposeEvent += this.OnExpose;
            this.BlueArea.QueueDraw();
            this.BlueArea.Parent.NoShowAll = true;
            this.BlueArea.TooltipText = Catalog.GetString("Protective goggles");

            this.OrangeArea.ExposeEvent += this.OnExpose;
            this.OrangeArea.QueueDraw();
            this.OrangeArea.Parent.NoShowAll = true;
            this.OrangeArea.TooltipText = Catalog.GetString("Breathing protection");

            this.SetState(BAKMarkingState.None);
        }

        private void OnExpose(object sender, ExposeEventArgs args)
        {
            DrawingArea area = (DrawingArea)sender;
            if (area.GdkWindow == null)
                return;

            Cairo.Context cr = Gdk.CairoHelper.Create(area.GdkWindow);


            Cairo.Color fill = this.GetColor(area);
            Cairo.Color line_color = new Cairo.Color(0.5, 0.5, 0.5);
            Cairo.Color white_transparent = new Color(1, 1, 1, 0.3);

            int width = area.Allocation.Width;
            int height = area.Allocation.Height;

            cr.Rectangle(0, 0, width, height);
            cr.SetSourceColor(this.BackGroundCairo);
            cr.Fill();

            cr.Arc(width / 2, height / 2, height / 2, 0, 2 * Math.PI);
            cr.ClosePath();
            cr.Clip();


            cr.Rectangle(0, 0, width, height);
            cr.SetSourceColor(fill);
            cr.Fill();

            cr.Rectangle(0, 0, width, height);
            cr.LineWidth = 1;
            cr.SetSourceColor(line_color);
            cr.Stroke();

            cr.MoveTo(new PointD(0, 0));
            cr.LineTo(new PointD(0, height));
            cr.LineTo(new PointD(width, 0));
            cr.LineTo(new PointD(0, 0));
            cr.ClosePath();
            cr.SetSourceColor(white_transparent);
            cr.Fill();

            ((IDisposable)cr.GetTarget()).Dispose();
            ((IDisposable)cr).Dispose();
        }

        private Cairo.Color GetColor(Gtk.DrawingArea area)
        {
            if (area == this.RedArea)
                return this.Red;

            if (area == this.YellowArea)
                return this.Yellow;

            if (area == this.BlueArea)
                return this.Blue;

            return this.Orange;
        }


        public void SetState(BAKMarkingState type)
        {
            this.RedArea.Parent.Visible = false;
            this.YellowArea.Parent.Visible = false;
            this.BlueArea.Parent.Visible = false;
            this.OrangeArea.Parent.Visible = false;

            if (type.HasFlag(BAKMarkingState.Red))
                this.RedArea.Parent.Visible = true;

            if (type.HasFlag(BAKMarkingState.Yellow))
                this.YellowArea.Parent.Visible = true;

            if (type.HasFlag(BAKMarkingState.Blue))
                this.BlueArea.Parent.Visible = true;

            if (type.HasFlag(BAKMarkingState.Orange))
                this.OrangeArea.Parent.Visible = true;
        }

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

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

        public Gdk.Color BackgroudColor
        {
            set
            {
                double red = (double)value.Red / ushort.MaxValue;
                double green = (double)value.Green / ushort.MaxValue;
                double blue = (double)value.Blue / ushort.MaxValue;

                this.BackGroundCairo = new Cairo.Color(red, green, blue);
            }
        }

        private Gtk.DrawingArea RedArea { get; set; }
        private Gtk.DrawingArea YellowArea { get; set; }
        private Gtk.DrawingArea BlueArea { get; set; }
        private Gtk.DrawingArea OrangeArea { get; set; }

        public Cairo.Color Red { get; private set; } = new Cairo.Color(0.95, 0, 0);
        public Cairo.Color Yellow { get; private set; } = new Cairo.Color(0.95, 0.95, 0);
        public Cairo.Color Blue { get; private set; } = new Cairo.Color(0, 0, 0.95);
        public Cairo.Color Orange { get; private set; } = new Cairo.Color(0.95, 0.61, 0);


        private Gtk.HBox Parent { get; set; }

        private Cairo.Color BackGroundCairo { get; set; }
    }
}
