using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Timers;

namespace PressureGenerator
{
    public class PressureGeneratorController
    {
        private PressureGeneratorWnd _View = new PressureGeneratorWnd();
        private IPressureGenerator _Model;
        private System.Timers.Timer ConfigTimer;
        
        public DeviceStatus Status;

        public static float GetLastStatic = 0;
        public static float GetLastPitot = 0;

        public enum DeviceStatus
        {
            NotConnected,
            Connecting,
            Connected
        }

        public PressureGeneratorController()
        {
            this._View = new PressureGeneratorWnd();
            this._View.setController(this);
            Status = DeviceStatus.NotConnected;
        }

        public Boolean Configure()
        {
            if (ConfigTimer != null)
                ConfigTimer.Start();
            this._View.ShowDialog();
            if (ConfigTimer != null)
                ConfigTimer.Stop();

            return (Status == DeviceStatus.Connected);
        }

        public void Connect()
        {
                        bool ChamberConnected = false;

            if (Status == DeviceStatus.NotConnected)
            {
                switch (this._View.SelectedGenerator)
                {
                    case 0: // PACE 6000
                        _Model = new PACE6000driver();
                        break;
                }
                Status = DeviceStatus.Connecting;
                _View.UpdateConnectionControls();
                if (_View.IsEthernetSelected) // network
                {
                    IPAddress address;
                    if (IPAddress.TryParse(_View.IpAddress, out address))
                    {
                        if (_View.TcpPort >= 0)
                            ChamberConnected = _Model.Connect(address, _View.TcpPort);
                        else
                        {
                            MessageBox.Show("Incorrect TCP Port", "Pressure generator connection", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                            ChamberConnected = false;
                        }
                    }
                    else
                    {
                        MessageBox.Show("Incorrect IP address format", "Pressure generator connection", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        ChamberConnected = false;
                    }
                }
                else // Serial line
                {
                    ChamberConnected = _Model.Connect(_View.ComPort,
                                   _View.ComBaudrate,
                                   _View.ComDatabits,
                                   _View.ComStopbits,
                                   _View.ComParity);
                }
            }
            else // Disconnect
            {
                //_Model.UpdaterStop();                        // stop updater
                _Model.Stop();                               // stop generator
                _Model.Disconnect();                         // disconnect generator
                Status = DeviceStatus.NotConnected;
                if (ConfigTimer != null)
                {
                    ConfigTimer.Stop();
                    ConfigTimer.Dispose();
                    ConfigTimer = null;
                }
            }

            if (ChamberConnected)
            {
                bool result = false;
                result = _Model.Run();                                  // start generator
                if (result)
                {
                    //_Model.UpdaterStart(TimeSpan.FromSeconds(3)); // start generator
                    Status = DeviceStatus.Connected;
                    ConfigTimer = new System.Timers.Timer(1000);
                    UpdateGeneratorValues();
                    ConfigTimer.Elapsed += new ElapsedEventHandler(PressureGeneratorUpdate);
                    ConfigTimer.Enabled = true;
                }
                else
                {
                    _Model.Disconnect();
                    Status = DeviceStatus.NotConnected;
                }
            }
            else
            {
                Status = DeviceStatus.NotConnected;
            }
            _View.UpdateConnectionControls();
        }

        private void PressureGeneratorUpdate(object sender, ElapsedEventArgs e)
        {
            _Model.ManualUpdate();
            _View.UpdateValues(_Model.GetActStatic(), _Model.GetActPitot());
        }

        private void UpdateGeneratorValues()
        {
            _View.Static = 0;   // _Model.
            _View.Pitot = 0;    // _Model.
        }

        public bool SetPressure(float Static, float Pitot)
        {
            bool _res = false;
            bool _r1 = _Model.SetStatic(Static);
            bool _r2 = _Model.SetPitot(Pitot);
            if (_r1 && _r2)
                _res = true;
            return _res;
        }

        public void Dispose()
        {
            if (_Model != null)
            {
                _Model.Disconnect();
                _Model = null;
            }
            if (ConfigTimer != null)
                ConfigTimer.Dispose();
        }

        public String[] getAvailableCOMs()
        {
            return System.IO.Ports.SerialPort.GetPortNames();
        }

        public DeviceStatus GetStatus { get { return Status; } }

        public bool Run()
        {
            return _Model.Run();
        }

        public bool Stop()
        {
            return _Model.Stop();
        }

        public void ManualUpdate()
        {
            _Model.ManualUpdate();
            GetLastStatic = _Model.GetActStatic();
            GetLastPitot = _Model.GetActPitot();
        }

        public float ActStatic { get { return (_Model.GetActStatic());} }

        public float ActPitot { get { return (_Model.GetActPitot()); } }

        public string Name { get { return (_Model.PressureName); } }

        public void SendCommand(string p)
        {
            _Model.SendCommand(p);
        }
    }
}
