// 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 System.Linq;
using Glade;

using Gtk;
using Hiperscan.Common.I18n;
using Hiperscan.Extensions.ApoIdent.Widgets;
using Hiperscan.GtkExtensions.Widgets;
using Hiperscan.Unix;
using Hiperscan.ApoIdentCore.GuiControl;
using Hiperscan.ApoIdentCore.SectionManager.Substance.SubstanceSelection;
using Hiperscan.ApoIdentCommon.ApoConfig.ThirdPartyDataExchange;
using Hiperscan.AnalysisModule.Identification;
using Hiperscan.AnalysisModule;

namespace Hiperscan.Extensions.ApoIdent
{
    public partial class ApoIdentApplication
    {
        [Widget] Gtk.Label substance_section_label = null;

        [Widget] Gtk.Label substance_search_label = null;

        [Obsolete("Do not use this field")]
        [Widget] Gtk.Entry substance_search_entry = null;

        [Obsolete("Do not use this field")]
        [Widget] Gtk.Button substance_classifier_button = null;

        [Obsolete("Do not use this field")]
        [Widget] Gtk.Button substance_info_button = null;

        [Obsolete("Do not use this field")]
        [Widget] Gtk.Button substance_clear_button = null;

        [Obsolete("Do not use this field")]
        [Widget] Gtk.Button substance_data_exchange_button = null;

        [Obsolete("Do not use this field")]
        [Widget] Gtk.Label substance_test_for_output_label = null;

        [Widget] Gtk.Label substance_test_for_label = null;
        [Widget] Gtk.Label substance_latin_label = null;
        [Widget] Gtk.Label substance_latin_output_label = null;
        [Widget] Gtk.Label substance_synonyms_label = null;

        [Widget] Gtk.Label substance_classifier_label = null;
        [Widget] Gtk.Label substance_classifier_output_label = null;
        [Widget] Gtk.EventBox substance_synonyms_output_eventbox = null;
        [Widget] Gtk.Label substance_bak_marking_label = null;
        [Widget] Gtk.Table substance_bak_marking_table = null;

        [Obsolete("Do not use this field")]
        [Widget] Gtk.Label substance_validation_label = null;

        private void UpdateSubstanceSection(UpdateArgs update_arg)
        {
            if (update_arg.Substance.HasFlag(UpdateCategory.Sensitives))
                this.SetSubstanceSensitives();

            if (update_arg.Substance.HasFlag(UpdateCategory.ReloadValues))
                this.ReloadSubstanceSearchEntry();

            if (update_arg.Substance.HasFlag(UpdateCategory.SetValues))
            {
                this.SetSubstanceSearchEntry();
                this.SetSpecimenDataExchangeButton();
                this.SetSubstanceNameOutputLabel();
                this.SetSubstanceValidationLinkLabel();
                this.SetSubstanceLatinOutputLabel();
                this.SetSubstanceSubstanceInfoButton();
                this.SetSubstanceSynonymsLabel();
                this.SetSubstanceClassifierOutputLabel();
                this.SetSubstanceBAKMarking();
                this.SetSubstanceClassifierChangeButton();
            }
        }

        private void SetSubstanceSensitives()
        {
            bool sensitive = this.Control.GlobalStates.QuitRequested == false &&
                                 this.HasVisibleSubstances &&
                              this.Control.GlobalStates.Busy == false &&
                                 this.Control.MeasuringManager.IsReferencing == false;

            this.substance_section_label.Sensitive = sensitive;
            this.substance_search_label.Sensitive = sensitive;
            this.SubstanceSearchEntry.Sensitive = sensitive;
            this.SubstanceDataExchangeButton.Sensitive = sensitive &&
                this.Control.GlobalStates.ConnectionSuccess;

            sensitive &= this.Control.SubstanceManager.IsComplete;

            this.SubstanceClearButton.Sensitive = sensitive;
            this.substance_test_for_label.Sensitive = sensitive;
            this.SubstanceTestForOutputLabel.Sensitive = sensitive;
            this.substance_latin_label.Sensitive = sensitive;
            this.substance_latin_output_label.Sensitive = sensitive;
            this.SubstanceValidationLinklabel.Sensitive = sensitive;
            this.SubstanceInfoButton.Sensitive = sensitive;
            this.substance_synonyms_label.Sensitive = sensitive;
            this.SubstanceSynonymsOutputLabel.Sensitive = sensitive;
            this.substance_classifier_label.Sensitive = sensitive;
            this.substance_classifier_output_label.Sensitive = sensitive;
            this.SubstanceClassifierExchangeButton.Sensitive = sensitive;

            if (sensitive)
                sensitive = this.Control.SubstanceManager.SubstancesCatalog.AnalysisType != AnalysisType.Quantification;

            this.substance_bak_marking_label.Sensitive = sensitive;
            this.SubstanceBAKMarkingWidget.Sensitive = sensitive;
        }

