// Created with MonoDevelop
//
//    Copyright (C) 2023 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.Spectroscopy;
using Hiperscan.Unix;

namespace Hiperscan.SGS.Benchtop
{
    public partial class Finder
    {
        public const ushort DEFAULT_RECALBRATION_AVERAGING = 500;
        public const ushort DEFAULT_REFERENCING_AVERAGING = 2000;
        public const ushort DEFAULT_STANDARD_SAMPLE_AVERAGING = 500;
        public const ushort DEFAULT_INSERT_SAMPLE_AVERAGING = 2000;

        protected void SetNewAveraging(ushort value)
        {
            if (this.Device != null)
            {
                this.CheckAverage(value);

                this.StoreAveraging();
                Console.WriteLine("Set Finder current device average to: {0}", value);

                if (this.Device.CurrentConfig.Average == value)
                    return;

                this.Device.CurrentConfig.Average = value;
                this.device.WriteConfig();
            }
        }

        protected void StoreAveraging()
        {
            if (this.Device != null)
                this.StoredAveraging = this.device.CurrentConfig.Average;
        }

        protected void RestoreAveraging()
        {
            if (this.Device != null)
            {
                if (this.StoredAveraging == 0)
                    return;

                Console.WriteLine("Restore Finder current device average to: {0}", this.StoredAveraging);
                if (this.Device.CurrentConfig.Average == this.StoredAveraging)
                    return;

                this.Device.CurrentConfig.Average = this.StoredAveraging;
                this.Device.WriteConfig();
            }
        }

        public static ushort GetApoIdentSampleAverage(IDevice device, bool insert)
        {
            ushort average = Finder.DEFAULT_STANDARD_SAMPLE_AVERAGING;

            if (device.Info.ProductId != Hiperscan.SGS.ProductId.APOIDENT_2X_ES20)
            {
                if (insert)
                    average = Finder.DEFAULT_INSERT_SAMPLE_AVERAGING;
            }

            return average;
        }

        protected ushort recalbration_averaging = Finder.DEFAULT_RECALBRATION_AVERAGING;
        public ushort RecalbrationAveraging
        {
            get
            {
                if (this.recalbration_averaging == 0)
                    return this.Device.CurrentConfig.Average;
                else
                    return this.recalbration_averaging;
            }
            set
            {
                this.CheckAverage(value);
                this.recalbration_averaging = value;

                if (this.StandardRecalibrationSet != null)
                    this.StandardRecalibrationSet.Average = value;

                if (this.InsertRecalibrationSet != null)
                    this.InsertRecalibrationSet.Average = value;

                Console.WriteLine("Set Finder recalibration average to: {0}", value);
            }
        }

        protected ushort referencing_averaging = Finder.DEFAULT_REFERENCING_AVERAGING;
        public ushort ReferencingAveraging
        {
            get
            {
                return this.referencing_averaging;
            }
            set
            {
                this.CheckAverage(value);
                this.referencing_averaging = value;

                if (this.StandardReferencingSet != null)
                    this.StandardReferencingSet.Average = value;

                if (this.InsertReferencingSet != null)
                    this.InsertReferencingSet.Average = value;

                //TODO
                //if (this.auto_referencing)
                //    this.ResetReferences();

                Console.WriteLine("Set Finder referencing average to: {0}", value);
            }
        }

        protected ushort standard_sample_averaging = Finder.DEFAULT_STANDARD_SAMPLE_AVERAGING;
        public ushort StandardSampleAveraging
        {
            get
            {
                if (this.standard_sample_averaging == 0)
                    return this.Device.CurrentConfig.Average;
                else
                    return this.standard_sample_averaging;
            }
            set
            {
                this.CheckAverage(value);
                this.standard_sample_averaging = value;

                if (this.StandardSampleSet != null)
                    this.StandardSampleSet.Averaging = value;

                Console.WriteLine("Set Finder standard sample average to: {0}", value);
            }
        }

        protected ushort insert_sample_averaging = Finder.DEFAULT_INSERT_SAMPLE_AVERAGING;
        public ushort InsertSampleAveraging
        {
            get
            {
                if (this.insert_sample_averaging == 0)
                    return this.Device.CurrentConfig.Average;
                else
                    return this.insert_sample_averaging;
            }
            set
            {
                this.CheckAverage(value);
                this.insert_sample_averaging = value;

                if (this.InsertSampleSet != null)
                    this.InsertSampleSet.Averaging = value;

                Console.WriteLine("Set Finder insert sample average to: {0}", value);
            }
        }

        protected void CheckAverage(ushort value)
        {
            if (value < this.Device.MinAverage || value > this.Device.MaxAverage)
                throw new ArgumentException(string.Format(Catalog.GetString("Cannot set replicate count for internal reference  measurement: Value {0} is not supported by the device."), value));
        }

        protected ushort StoredAveraging { get; set; } = 0;
    }
}
