// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2021 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.IO;
using System.Reflection;

namespace Hiperscan.Extensions.ApoIdent
{
    public partial class GuiDesigner
    {
        private class GreyColour
        {
            public double A { get; set; }
            public double Gray { get; set; }
        }

        private void LoadActiveIconImages()
        {
            foreach (ApoIdentIcon icon in Enum.GetValues(typeof(ApoIdentIcon)))
            {
                string resource = this.GetIconResource(icon);
                Gdk.Size size = this.GetIconSize(icon);
                Gdk.Pixbuf pixbuf = new Gdk.Pixbuf(null, resource, size.Width, size.Height);
                this.ActiveIcons.Add(icon, pixbuf);
            }
        }

        private void LoadInactiveIconImages()
        {
            foreach (ApoIdentIcon icon in Enum.GetValues(typeof(ApoIdentIcon)))
            {
                GreyColour[,] grey_raw_data = this.GetGreyRawData(icon);
                Gdk.Pixbuf pixbuf = this.GetInactivePicture(icon, grey_raw_data);
                this.InactiveIcons.Add(icon, pixbuf);
            }
        }

        private GreyColour[,] GetGreyRawData(ApoIdentIcon icon)
        {
            string resource = this.GetIconResource(icon);

            using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource))
            {
                System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(stream);
                GreyColour[,] pixels = new GreyColour[bitmap.Width, bitmap.Height];

                for (int x = 0; x < bitmap.Width; x++)
                {
                    for (int y = 0; y < bitmap.Height; y++)
                    {

                        System.Drawing.Color c = bitmap.GetPixel(x, y);
                        pixels[x, y] = new GreyColour();
                        pixels[x, y].A = c.A;
                        pixels[x, y].Gray = (c.R + c.G + c.B) / 3;
                    }
                }

                return pixels;
            }
        }

        private Gdk.Pixbuf GetInactivePicture(ApoIdentIcon icon, GreyColour[,] grey_picture)
        {
            Gdk.Color color = new Gdk.Color(125, 125, 255);

            System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(grey_picture.GetLength(0), grey_picture.GetLength(1));

            using (MemoryStream ms = new MemoryStream())
            {
                for (int x = 0; x < grey_picture.GetLength(0); x++)
                {
                    for (int y = 0; y < grey_picture.GetLength(1); y++)
                    {
                        double gray = grey_picture[x, y].Gray;

                        int red = (int)(gray + (255 - gray) / 255 * (color.Red / 256));
                        int green = (int)(gray + (255 - gray) / 255 * (color.Green / 256));
                        int blue = (int)(gray + (255 - gray) / 255 * (color.Blue / 256));

                        System.Drawing.Color c = System.Drawing.Color.FromArgb((int)grey_picture[x, y].A, red, green, blue);
                        bitmap.SetPixel(x, y, c);
                    }
                }

                bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                ms.Position = 0;
                Gdk.Size size = this.GetIconSize(icon);
                return new Gdk.Pixbuf(ms, size.Width, size.Height);
            }
        }

        private Gdk.Size GetIconSize(ApoIdent.ApoIdentIcon icon)
        {
            Gtk.IconSize size = Gtk.IconSize.Dialog;

            switch (icon)
            {
                case ApoIdentIcon.ClassifierChange:
                case ApoIdentIcon.DataExchangeLennartz:
                case ApoIdentIcon.DataExchangeLennartzOk:
                case ApoIdentIcon.LabelPrint:
                case ApoIdentIcon.Pdf:
                case ApoIdentIcon.Print:
                case ApoIdentIcon.Save:
                case ApoIdentIcon.SubstanceInfo:
                case ApoIdentIcon.SubstanceWarning:
                case ApoIdentIcon.Clear:
                    size = Gtk.IconSize.LargeToolbar;
                    if (Environment.OSVersion.Platform != PlatformID.Unix)
                        size = Gtk.IconSize.SmallToolbar;
                    break;

                default:
                    break;
            }

            Gtk.Icon.SizeLookup(size, out int x, out int y);
            return new Gdk.Size(x, y);
        }

        private string GetIconResource(ApoIdentIcon icon)
        {
            return String.Format("Hiperscan.Extensions.ApoIdent.GuiDesigner.ButtonIcons.{0}.png", icon);
        }

        private Dictionary<ApoIdentIcon, Gdk.Pixbuf> ActiveIcons { get; set; } = new Dictionary<ApoIdentIcon, Gdk.Pixbuf>();
        private Dictionary<ApoIdentIcon, Gdk.Pixbuf> InactiveIcons { get; set; } = new Dictionary<ApoIdentIcon, Gdk.Pixbuf>();
    }
}
