// 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.SGS;
using Hiperscan.SGS.Common;
using Hiperscan.Unix;


namespace Hiperscan.ApoIdentCore.ComplexFinder
{
    public partial class CombinedFinder
    {
        public event EventHandler DeviceRemoved = null;
        public event EventHandler DeviceReadyStateChanged = null;
        public event EventHandler AverageSet = null;
        public event EventHandler DeviceTypeDetected = null;

        public event Hiperscan.SGS.Benchtop.Finder.WaitForExternalEmptyReferenceHandler WaitForExternalEmptyReference = null;
        public event Hiperscan.SGS.Benchtop.Finder.WaitForExternalWhiteReferenceHandler WaitForExternalWhiteReference = null;
        public event Hiperscan.SGS.Benchtop.Finder.ExternalCalibrationFinishedHandler ExternalCalibrationFinished = null;


        public event Hiperscan.SGS.Benchtop.Finder.InternalCalibrationStarteddHandler InternalCalibrationStarted = null;
        public event Hiperscan.SGS.Benchtop.Finder.InternalCalibrationFinishedHandler InternalCalibrationFinished = null;


        public event EventHandler WarmupStateChanged = null;
        public event EventHandler WarmupQuitRequested = null;

        private void AddDeviceEvents()
        {
            this.Device.StateChanged += this.OnDeviceStateChangedOutPut;
            this.Device.StateChanged += this.OnDeviceStateChangedRemove;
        }

        private void AddFinderEvents()
        {
            if (this.Device == null)
                return;

            if (this.StandardFinder != null)
            {
                this.StandardFinder.WaitForExternalEmptyReference += () => this.WaitForExternalEmptyReference?.Invoke();
                this.StandardFinder.WaitForExternalWhiteReference += () => this.WaitForExternalWhiteReference?.Invoke();
                this.StandardFinder.ExternalCalibrationFinished += (success) => this.ExternalCalibrationFinished(success); ;
                this.StandardFinder.InternalCalibrationStarted += () => this.InternalCalibrationStarted?.Invoke();
                this.StandardFinder.InternalCalibrationFinished += () => this.InternalCalibrationFinished?.Invoke();
            }

            if (this.InsertFinder != null)
            {
                this.InsertFinder.WaitForExternalEmptyReference += () => this.WaitForExternalEmptyReference?.Invoke();
                this.InsertFinder.WaitForExternalWhiteReference += () => this.WaitForExternalWhiteReference?.Invoke();
                this.InsertFinder.ExternalCalibrationFinished += (success) => this.ExternalCalibrationFinished(success);
                this.InsertFinder.InternalCalibrationStarted += () => this.InternalCalibrationStarted?.Invoke();
                this.InsertFinder.InternalCalibrationFinished += () => this.InternalCalibrationFinished?.Invoke();
            }
        }

        private void AddWarmUpEvents()
        {
            if (this.Warmup == null)
                return;

            this.Warmup.WarmupStateChanged += (sender, e) => this.WarmupStateChanged?.Invoke(sender, e);
            this.Warmup.QuitRequested += (sender, e) => this.WarmupQuitRequested?.Invoke(sender, e);
        }

        private void OnDeviceStateChangedRemove(IDevice dev)
        {
            if (this.IsDeviceReady == false)
            {
                this.DeviceRemoved?.Invoke(this, EventArgs.Empty);
            }
        }

        private void OnDeviceStateChangedOutPut(IDevice dev)
        {
            Spectrometer.State state = dev.GetState();
            Console.WriteLine(state);
            switch (state)
            {

                case Spectrometer.State.Disconnected:
                    this.DeviceReadyState = Catalog.GetString("Offline");
                    break;

                case Spectrometer.State.Unknown:
                case Spectrometer.State.Unprogrammed:
                    this.DeviceReadyState = Catalog.GetString("Error");
                    break;

                case Spectrometer.State.ReadConfig:
                case Spectrometer.State.WriteConfig:
                    this.DeviceReadyState = Catalog.GetString("Initialising");
                    break;

            }
        }
    }
}
