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

using Hiperscan.Spectroscopy.IdentModule;
using Hiperscan.Unix;


namespace Hiperscan.Extensions.ApoIdent
{
    public partial class FinderWindow
    {
        [Widget] Gtk.Alignment info_align1 = null;
        [Widget] Gtk.Alignment info_align2 = null;

        [Widget] Gtk.Button user_name_label_button          = null;
        [Widget] Gtk.Button manufacturer_label_button       = null;
        [Widget] Gtk.Button batch_number_button             = null;
        [Widget] Gtk.Button comment_label_button            = null;
        [Widget] Gtk.Button pzn_label_button                = null;
        [Widget] Gtk.Button test_id_label_button            = null;
        [Widget] Gtk.Button init_corr_factor_label_button   = null;

        [Widget] Gtk.LinkButton additional_linkbutton       = null;
        [Widget] Gtk.LinkButton use_by_date_linkbutton      = null;


        [Widget] Gtk.Alignment user_alignment           = null;
        [Widget] Gtk.Alignment supplier_alignment       = null;
        [Widget] Gtk.Alignment pzn_alignment            = null;
        [Widget] Gtk.Alignment batch_alignment          = null;
        [Widget] Gtk.Alignment comment_alignment        = null;
        [Widget] Gtk.Alignment corr_fac_alignment       = null;

        [Widget] Gtk.ComboBox expiry_date_month_combo   = null;
        [Widget] Gtk.ComboBox expiry_date_year_combo    = null;
        [Widget] Gtk.Image expiry_date_image            = null;

        [Widget] Gtk.Label test_id_label                = null;
        [Widget] Gtk.Label additional_label             = null;

        RegexEntry user_regexentry     = null;
        RegexEntry supplier_regexentry = null;
        RegexEntry pzn_regexentry      = null;
        RegexEntry batch_regexentry    = null;
        RegexEntry corr_fac_regexentry = null;
        RegexEntry comment_regentry    = null;

        private void UpdateDetailSection(bool init_report_section, bool update_entries = true)
        {
            bool active = (this.InitState == ServerDeviceState.StartIdentModuleSuccess ||
                            this.InitState == ServerDeviceState.Success) &&
                            this.IdentServerClient.HasValidResult || 
                            this.CreateNotMeasurableReport;

            this.info_align1.Sensitive = active;
            this.info_align2.Sensitive = active;

            this.SetButtonStyle(WindowSections.DetailSection, active);

            if (init_report_section == true)
            {
                this.GtkSupplierValue = String.Empty;
                this.GtkBatchValue = String.Empty;
                this.GtkPznValue = String.Empty;
                this.GtkCorrectionFactorValue = String.Empty;
                this.GtkCommentValue = String.Empty;
                this.expiry_date_year_combo.Active = 0;
                this.expiry_date_month_combo.Active = 0;
                this.Config.Profiles.Current.AdditionalCompletionEntries.Reset();
            }

            this.UpdateUserEntry(active);
            this.UpdateSupplierEntry(active, update_entries);
            this.UpdateBatchEntry(active, update_entries);
            this.UpdatePznEntry(active);
            this.UpdateCorrFacEntry(active);
            this.UpdateExpiryDate(active);
            this.UpdateSubstanceTestLinkButton();

            this.UpdateAdditionalLabel(active);
            this.UpdateTestId(active);

            if (init_report_section)
                this.InitReportSectionState();
        }



        private void UpdateUserEntry(bool active)
        {
            switch(this.SubstanceManagement.ProtocolCompletion)
            {
                case ProtocolAutoCompletionType.ThirdParty:
                    this.user_regexentry.Sensitive = false;
                    string key = this.Config.Profiles.Current.ExchangeData.CurrentDataSetKey;
                    this.GtkUsernameValue = this.Config.Profiles.Current.ExchangeData[key].User;
                    break;

                default:
                    this.user_regexentry.Sensitive = active;
                    break;                    
            }
        }

        private void UpdateSupplierEntry(bool active, bool update)
        {
            switch (this.SubstanceManagement.ProtocolCompletion)
            {
                case ProtocolAutoCompletionType.Scanner:
                    this.GtkSupplierValue = this.Scanner.ScannerInfo.SupplierName ?? String.Empty;
                    this.supplier_regexentry.Sensitive = active;
                    break;

                case ProtocolAutoCompletionType.ThirdParty:                   
                    string key = this.Config.Profiles.Current.ExchangeData.CurrentDataSetKey;
                    this.GtkSupplierValue = this.Config.Profiles.Current.ExchangeData[key].Supplier;
                    this.supplier_regexentry.Sensitive = false;
                    break;

                default:
                    if (this.SubstanceManagement?.CurrentModelClass != null &&
                        String.IsNullOrEmpty(this.SubstanceManagement.CurrentModelClass.DefaultSupplierName) == false &&
                        update == true)
                        this.GtkSupplierValue = this.SubstanceManagement.CurrentModelClass.DefaultSupplierName;
                    this.supplier_regexentry.Sensitive = active;
                    break;
            }

        }

