// 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 Gdk;
using Glade;
using GLib;
using Gtk;
using Hiperscan.AnalysisModule;
using Hiperscan.AnalysisModule.Identification;
using Hiperscan.ApoIdentCore;
using Hiperscan.ApoIdentCore.SectionManager.Substance.SubstanceSelection;
using Hiperscan.Unix;

namespace Hiperscan.Extensions.ApoIdent
{
    public class ModelClassDialog
    {
        [Widget] Gtk.Dialog model_class_dialog      = null;
        [Widget] Gtk.Label advice_label             = null;
        [Widget] Gtk.TreeView model_class_treeview  = null;
        [Widget] Gtk.Button close_button = null;

        public static ModelClassDialog Run(Gtk.Window parent, AppControl control)
        {
            return new ModelClassDialog(parent, control.SubstanceManager.SubstancesCatalog);
        }

        private ModelClassDialog(Gtk.Window parent, SubstancesCatalog substance_catalog)
        {
            this.SubstancesCatalog = substance_catalog;
            this.SubstancesCatalog.ResetUserSelections();
            this.SubstancesCatalog.SortPreselectedSubstanceByCategory();

            Glade.XML gui = new Glade.XML(null, "model_class_dialog.glade", "model_class_dialog", "Hiperscan");
            gui.Autoconnect(this);

            this.model_class_dialog.IconList = ApoIdentStock.FinderIcons;
            this.model_class_dialog.TransientFor = parent;

            this.InitSubstanceCategories(18);

            ApoIdent.ApoIdentApplication.SetWmcClassName(this.model_class_dialog);

            this.model_class_dialog.Default = this.close_button;
            this.model_class_dialog.KeyPressEvent += this.OnKeyPressEvent;
            Gtk.ListStore store = new ListStore (typeof(Gdk.Pixbuf),
                                                 typeof(string),
                                                 typeof(string),
                                                 typeof(IdentSubstance));

            this.model_class_treeview.AppendColumn(Catalog.GetString("Category"), new CellRendererPixbuf(), "pixbuf" , 0);
            this.model_class_treeview.AppendColumn(Catalog.GetString("Substance name"), new CellRendererText(), "text" , 1);
            this.model_class_treeview.AppendColumn(Catalog.GetString("Classifier"), new CellRendererText(), "text" , 2);

            this.model_class_treeview.Model = store;
            this.model_class_treeview.ButtonPressEvent += this.OnButtonPressEvent;


            foreach (IdentSubstance substance in this.SubstancesCatalog.PreselectedSubstances)
            {
                switch (substance.Classification.ClassificationType)
                {
                    case ClassificationType.Multiple:
                        store.AppendValues(this.YelllowPoint,
                                           substance.BestReferenceName,
                                           substance.ModelClass.Name,
                                           substance);
                        break;

                    case ClassificationType.UserDefined:
                        store.AppendValues(this.BlackPoint,
                                           substance.BestReferenceName,
                                           substance.ModelClass.Name,
                                           substance);
                        break;

                    case ClassificationType.NotMeasurable:
                        store.AppendValues(this.RedPoint, 
                                           substance.BestReferenceName, 
                                           substance.ModelClass.Name,
                                           substance);
                        break;

                    case ClassificationType.Single:
                        Gdk.Pixbuf pix_puf = substance.AnalysisType == AnalysisType.Identification ? this.GreenPoint : this.WhitePoint;
                        store.AppendValues(pix_puf, 
                                           substance.BestReferenceName, 
                                           substance.ModelClass.Name,
                                           substance);
                        break;

                    default:
                        break;
                }
            }

            this.advice_label.Text = String.Format(Catalog.GetString("Substance '{0}' is available in several classifiers. Please choose a classifier to continue."),
                                                   this.SubstancesCatalog.FuzzyName);

            int screen_width = -1;
            try
            {
                screen_width = Gdk.Display.Default.DefaultScreen.Width /
                               Gdk.Display.Default.DefaultScreen.NMonitors;
            }
            catch (Exception)
            {
                screen_width = -1;
            }

            int width = this.model_class_treeview.SizeRequest().Width + 20;
            if (width > screen_width)
                width = screen_width - 100;

            this.advice_label.WidthRequest = width;
            this.model_class_dialog.HeightRequest = 300;

             Gtk.TreeIter iter;
            store.GetIterFirst(out iter);
            this.model_class_treeview.Selection.SelectIter(iter);
            ((IdentSubstance)store.GetValue(iter, 3)).FromUserSelected = true;
            this.model_class_treeview.Selection.Changed += this.OnSelectionChanged;


            this.model_class_dialog.IconList = ApoIdentStock.FinderIcons;

            GuiDesigner.SetSchema(this.model_class_dialog);
            this.model_class_dialog.Run();
            this.model_class_dialog.Destroy();
        }

        private void OnSelectionChanged(object sender, EventArgs e)
        {
            Gtk.TreeIter iter;
            this.model_class_treeview.Selection.GetSelected(out iter);
            ListStore store = (ListStore) this.model_class_treeview.Model;

            this.SubstancesCatalog.ResetUserSelections();
            ((IdentSubstance)store.GetValue(iter, 3)).FromUserSelected = true;
        }

        [ConnectBefore]
        private void OnButtonPressEvent(object sender, ButtonPressEventArgs e)
        {
            if (e.Event.Button == 1 && e.Event.Type == Gdk.EventType.TwoButtonPress)
                this.model_class_dialog.Destroy();
        }

        [ConnectBefore]
        private void OnKeyPressEvent(object sender, KeyPressEventArgs e)
        {
            if (e.Event.Key == Gdk.Key.Return || e.Event.Key == Gdk.Key.KP_Enter)
                this.model_class_dialog.Destroy();
        }

        private void InitSubstanceCategories(int size)
        {
            this.WhitePoint = new Pixbuf(null, "white_point.png", size, size);
            this.GreenPoint = new Pixbuf(null, "green_point.png", size, size);
            this.YelllowPoint = new Pixbuf(null, "yellow_point.png", size, size);
            this.RedPoint = new Pixbuf(null, "red_point.png", size, size);
            this.BlackPoint = new Pixbuf(null, "black_point.png", size, size);
        }

        private Gdk.Pixbuf WhitePoint { get; set; }
        private Gdk.Pixbuf GreenPoint    {get; set;}
        private Gdk.Pixbuf YelllowPoint  {get; set;}
        private Gdk.Pixbuf RedPoint      {get; set;}
        private Gdk.Pixbuf BlackPoint    {get; set;}
        private SubstancesCatalog SubstancesCatalog { get; set; }
    }
}