        private void ReloadSubstanceSearchEntry()
        {
            ListStore store = (ListStore)this.SubstanceSearchEntry.GtkEntry.Completion.Model;
            store.Clear();

            if (this.HasVisibleSubstances == false)
                return;

            foreach (SubstanceListAutoCompletionEntry substance_entry in this.Control.SubstanceManager.SubstancesCatalog.AutoCompletionEntries)
            {
                Gdk.Pixbuf pixbuf = this.GuiDesigner.GetSubstancePoint(substance_entry);
                store.AppendValues(pixbuf, substance_entry.SubstanceName);
            }
        }

        private void SetSubstanceSearchEntry()
        {
            this.SubstanceSearchEntry.IsValid = this.Control.SubstanceManager.IsComplete;
            this.SubstanceSearchEntry.GtkEntry.Text = this.Control.SubstanceManager.SubstancesCatalog.SelectedSubstanceName ?? String.Empty;

            IdentSubstance substance = null;
            if (this.Control.SubstanceManager.IsComplete)
                substance = this.Control.SubstanceManager.SubstancesCatalog.Substance;

            this.GuiDesigner.SetSubstanceEntryBg(this.SubstanceSearchEntry, substance);
        }

        private void SetSpecimenDataExchangeButton()
        {
            bool visible =
                    this.Control.ProfileManager.CurrentProfile != null &&
                    this.Control.ProfileManager.CurrentProfile.ExchangeData.IsActivated == true &&
                    CatalogLocale.Language == "de";

            this.SubstanceDataExchangeButton.Visible = visible;

            if (visible == false)
                return;

            switch (this.Control.ProfileManager.CurrentProfile.ExchangeData.ProtocolType)
            {
                case ProtocolType.Lennartz:
                    this.SubstanceDataExchangeButton.GtkButton.TooltipText = Catalog.GetString("Import data from laboratory software 'Dr. Lennartz'");
                    this.GuiDesigner.ChangeButtonIcon(this.SubstanceDataExchangeButton, ApoIdentIcon.DataExchangeLennartz);

                    if (this.Control.SubstanceManager.SubstancesCatalog.SelectionType == SubstanceSelectionType.ThirdParty &&
                        this.Control.ProtocolManager.DataExchangeSuccess == true)
                    {
                        this.GuiDesigner.ChangeButtonIcon(this.SubstanceDataExchangeButton, ApoIdentIcon.DataExchangeLennartzOk);
                    }
                    break;

                default:
                    break;
            }
        }

        private void SetSubstanceNameOutputLabel()
        {
            if (this.Control.SubstanceManager.IsComplete)
                this.SubstanceTestForOutputLabel.Text = this.Control.SubstanceManager.SubstancesCatalog.Classification.Name;
            else
                SubstanceTestForOutputLabel.Text = String.Empty;
        }

        private void SetSubstanceValidationLinkLabel()
        {
            bool is_test_module = false;
            if (this.Control.SubstanceManager.IsComplete)
            {
                if (this.Control.SubstanceManager.SubstancesCatalog.AnalysisType == AnalysisModule.AnalysisType.Identification)
                    is_test_module = this.Control.IdentModuleSettings.TestVersion ?? true;
                else
                    is_test_module = this.Control.QuantifierModuleSettings.TestVersion ?? true;
            }

            this.SubstanceValidationLinklabel.Visible = this.Control.SubstanceManager.IsComplete &&
                this.Control.SubstanceManager.SubstancesCatalog.ModelClass.HasValidationDocument == true &&
                is_test_module == false;
        }

