// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2021 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 System.IO;
using System.Threading.Tasks;
using Hiperscan.Common;
using Hiperscan.SGS;
using Hiperscan.SGS.Benchtop;
using Hiperscan.SGS.Common;

namespace Hiperscan.Extensions.ApoIdent
{
    public partial class CombinedFinder
    {
        public class FinderButtonPolling : Polling
        {
            public event EventHandler FinderButtonPressedHandler = null;

            public FinderButtonPolling(IDevice device, bool hard_ware_supports_button)
            {
                this.PollingTimeIntervall = 500;

                this.ConsoleWriter = Console.Out;
                this.Device = device;


                if (this.Device != null && hard_ware_supports_button)
                    this.CanPolling = true;
            }

            protected override void AfterFinishRunning()
            {
                this.ConsoleActive = false;
                for (int i = 0; i < 5; i++)
                {
                    lock (this.Device)
                    {
                        try
                        {
                            if (this.Device.GetState() != Spectrometer.State.Idle)
                                throw new Exception("Device has no state 'Idle'.");

                            this.Device.WaitForIdle(1000);
                            this.Device.SwitchFinderStatusLED(false);
                            this.ConsoleActive = true;
                            break;
                        }
                        catch (Exception ex)
                        {
                            if (i == 4)
                            {
                                this.ConsoleActive = true;
                                if (this.Device.IsConnected)
                                    Console.WriteLine("Cannot deactivate finder button: {0}", ex);
                            }
                        }
                    }
                }

                Console.WriteLine("FinderButton polling stopped.");
            }

            protected override void BeforeStartRunning()
            {
                Console.WriteLine("FinderButton start polling...");
                this.ConsoleActive = false;

                for (int i = 0; i < 5; i++)
                {
                    lock (this.Device)
                    {
                        try
                        {
                            if (this.Device.GetState() != Spectrometer.State.Idle)
                                throw new Exception("Device has no state 'Idle'.");

                            this.Device.WaitForIdle(1000);
                            this.Device.SwitchFinderStatusLED(true);
                            this.ConsoleActive = true;
                            break;
                        }
                        catch (Exception ex)
                        {
                            if (i == 4)
                            {
                                this.ConsoleActive = true;
                                if (this.Device.IsConnected)
                                    Console.WriteLine("Cannot activate finder button: {0}", ex);
                            }
                        }
                    }
                }

            }

            protected override void ExecutePollingEvent()
            {
                lock (this.Device)
                {

                    try
                    {
                        this.ConsoleActive = false;

                        this.StateNotification = false;

                        if (this.Device.FinderButtonPressed())
                        {
                            this.CycleIsRunning = true;
                            this.FinderButtonPressedHandler(this, EventArgs.Empty);
                        }

                        if (CycleIsRunning == false)
                        {
                            this.ConsoleActive = false;
                            this.StateNotification = true;
                        }

                        this.ConsoleActive = true;
                    }
                    catch(Exception ex)
                    {
                        this.ConsoleActive = true;
                        if (this.Device.IsConnected)
                            Console.WriteLine("Error while activationg finder button: {0}", ex);
                    }
                }
            }

            private bool ConsoleActive
            {
                set
                {
                    if (ApoIdentEnvs.DebugOn)
                        return;

                        if (value == false)
                        Console.SetOut(TextWriter.Null);
                    else
                        Console.SetOut(this.ConsoleWriter);
                }
            }

           
            public bool StateNotification
            {
                set
                {
                    if (this.CanPolling == false)
                        return;

                    try
                    {
                        this.Device.StateNotification = value;
                    }
                    catch(Exception)
                    {

                    }
                }
            }

            private IDevice Device { get; set; } = null;
            private TextWriter ConsoleWriter { get; set; }
        }
    }
}
