// 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 Glade;

using Gtk;

using Hiperscan.Common.I18n;
using Hiperscan.Extensions.ApoIdent.Widgets;
using Hiperscan.GtkExtensions.Widgets;
using Hiperscan.Spectroscopy.IdentModule;
using Hiperscan.Unix;

//TODO Lennartz-ok missing


namespace Hiperscan.Extensions.ApoIdent
{
    public partial class ApoIdentApplication
    {
        [Widget] Gtk.Label big_substance_label = null;
        [Widget] Gtk.Label substance_search_label = null;
        [Widget] Gtk.Label substance_classifier_label = null;
        [Widget] Gtk.Label substance_name_label = null;
        [Widget] Gtk.Label substance_latin_label = null;
        [Widget] Gtk.Label substance_validation_label = null;
        [Widget] Gtk.Label substance_bak_marking_label = null;

        [Widget] Gtk.Label substance_classifier_output_label = null;
        [Widget] Gtk.Label substance_name_output_label = null;
        [Widget] Gtk.Label substance_latin_output_label = null;
        [Widget] Gtk.Label substance_validation_output_label = null;

        [Widget] Gtk.Button substance_data_exchange_button = null;
        [Widget] Gtk.Button substance_classifier_change_button = null;
        [Widget] Gtk.Button substance_info_button = null;

        [Widget] Gtk.HBox substance_bak_marking_hbox = null;
                                                       
        [Widget] Gtk.Entry substance_search_entry = null;


        private void UpdateSubstanceSection(bool reinit_substances, bool activate_substance_search_entry)
        {
            bool section_is_active = this.Control.QuitRequested == false &&
                this.Control.ConnectionSuccess &&
                                         this.Control.Busy == false &&
                                         this.Control.MeasuringProgressState.IsProcessing == false;

            this.big_substance_label.Sensitive = section_is_active;
            this.substance_search_label.Sensitive = section_is_active;
            this.SubstanceSearchEntry.Sensitive = section_is_active;
            this.substance_data_exchange_button.Sensitive = section_is_active;

            section_is_active = section_is_active && this.Control.SubstanceSelected;

            this.substance_classifier_label.Sensitive = section_is_active;
            this.substance_name_label.Sensitive = section_is_active;
            this.substance_latin_label.Sensitive = section_is_active;
            this.substance_validation_label.Sensitive = section_is_active;

            this.substance_classifier_output_label.Sensitive = section_is_active;
            this.substance_name_output_label.Sensitive = section_is_active;
            this.substance_latin_output_label.Sensitive = section_is_active;
            this.substance_bak_marking_label.Sensitive = section_is_active;
            this.substance_validation_output_label.Sensitive = section_is_active;
            this.SubstanceValidationLinklabel.Sensitive = section_is_active;

            this.substance_classifier_change_button.Sensitive = section_is_active;
            this.substance_info_button.Sensitive = section_is_active;

            this.SubstanceBAKMarking.Sensitive = section_is_active;

            if (reinit_substances == true)
                this.ReinitSubstanceSearchEntry();

            this.SetSubstanceSearchEntry();
            this.SetSubstanceSearchEntryColor();

            this.SetSubstanceClassifierOutputLabel();
            this.SetSubstanceNameOutputLabel();
            this.SetSubstanceLatinOutputLabel();
            this.SetSubstanceValidationOutputLabel();
            this.SetBakMarking();

            this.SetSubstanceDataExchangeButton();
            this.SetSubstanceClassifierChangeButton();
            this.SetSubstanceInfoutton();

            this.SetSubstanceButtonStates();

            if (activate_substance_search_entry)
                this.SetFpcusOnSubstanceSearchEntry();
        }

        private void ReinitSubstanceSearchEntry()
        {
            this.substance_search_entry.Text = String.Empty;

            ListStore specimen_store = (ListStore)this.substance_search_entry.Completion.Model;
            specimen_store.Clear();

            if (this.Control.ConnectionSuccess == false)
                return;

            Gtk.Label label = new Gtk.Label();
            int max = 0;

            foreach (SubstanceListAutoCompletionEntry substance_entry in this.SubstanceManagement.AutpCompletionEntries)
            {
                specimen_store.AppendValues(substance_entry.SubstanceCategory, substance_entry.SubstanceName, substance_entry);
                label.Text = substance_entry.SubstanceName;
                int width = label.SizeRequest().Width;
                if (width > max)
                    max = width;
            }

            foreach (string model_class in this.SubstanceManagement.AllModelClassNames)
            {
                label.Text = model_class;
                int width = label.SizeRequest().Width;
                if (width > max)
                    max = width;
            }

            this.substance_search_entry.WidthRequest = max + 60;
        }

        private void SetSubstanceSearchEntry()
        {
            this.substance_search_entry.Text = this.SubstanceManagement?.CurrentSelectedName ?? String.Empty;
        }

        private void SetSubstanceSearchEntryColor()
        {
            switch (SubstanceListAutoCompletionEntry.ConvertToSubstanceCategory(this.SubstanceManagement.CurrentClassification))
            {
                case SubstanceCategory.SingleSubstance:
                    this.substance_search_entry.ModifyBase(StateType.Normal, ApoIdentColors.SEARCH_ENTRY_GREEN_BG);
                    break;

                case SubstanceCategory.Classifiaction:
                    this.substance_search_entry.ModifyBase(StateType.Normal, ApoIdentColors.SEARCH_ENTRY_YELLOW_BG);
                    break;

                case SubstanceCategory.NotMeasurable:
                    this.substance_search_entry.ModifyBase(StateType.Normal, ApoIdentColors.SEARCH_ENTRY_RED_BG);
                    break;

                case SubstanceCategory.UserDefined:
                    this.substance_search_entry.ModifyBase(StateType.Normal, ApoIdentColors.SEARCH_ENTRY_GRAY_BG);
                    break;

                default:
                    this.substance_search_entry.ModifyBase(StateType.Normal, ApoIdentColors.SEARCH_ENTRY_DEFAULT_BG);
                    break;
            }
        }

