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

using Hiperscan.Spectroscopy;
using Hiperscan.Unix;


namespace Hiperscan.Extensions.ApoIdent
{
    public partial class FinderWindow
    {
        private void OnSpecimenEntryChanged(object sender, EventArgs e)
        {
            if (this.IsUpdating == true)
                return;

            this.IsUpdating = true;
            this.SubstanceManagement.SelectNewSubstance(this.substance_search_entry.Text.Trim());
            this.IsUpdating = false;
        }

        private void OnSpecimenEntryFocusOut(object sender, Gtk.FocusOutEventArgs e)
        {
            if (this.IsUpdating == true)
                return;

            this.IsUpdating = true;
            (sender as Entry).Text = this.SubstanceManagement.CurrentSubstance?.SelectedName ?? String.Empty;
            this.IsUpdating = false;
        }

        private void OnModelClassButtonClicked(object sender, EventArgs e)
        {
            if (this.IsUpdating == true)
                return;
            
            this.IsUpdating = true;
            this.SubstanceManagement.SelectNewSubstance(this.substance_search_entry.Text.Trim());
            this.IsUpdating = false;
        }

        private void OnBeforeSubstanceSelectionChanged(object sender, EventArgs e)
        {
            if (this.RemindSave() == false)
            {
                this.IsUpdating = true;
                this.SubstanceManagement.ContinueAction = false;
                this.substance_search_entry.Text = this.SubstanceManagement.CurrentSubstance?.SelectedName ?? String.Empty;
                this.IsUpdating = false;
            }
        }

        private void OnBeforeClassifierSelectionShown(object sender, EventArgs e)
        {
            if (this.IsUpdating == true)
                return;
   
            this.Update(FinderUpdateState.BeforeClassifierSelectionShown);
        }

        private void OnAfterSubstanceSelectionChanged(object sender, EventArgs e)
        {
            if (this.InitState == ServerDeviceState.Success && this.SubstanceManagement.CurrentModelClass.IsFluid == true)
                this.Finder.Current.ResetRecalibrationTimestamp();

            this.no_misidentification_yet                           = true;
            this.CurrentReport                                      = null;
            this.CurrentProcessedSpectrum                           = null;
            this.CreateNotMeasurableReport                          = false;
            this.IdentServerClient.UpdateAuthentificationSet(this.SubstanceManagement);
            this.IdentServerClient.DiscardResult();
            if (this.SubstanceManagement.CurrentModelClass.IsInsertModelClass == true)
                this.Finder.SwitchFinder(ProbeType.FinderInsert);
            else
            this.Finder.SwitchFinder(ProbeType.FinderStandard);


            this.Update(FinderUpdateState.ResetAfterSubstanceChanged);

            if (this.SubstanceManagement.CurrentClassification.IsNirMeasurable == false)
            {
                this.SetNotMeasurableInfo(false, this.SubstanceManagement.IsSubstanceReselected == false);
                this.SubstanceManagement.IsSubstanceReselected = false;
                return;
            }

            if (String.IsNullOrEmpty(this.SubstanceManagement.CurrentSubstance.AdditionalSubstanceInfo) == false)
            {
                if (this.SubstanceManagement.IsSubstanceReselected == false)
                    this.ShowAdditianalInfo(this.SubstanceManagement.CurrentSubstance.AdditionalSubstanceInfo);
            }

            this.SubstanceManagement.IsSubstanceReselected = false;
        }

        private void SetNotMeasurableInfo(bool is_latin_name, bool show_dialog)
        {
            string message = String.Format(Catalog.GetString("You have chosen a substance of the classifier '{0}'. In this mode you can create only a protocol without NIRS-measuring. Please complete the mandatory fields for this substance."),
                                           this.SubstanceManagement.CurrentModelClass.ModelClassName);

            this.CreateNotMeasurableReport  = true;
            this.DetailSectionState.Set(DetailSectionStates.HasResult, this.SubstanceManagement.CurrentSubstance != null);

            if (show_dialog == true)
            {
                MessageDialog mdlg = new MessageDialog(this.finder_window,
                                                       DialogFlags.Modal,
                                                       Gtk.MessageType.Info,
                                                       ButtonsType.Ok,
                                                       message);

                mdlg.IconList = ApoIdentStock.FinderIcons;
                mdlg.Run();
                mdlg.Destroy();
            }


            this.NotMeasurableCreationDate = DateTime.Now;
            this.no_misidentification_yet   = true;
            this.OldBatchNumber            = String.Empty;
            this.Update(FinderUpdateState.SubstanceNotMeasurableChanged);
        }

        private void ShowAdditianalInfo(string message)
        {
            Gtk.MessageDialog mdlg = new Gtk.MessageDialog(this.finder_window,
                                                           Gtk.DialogFlags.Modal,
                                                           Gtk.MessageType.Warning,
                                                           Gtk.ButtonsType.Ok,
                                                           false,
                                                           message);


            mdlg.IconList = ApoIdentStock.FinderIcons;
            mdlg.Run();
            mdlg.Destroy();
        }

        private void OnLoadingSomeModelClassesFailed(object sender, EventArgs e)
        {
            string message = (string) (e as DataEventArgs).Data[DataEventArgs.ERROR];

            this.HideGreetingWindow();
            Gtk.MessageDialog mdlg = new Gtk.MessageDialog(this.finder_window,
                                                           Gtk.DialogFlags.Modal,
                                                           Gtk.MessageType.Warning,
                                                           Gtk.ButtonsType.Ok,
                                                           message);

            mdlg.IconList = ApoIdentStock.FinderIcons;
            mdlg.Run();
            mdlg.Destroy();
            this.host.ProcessEvents();
            this.ShowGreetingWindow();
        }

        private void InitSubstanceManagement()
        {
            this.SubstanceManagement = new SubstanceManagement(this.Config, this.IdentServerClient);
            this.SubstanceManagement.BeforeSubstanceSelectionChanged    += this.OnBeforeSubstanceSelectionChanged;
            this.SubstanceManagement.AfterSubstanceSelectionChanged     += this.OnAfterSubstanceSelectionChanged;
            this.SubstanceManagement.BeginLoadingData                   += this.OnBeginLoadingData;
            this.SubstanceManagement.LoadingDataProgressed              += this.OnLoadingDatatProgressed;
            this.SubstanceManagement.LoadingDataFailed                  += this.OnLoadingDataFailed;
            this.SubstanceManagement.LoadingSomeModelClassesFailed      += this.OnLoadingSomeModelClassesFailed;
            this.SubstanceManagement.BeforeClassifierSelectionShown     += this.OnBeforeClassifierSelectionShown;

            this.SubstanceManagement.Pdfs.LoadingValidationDocuStarted     += this.OnPdfDataChanged;
            this.SubstanceManagement.Pdfs.LoadingValidationDocuFinished    += this.OnPdfDataChanged;
            this.SubstanceManagement.Pdfs.LoadingSubstancuDocuStarted      += this.OnPdfDataChanged;
            this.SubstanceManagement.Pdfs.LoadingSubstanceDocuFinished     += this.OnPdfDataChanged;
            this.SubstanceManagement.Pdfs.LoadingAdditionalTestsStarted    += this.OnPdfDataChanged;
            this.SubstanceManagement.Pdfs.LoadingAdditionalTestsFinished   += this.OnPdfDataChanged;
        }

        public SubstanceManagement SubstanceManagement {get; private set;}
        private Scanner Scanner { get; set; }
    }
}