        private void SetSubstanceLatinOutputLabel()
        {
            if (this.Control.SubstanceManager.IsComplete)
            {
                string tmp = this.Control.SubstanceManager.SubstancesCatalog.SelectedLatinName;
                if (String.IsNullOrEmpty(tmp))
                    tmp = IdentSubstance.NOT_AVAILABLE;
                this.substance_latin_output_label.Text = tmp;
            }
            else
            {
                this.substance_latin_output_label.Text = String.Empty;
            }
        }

        private void SetSubstanceSubstanceInfoButton()
        {
            this.SubstanceInfoButton.Visible = this.Control.SubstanceManager.IsComplete &&
                this.Control.SubstanceManager.SubstancesCatalog.IsYellowSubstance;
        }

        private void SetSubstanceSynonymsLabel()
        {
            if (this.Control.SubstanceManager.IsComplete)
            {
                string output_text = String.Join("; ", this.Control.SubstanceManager.SubstancesCatalog.Synonnyms.ToArray());
                string tooltip_text = String.Join("\n   - ", this.Control.SubstanceManager.SubstancesCatalog.Synonnyms.ToArray());
                string header = String.Format(Catalog.GetString("Synonyms for {0}"), this.Control.SubstanceManager.SubstancesCatalog.SelectedSubstanceName);

                if (String.IsNullOrEmpty(output_text))
                    output_text = IdentSubstance.NOT_AVAILABLE;
                else
                    tooltip_text = "   - ";

                this.SubstanceSynonymsOutputLabel.Text = output_text;
                this.SubstanceSynonymsOutputLabel.TooLtipTitle = header;
                this.SubstanceSynonymsOutputLabel.TooltipText = tooltip_text;
            }
            else
            {
                this.SubstanceSynonymsOutputLabel.Text = String.Empty;
                this.SubstanceSynonymsOutputLabel.TooLtipTitle = String.Empty;
                this.SubstanceSynonymsOutputLabel.TooltipText = String.Empty;
            }
        }

        private void SetSubstanceClassifierOutputLabel()
        {
            if (this.HasSubstances == false)
                this.substance_classifier_output_label.Text = Catalog.GetString("No models available.");
            else
                this.substance_classifier_output_label.Text = this.Control.SubstanceManager.SubstancesCatalog?.ModelClass?.Name ?? String.Empty;
        }


        private void SetSubstanceBAKMarking()
        {
            bool is_visible = this.Control.ProfileManager.CurrentProfile != null && this.Control.ProfileManager.CurrentProfile.IsBakMarkingUsable && 
                                  this.Control.ProfileManager.CurrentProfile.BakMarking.IsActive &&
                                  this.Control.GlobalStates.IsOnlyQuantifierModuleAvailable == false;

            this.substance_bak_marking_label.Visible = is_visible;
            this.SubstanceBAKMarkingWidget.Visible = is_visible;

            this.SubstanceBAKMarkingWidget.State = BAKMarkingState.None;

            if (this.Control.SubstanceManager.IsComplete &&
                this.Control.ProfileManager.CurrentProfile != null)
            {
                this.SubstanceBAKMarkingWidget.State = this.Control.ProfileManager.CurrentProfile.BakMarking.CurrentValue;
            }
        }

        private void SetSubstanceClassifierChangeButton()
        {
            this.SubstanceClassifierExchangeButton.Visible = false;

            if (this.Control.SubstanceManager.IsComplete)
                this.SubstanceClassifierExchangeButton.Visible = this.Control.SubstanceManager.SubstancesCatalog.IsPreselectionUnique == false;
        }


        private OutLinedEntry SubstanceSearchEntry { get; set; }
        private LinkLabel SubstanceValidationLinklabel { get; set; }
        private BAKMarkingWidget SubstanceBAKMarkingWidget { get; set; }
        private ApoIdentButton SubstanceClassifierExchangeButton { get; set; }
        private ApoIdentButton SubstanceInfoButton { get; set; }
        private ApoIdentButton SubstanceClearButton { get; set; }
        private ApoIdentButton SubstanceDataExchangeButton { get; set; }
        private FlexLabel SubstanceSynonymsOutputLabel { get; set; }
        private FlexEllipsizeLabel SubstanceTestForOutputLabel { get; set; }
    }
}