        private void SetSubstanceClassifierOutputLabel()
        {
            if (this.Control.ConnectionSuccess == false)
                this.substance_classifier_output_label.Text = Catalog.GetString("Models not available.");
            else
                this.substance_classifier_output_label.Text = this.SubstanceManagement.CurrentModelClass?.ModelClassName ?? String.Empty;
        }

        private void SetSubstanceNameOutputLabel()
        {
            this.substance_name_output_label.Text = this.SubstanceManagement.CurrentSelectedDefaultName;
        }

        private void SetSubstanceLatinOutputLabel()
        {
            if (this.Control.SubstanceSelected == false)
            {
                this.substance_latin_output_label.Text = String.Empty;
                return;
            }

            if (String.IsNullOrEmpty(this.SubstanceManagement.CurrentSelectedLatinName))
                this.substance_latin_output_label.Text = LocalizedSubstanceExtensions.NotAvailable;
            else
                this.substance_latin_output_label.Text = this.SubstanceManagement.CurrentSelectedLatinName;
        }



        private void SetSubstanceValidationOutputLabel()
        {
            this.substance_validation_output_label.Text = String.Empty;

            if (this.Control.SubstanceSelected)
            {
                if (this.SubstanceManagement.CurrentModelClass.ValidationDocument == false)
                    this.substance_validation_output_label.Text = Catalog.GetString("Not available");
                else
                    this.substance_validation_output_label.Text = Catalog.GetString("Available");
            }
        }


        private void SetBakMarking()
        {
            this.SubstanceBAKMarking.SetState(BAKMarkingState.None);
            bool visible = false;
            if (this.Config.Profiles.Current != null)
            {
                visible = true;
                visible &= this.Config.Profiles.Current.ReportCountry == Configurations.ReportCountryType.Germany;
                visible &= this.Config.Profiles.Current.ExchangeData.ProtocolType == ProtocolType.ApoIdent;
                visible &= this.Config.Profiles.Current.BAKMarkingActivated;
            }


            this.substance_bak_marking_label.Visible = visible;
            this.SubstanceBAKMarking.Visible = visible;

            if (this.SubstanceManagement.CurrentSubstance != null)
                this.SubstanceBAKMarking.SetState(this.SubstanceManagement.CurrentSubstance.BAKMarkingState);
        }

        private void SetSubstanceDataExchangeButton()
        {
            this.substance_data_exchange_button.Visible = 
                this.Config.Profiles.Current != null &&
                this.Config.Profiles.Current.ExchangeData.IsActivated == true &&
                Locale.Language == "de";

            if (this.substance_data_exchange_button.Visible == false)
                return;

            switch (this.Config.Profiles.Current.ExchangeData.ProtocolType)
            {
                case ProtocolType.Lennartz:
                    this.substance_data_exchange_button.TooltipText = Catalog.GetString("Import data for laboratory program 'Dr. Lennartz'"); ;
                    this.SetButtonIcon(this.substance_data_exchange_button, ApoIdentIcon.DataExchangeLennartz);

                    if (this.SubstanceManagement.ProtocolCompletion == ProtocolAutoCompletionType.ThirdParty
                        && this.Config.Profiles.Current.ExchangeData.ExportSuccess == true)
                    {
                        this.SetButtonIcon(this.substance_data_exchange_button, ApoIdentIcon.DataExchangeLennartzOk);
                    }
                    break;

                default:
                    break;
            }
        }

        private void SetSubstanceClassifierChangeButton()
        {
            this.substance_classifier_change_button.Visible = this.SubstanceManagement.CurrentSubstance != null &&
                this.SubstanceManagement.GetModelClassesBySubstanceName(this.SubstanceManagement.CurrentSelectedName).Count > 1;
        }

        private void SetSubstanceInfoutton()
        {
            SubstanceCategory category = SubstanceListAutoCompletionEntry.ConvertToSubstanceCategory(this.SubstanceManagement.CurrentClassification);
            this.substance_info_button.Visible = category == SubstanceCategory.Classifiaction;
        }

        private void SetSubstanceButtonStates()
        {
            this.SetButtonActiveState(this.substance_data_exchange_button);
            this.SetButtonActiveState(this.substance_info_button);
            this.SetButtonActiveState(this.substance_classifier_change_button);

        }

        private void SetFpcusOnSubstanceSearchEntry()
        {
            if (this.TestUserEntry.IsValid == true)
            {
                if (this.SubstanceSearchEntry.GtkEntry.Text.Length > 0)
                    this.SubstanceSearchEntry.GtkEntry.SelectRegion(0, this.SubstanceSearchEntry.GtkEntry.Text.Length);
                this.SubstanceSearchEntry.GtkEntry.HasFocus = true;
            }
            else
            {
                this.TestUserEntry.GtkEntry.HasFocus = true;
            }
        }

        private LinkLabel SubstanceValidationLinklabel { get; set; }
        private OutLinedRegexEntry SubstanceSearchEntry { get; set; }
        private BAKMarking SubstanceBAKMarking { get; set; }
    }
}
