// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2022, 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 Hiperscan.ApoIdentCore.Enums;
using Hiperscan.ApoIdentCore.GuiControl;
using Hiperscan.ApoIdentCore.SectionManager.Specimen;
using Hiperscan.ApoIdentCore.SectionManager.Specimen.Fields;
using Hiperscan.ApoIdentCore.SectionManager.Substance.SubstanceSelection;
using Hiperscan.ApoIdentCommon.ApoConfig.Cache;
using Hiperscan.ApoIdentCommon.ApoConfig.Enums;

namespace Hiperscan.ApoIdentCore
{
    public partial class AppControl
    {
        private void InitSpecimenManager()
        {
            if (this.SpecimenManager == null)
            {
                this.SpecimenManager = new SpecimenManager(this.ProfileManager, this.GlobalStates);
                this.SpecimenManager.SetValidStateChangedEvents(this.OnSpecimenFieldValidStateChanged);
                this.SpecimenManager.SetValueChangedEvents(this.OnProtocolValueChanged);
                this.SpecimenManager.SetGracePeriodPluralChangedEvent(this.OnSpecimenGracePeriodPluralChanged);
                this.SpecimenManager.CompleteStateChanged += this.OnSpecimenCompleteStateChanged;
            }
        }

        public void SetPpn(string ppn)
        {
            if (this.GuiSyncControl.IsSpecimenSectionUpdating)
                return;

            this.SpecimenManager.PPN.Entry = ppn;
        }

        public void SetProducer(string producer)
        {
            if (this.GuiSyncControl.IsSpecimenSectionUpdating)
                return;

            this.SpecimenManager.Producer.Entry = producer;
        }

        public void SetBatch(string batch)
        {
            if (this.GuiSyncControl.IsSpecimenSectionUpdating)
                return;

            this.SpecimenManager.Batch.Entry = batch;
        }

        public void SetReferenceQuantityValue(string value)
        {
            if (this.GuiSyncControl.IsSpecimenSectionUpdating)
                return;

            ReferenceQuantityEntry tmp = this.SpecimenManager.ReferenceQuantity.GetEntryValue();
            tmp.QuantityValue = value;
            this.SpecimenManager.ReferenceQuantity.Entry = tmp;
        }

        public void SetReferenceQuantityUnit(ReferenceQuantityTypes type)
        {
            if (this.GuiSyncControl.IsSpecimenSectionUpdating)
                return;

            ReferenceQuantityEntry tmp = this.SpecimenManager.ReferenceQuantity.GetEntryValue();
            tmp.QuatityUnit = type;
            this.SpecimenManager.ReferenceQuantity.Entry = tmp;
        }

        public void SetDistributor(string distributor)
        {
            if (this.GuiSyncControl.IsSpecimenSectionUpdating)
                return;

            this.SpecimenManager.Distributor.Entry = distributor;
        }

        public void SetPrice(string price)
        {
            if (this.GuiSyncControl.IsSpecimenSectionUpdating)
                return;

            this.SpecimenManager.Price.Entry = price;
        }

        public void SetExpiryDate(string date)
        {
            if (this.GuiSyncControl.IsSpecimenSectionUpdating)
                return;

            this.SpecimenManager.ExpiryDate.Entry = date;
        }

        public void SetGracePeriodValue(string value)
        {
            if (this.GuiSyncControl.IsSpecimenSectionUpdating)
                return;

            GracePeriodEntry tmp = this.SpecimenManager.GracePeriod.GetEntryValue();
            tmp.QuantityValue = value;

            if (this.SubstanceManager.SubstancesCatalog.SelectionType != SubstanceSelectionType.ThirdParty)
                this.ProfileManager.CurrentProfile.GracePeriod.CurrentValue = tmp;

            this.SpecimenManager.GracePeriod.Entry = tmp;
        }

        public void SetGracePeriodUnit(GracePeriodTypes type)
        {
            if (this.GuiSyncControl.IsSpecimenSectionUpdating)
                return;

            GracePeriodEntry tmp = this.SpecimenManager.GracePeriod.GetEntryValue();
            tmp.QuantityUnit = type;

            if (this.SubstanceManager.SubstancesCatalog.SelectionType != SubstanceSelectionType.ThirdParty)
                this.ProfileManager.CurrentProfile.GracePeriod.CurrentValue = tmp;

            this.SpecimenManager.GracePeriod.Entry = tmp;
        }

        public void SetCorrectionFactor(string factor)
        {
            if (this.GuiSyncControl.IsSpecimenSectionUpdating)
                return;

            this.SpecimenManager.CorrectionFactor.Entry = factor;
        }

        public void SetDeliveryDate(string date)
        {
            if (this.GuiSyncControl.IsSpecimenSectionUpdating)
                return;

            this.SpecimenManager.DeliveryDate.Entry = date;
        }

        public void SetTHC(string thc)
        {
            if (this.GuiSyncControl.IsSpecimenSectionUpdating)
                return;

            this.SpecimenManager.THC.Entry = thc;
        }

        public void SetCBD(string cbd)
        {
            if (this.GuiSyncControl.IsSpecimenSectionUpdating)
                return;

            this.SpecimenManager.CBD.Entry = cbd;
        }

        public void SetVariety(string variety)
        {
            if (this.GuiSyncControl.IsSpecimenSectionUpdating)
                return;

            this.SpecimenManager.Variety.Entry = variety;
        }

        private void OnSpecimenFieldValidStateChanged(object sender, EventArgs e)
        {
            UpdateArgs args = new UpdateArgs();
            args.Specimen = UpdateCategory.ValidStates;
            this.UpdateGuiNeeded?.Invoke(args);
        }

        private void OnSpecimenGracePeriodPluralChanged(object sender, EventArgs e)
        {
            UpdateArgs args = new UpdateArgs();
            args.Specimen = UpdateCategory.SpecialCases;
            this.UpdateGuiNeeded?.Invoke(args);
        }

        private void OnSpecimenCompleteStateChanged(object sender, EventArgs e)
        {
            this.ProtocolManager.AreSpecimenDataComplete = this.SpecimenManager.IsComplete;

            UpdateArgs args = new UpdateArgs();
            args.Protocol = UpdateCategory.Sensitives;
            if (this.ResultManager.AnalysisResultExists)
            {
                if (this.ProtocolManager.IsComplete)
                    args.AnimationType = ProgramState.ReadyForProtocolCreation;
                else
                    args.AnimationType = ProgramState.ReadyForProtocolInput;
            }
            this.UpdateGuiNeeded?.Invoke(args);
        }

        public SpecimenManager SpecimenManager { get; set; }
    }
}
