// 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.GuiExtensions;

namespace Hiperscan.ApoIdentCore.GuiControl
{
    public class SyncControl : SyncControlTemplate<UpdateArgs, DialogArgs>
    {
        public void EnterInitGUI()
        {
            this.EnterUpdateGui(this.InitialArg);
        }

        public void LeaveInitGUI()
        {
            this.LeaveUpdateGui(this.InitialArg);
            this.WaitForUpdateGuiFinished(this.InitialArg);
        }

        protected override void RunActionByEnter(UpdateArgs args)
        {
            if (this.IsSettingData(args.Pharmacy))
                this.PharmacySectionCounter++;

            if (this.IsSettingData(args.Substance))
                this.SubstanceSectionCounter++;

            if (this.IsSettingData(args.Specimen))
                this.SpecimenSectionCounter++;

            if (this.IsSettingData(args.Result))
                this.ResultSectionCounter++;
        }

        protected override void RunActionByLeave(UpdateArgs args)
        {
            if (this.IsSettingData(args.Pharmacy))
                this.PharmacySectionCounter--;

            if (this.IsSettingData(args.Substance))
                this.SubstanceSectionCounter--;

            if (this.IsSettingData(args.Specimen))
                this.SpecimenSectionCounter--;

            if (this.IsSettingData(args.Result))
                this.ResultSectionCounter--;
        }

        private bool IsSettingData(UpdateCategory update_category)
        {
            if (update_category.HasFlag(UpdateCategory.SetValues))
                return true;

            if (update_category.HasFlag(UpdateCategory.ReloadValues))
                return true;

            if (update_category.HasFlag(UpdateCategory.SpecialCases))
                return true;

            return false;
        }

        public bool IsPharmacySectionUpdating
        {
            get
            {
                lock(this.GuiUpdateAccessSync)
                {
                    return this.PharmacySectionCounter > 0;
                }
            }
        }

        public bool IsSubstanceSectionUpdating
        {
            get
            {
                lock (this.GuiUpdateAccessSync)
                {
                    return this.SubstanceSectionCounter > 0;
                }
            }
        }

        public bool IsSpecimenSectionUpdating
        {
            get
            {
                lock (this.GuiUpdateAccessSync)
                {
                    return this.SpecimenSectionCounter > 0;
                }
            }
        }

        public bool IsResultSectionUpdating
        {
            get
            {
                lock (this.GuiUpdateAccessSync)
                {
                    return this.ResultSectionCounter > 0;
                }
            }
        }

        private long PharmacySectionCounter { get; set; } = 0;
        private long SubstanceSectionCounter { get; set; } = 0;
        private long SpecimenSectionCounter { get; set; } = 0;
        private long ResultSectionCounter { get; set; } = 0;

        private UpdateArgs InitialArg { get; set; } = new UpdateArgs();
        private object GuiUpdateAccessSync { get; set; } = new object();
    }
}