        private void UpdateBatchEntry(bool active, bool update)
        {
            bool is_non_multiple = true;
            if (this.SubstanceManagement == null || this.SubstanceManagement.CurrentClassification == null)
                is_non_multiple = false;
            else
                is_non_multiple = this.SubstanceManagement.CurrentClassification.ClassificationType == ClassificationType.NonMultiple;

            switch (this.SubstanceManagement.ProtocolCompletion)
            {
                case ProtocolAutoCompletionType.Scanner:
                    this.GtkBatchValue = this.Scanner.ScannerInfo.BatchNumber ?? String.Empty;
                    this.batch_regexentry.Sensitive = active;
                    break;

                case ProtocolAutoCompletionType.ThirdParty:                    
                    string key = this.Config.Profiles.Current.ExchangeData.CurrentDataSetKey;
                    this.GtkBatchValue = this.Config.Profiles.Current.ExchangeData[key].BatchNumber;
                    this.batch_regexentry.Sensitive = false;
                    break;

                default:
                    if ((active == true || is_non_multiple) &&
                        String.IsNullOrEmpty(this.SubstanceManagement.CurrentSubstance.SelectedBatchNumber) == false &&
                              update == true)
                              this.GtkBatchValue = this.SubstanceManagement.CurrentSubstance.SelectedBatchNumber;
                    this.batch_regexentry.Sensitive = active;
                    break;
            }
        }

        private void UpdatePznEntry(bool active)
        {
            switch (this.SubstanceManagement.ProtocolCompletion)
            {
                case ProtocolAutoCompletionType.Scanner:
                    this.GtkPznValue = this.Scanner.ScannerInfo.PZN ?? String.Empty;
                    this.pzn_regexentry.Sensitive = active;
                    this.pzn_regexentry.IgnoreTextValidation = false;
                    break;

                case ProtocolAutoCompletionType.ThirdParty:
                    this.pzn_regexentry.IgnoreTextValidation = true;
                    string key = this.Config.Profiles.Current.ExchangeData.CurrentDataSetKey;
                    this.GtkPznValue = this.Config.Profiles.Current.ExchangeData[key].PZN;
                    this.pzn_regexentry.Sensitive = false;
                    break;

                default:
                    this.pzn_regexentry.Sensitive = active;
                    this.pzn_regexentry.IgnoreTextValidation = false;
                    break;
            }
        }

        private void UpdateCorrFacEntry(bool active)
        {
            switch (this.SubstanceManagement.ProtocolCompletion)
            {
                case ProtocolAutoCompletionType.Scanner:                   
                    this.corr_fac_regexentry.IgnoreTextValidation = false;
                    this.GtkCorrectionFactorValue = this.Scanner.ScannerInfo.WeightingCorrection ?? String.Empty;
                    this.corr_fac_regexentry.Sensitive = active;
                    break;

                case ProtocolAutoCompletionType.ThirdParty:
                    this.corr_fac_regexentry.IgnoreTextValidation = true;
                    string key = this.Config.Profiles.Current.ExchangeData.CurrentDataSetKey;
                    this.GtkCorrectionFactorValue = this.Config.Profiles.Current.ExchangeData[key].WeightCorrFactor ?? String.Empty;
                    this.corr_fac_regexentry.Sensitive = false;
                    break;

                default:
                    this.corr_fac_regexentry.IgnoreTextValidation = false;
                    this.corr_fac_regexentry.Sensitive = active;
                    break;
            }
        }

        private void UpdateExpiryDate(bool active)
        {
            string year = null;
            int index = -1;
            ListStore store = (ListStore)this.expiry_date_year_combo.Model;
            int max = store.IterNChildren();
            TreeIter iter;

            switch (this.SubstanceManagement.ProtocolCompletion)
            {
                case ProtocolAutoCompletionType.Scanner:
                    if (this.Scanner.ScannerInfo.ExpirationDate != null)
                    {
                        DateTime tmp_date = Scanner.ScannerInfo.ExpirationDate ?? DateTime.Now;
                        year = tmp_date.ToString("yyyy");                                              

                        for (int i = 0; i < max; i++)
                        {
                            index++;
                            store.IterNthChild(out iter, i);
                            if (year == (string)store.GetValue(iter, 0))
                                break;
                        }
                        this.expiry_date_year_combo.Active = index;
                        this.expiry_date_month_combo.Active = tmp_date.Month;
                    }

                    this.expiry_date_month_combo.Sensitive = active;
                    this.expiry_date_year_combo.Sensitive = active;
                    this.use_by_date_linkbutton.Sensitive = active;

                    break;

                case ProtocolAutoCompletionType.ThirdParty:
                    string key = this.Config.Profiles.Current.ExchangeData.CurrentDataSetKey;
                    if (this.Config.Profiles.Current.ExchangeData[key].TypeOfDate == "Verfallsdatum")
                    {
                        this.use_by_date_linkbutton.Label = Catalog.GetString("Use-by date:");
                        BatchDeadLine.CurrentDeadLineType = BatchDeadLine.DeadLineType.UseByDate;
                    }
                    else
                    {
                        this.use_by_date_linkbutton.Label = Catalog.GetString("Shelf life:");
                        BatchDeadLine.CurrentDeadLineType = BatchDeadLine.DeadLineType.ShelfLife;
                    }

                    year = this.Config.Profiles.Current.ExchangeData[key].ExpiryDate.ToString("yyyy");
                    for (int i = 0; i < max; i++)
                    {
                        index++;
                        store.IterNthChild(out iter, i);
                        if (year == (string)store.GetValue(iter, 0))
                            break;
                    }

                    this.expiry_date_year_combo.Active = index;
                    this.expiry_date_month_combo.Active = this.Config.Profiles.Current.ExchangeData[key].ExpiryDate.Month;
                    this.expiry_date_month_combo.Sensitive = false;
                    this.expiry_date_year_combo.Sensitive = false;
                    this.use_by_date_linkbutton.Sensitive = false;
           

                
                    break;

                default:
                    this.expiry_date_month_combo.Sensitive = active;
                    this.expiry_date_year_combo.Sensitive = active;
                    this.use_by_date_linkbutton.Sensitive = active;
                    break;
            }

            this.expiry_date_image.Visible = this.expiry_date_year_combo.Active == 0 ||
                this.expiry_date_month_combo.Active == 0;
        }

        private void UpdateAdditionalLabel(bool active)
        {
			if (String.IsNullOrEmpty((this.Config.Profiles.Current?.AdditionalCompletionEntries.ProtocolText)) == true)
                this.additional_label.Text = Catalog.GetString("(empty)");
            else
				this.additional_label.Text = this.Config.Profiles.Current.AdditionalCompletionEntries.ProtocolText.Replace("\n", " ");
        }

        private void UpdateTestId(bool active)
        {
            if (active == true)
            {
                this.test_id_label.Markup = "<span size=\"large\">" +
                    this.GetTestId() + "</span>";
            }
            else
            {
                this.test_id_label.Markup = "<span size=\"large\"></span>";
            }
        }

        private void UpdateSubstanceTestLinkButton()
        {
            this.additional_linkbutton.Label = this.GetSubstanceTestType(true);
        }

        public string GetSubstanceTestType(bool with_double_points)
        {
            string test_type = String.Empty;

            if (this.CreateNotMeasurableReport == false)
            {
                if (this.IdentServerClient.HasValidResult == true && this.IdentServerClient.IsTruePositive)
                {
                    if (this.SubstanceManagement.CurrentClassification.ClassificationType == ClassificationType.Multiple)
                        test_type = Catalog.GetString("Complementary tests");
                    else
                        test_type = Catalog.GetString("Additional tests");
                }
                else
                {
                    test_type = Catalog.GetString("Identity tests");
                }
            }
            else
            {
                test_type = Catalog.GetString("Identity tests");
            }

            return test_type + (with_double_points == true ? ":" : String.Empty);
        }

        public string GetTestId()
        {
            DateTime date;

            if (this.SubstanceManagement.CurrentClassification.IsNirMeasurable)
                date = this.CurrentProcessedSpectrum.Timestamp;
            else
                date = this.NotMeasurableCreationDate;

            return (date.Year % 100).ToString() + date.ToString("MMddHHmmss");
        }


        private void SetFocusAfterMeasurement()
        {
            switch (this.SubstanceManagement.ProtocolCompletion)
            {
                case ProtocolAutoCompletionType.ThirdParty:
                    this.comment_regentry.GrabFocus();
                    break;

                default:
                    if (String.IsNullOrEmpty(this.user_regexentry.Entry.Text))
                        this.user_regexentry.Entry.GrabFocus();
                    else
                        this.supplier_regexentry.Entry.GrabFocus();
                    break;
            }           
        }

        private void InitializeEntryCompletion()
        {
            ListStore store = new ListStore(typeof(String));
            foreach (string user in this.Config.GuiSettings.UserCompletion)
            {
                store.AppendValues(user);
            }
            this.user_regexentry.Entry.Completion = new InlineEntryCompletion();
            this.user_regexentry.Entry.Completion.Model = store;
            this.user_regexentry.Entry.Completion.TextColumn = 0;

            store = new ListStore(typeof(String));
            foreach (string supplier in this.Config.GuiSettings.SupplierCompletion)
            {
                store.AppendValues(supplier);
            }
            this.supplier_regexentry.Entry.Completion = new InlineEntryCompletion();
            this.supplier_regexentry.Entry.Completion.Model = store;
            this.supplier_regexentry.Entry.Completion.TextColumn = 0;
        }

        private void UpdateEntryCompletion()
        {
            if (this.Config.GuiSettings.UserCompletion.Contains(this.GtkUsernameValue) == false)
                this.Config.GuiSettings.UserCompletion.Add(this.GtkUsernameValue);

            if (this.Config.GuiSettings.SupplierCompletion.Contains(this.GtkSupplierValue) == false)
                this.Config.GuiSettings.SupplierCompletion.Add(this.GtkSupplierValue);

            this.InitializeEntryCompletion();
        }
    }
}
