using System;
using System.Windows.Forms;

namespace ClimaChamber
{
    /// <summary>
    /// GUI for connection to specific climatic chamber
    /// </summary>
    public partial class ClimaChamberWnd : Form
    {
        /// <summary>
        /// Controller
        /// </summary>
        private ClimaController _Controller;

        /// <summary>
        /// Constructor. Allocate components
        /// </summary>
        public ClimaChamberWnd()
        {
            InitializeComponent();
            this.ClimaChamberSelectBox.SelectedIndex = 0;
            this.BaudrateList.SelectedItem = "9600";
            this.DatabitsList.SelectedItem = "8";
            this.StopbitsList.SelectedItem = "1";
            this.ParityList.SelectedItem = "None";
        }

        /// <summary>
        /// Set controller
        /// </summary>
        /// <param name="controller">Controller</param>
        public void setController(ClimaController controller)
        {
            this._Controller = controller;
        }

        /// <summary>
        /// Enable ethernet and disable serial port
        /// </summary>
        /// <param name="sender">Sender object</param>
        /// <param name="e">Arguments</param>
        private void EthernetButton_CheckedChanged(object sender, EventArgs e)
        {
            if (this.EthernetButton.Checked == true)
            {
                this.IPaddressBox.Enabled = true;
                this.IPportBox.Enabled = true;

                this.SerialButton.Checked = false;
                this.COMportList.Enabled = false;
                this.BaudrateList.Enabled = false;
                this.DatabitsList.Enabled = false;
                this.StopbitsList.Enabled = false;
                this.ParityList.Enabled = false;
            }
        }
        /// <summary>
        /// Enable serial port and disable ethernet
        /// </summary>
        /// <param name="sender">Sender object</param>
        /// <param name="e">Arguments</param>
        private void SerialButton_CheckedChanged(object sender, EventArgs e)
        {
            if (this.SerialButton.Checked == true)
            {
                this.EthernetButton.Checked = false;
                this.IPaddressBox.Enabled = false;
                this.IPportBox.Enabled = false;

                this.COMportList.Enabled = true;
                this.BaudrateList.Enabled = true;
                this.DatabitsList.Enabled = true;
                this.StopbitsList.Enabled = true;
                this.ParityList.Enabled = true;
            }
        }
        /// <summary>
        /// Connect to device
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ClimaConnectButton_Click(object sender, EventArgs e)
        {
            this._Controller.Connect();
        }

        /// <summary>
        /// Gets index of selected device
        /// </summary>
        public int SelectedChamber
        { get { return (this.ClimaChamberSelectBox.SelectedIndex); } }
        /// <summary>
        /// Gets state of ethernet
        /// </summary>
        public bool IsEthernetSelected
        { get { return (this.EthernetButton.Checked); } }
        /// <summary>
        /// Gets state of serial port
        /// </summary>
        public string IpAddress
        { get { return (this.IPaddressBox.Text); } }
        /// <summary>
        /// Gets port address
        /// </summary>
        public int TcpPort
        { get 
            {
                int portNum;
                if (Int32.TryParse(this.IPportBox.Text, out portNum))
                    return portNum;
                else
                    return -1;
            }
        }
        /// <summary>
        /// Gets COM ports name
        /// </summary>
        public String ComPort
        {
            get { return (this.COMportList.SelectedItem == null ? "None" : this.COMportList.SelectedItem.ToString()); }
        }
        /// <summary>
        /// Gets communication speed
        /// </summary>
        public String ComBaudrate
        {
            get { return (this.BaudrateList.SelectedItem.ToString()); }
        }
        /// <summary>
        /// Gets data length 
        /// </summary>
        public String ComDatabits
        {
            get { return (this.DatabitsList.SelectedItem.ToString()); }
        }
        /// <summary>
        /// Gets number of stop bits
        /// </summary>
        public String ComStopbits
        {
            get { return (this.StopbitsList.SelectedItem.ToString()); }
        }
        /// <summary>
        /// Gets parity for communication
        /// </summary>
        public String ComParity
        {
            get { return (this.ParityList.SelectedItem.ToString()); }
        }
        /// <summary>
        /// Close GUI
        /// </summary>
        /// <param name="sender">Sender object</param>
        /// <param name="e">Arguments</param>
        private void close_btn_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.OK;
        }

        /// <summary>
        /// Update GUI
        /// </summary>
        public void UpdateConnectionControls()
        {
            bool enabled = _Controller.Status == ClimaController.DeviceStatus.NotConnected;
            this.EthernetButton.Enabled = enabled;
            this.IPaddressBox.Enabled = enabled;
            this.IPportBox.Enabled = enabled;

            this.SerialButton.Enabled = enabled;
            this.COMportList.Enabled = enabled;
            this.BaudrateList.Enabled = enabled;
            this.DatabitsList.Enabled = enabled;
            this.StopbitsList.Enabled = enabled;
            this.ParityList.Enabled = enabled;
            switch (_Controller.Status)
            { 
                case ClimaController.DeviceStatus.NotConnected:
                    this.ClimaConnectButton.Enabled = true;
                    this.ClimaConnectButton.Text = "Connect";
                    this.toolStripStatusLabel1.Text = "Disconnected";
                    EnableConfigAndWeather(false);
                    break;
                case ClimaController.DeviceStatus.Connecting:
                    this.ClimaConnectButton.Enabled = false;
                    this.ClimaConnectButton.Text = "Connecting";
                    this.toolStripStatusLabel1.Text = "Connecting...";
                    EnableConfigAndWeather(false);
                    break;
                case ClimaController.DeviceStatus.Connected:
                    this.ClimaConnectButton.Enabled = true;
                    this.ClimaConnectButton.Text = "Disconnect";
                    this.toolStripStatusLabel1.Text = "Connected";
                    EnableConfigAndWeather(true);
                    break;
            }
        }
        /// <summary>
        /// Enable doc kaprt for showing current values
        /// </summary>
        /// <param name="enabled">State</param>
        private void EnableConfigAndWeather(bool enabled)
        {
            this.ClimaConfGroupBox.Enabled = enabled;
            this.WeatherGroupBox.Enabled = enabled;
        }
        /// <summary>
        /// Configure device
        /// </summary>
        /// <param name="sender">Sender object</param>
        /// <param name="e">Agruments</param>
        private void ConfigureBtn_Click(object sender, EventArgs e)
        {
            this._Controller.ConfigureClimaRates();
        }
        /// <summary>
        /// Gets or Sets heating gradient
        /// </summary>
        public float HeatRate
        {
            get
            {
                float rate;
                if (Single.TryParse(this.HeatingTxtBox.Text, out rate))
                    return rate;
                else
                    return 0.0f;
            }
            set
            {
                HeatingTxtBox.Text = String.Format("{0}", value);
            }
        }
        /// <summary>
        /// Gets or Sets cooling gradient
        /// </summary>
        public float CoolRate
        {
            get {
                float rate;
                if (Single.TryParse(this.CoolingTxtBox.Text, out rate))
                    return rate;
                else
                    return 0.0f;
            }
            set {
                CoolingTxtBox.Text = String.Format("{0}", value);
            }
        }
        /// <summary>
        /// Gets or sets humidity gradient
        /// </summary>
        public float HumidRate
        {
            get 
            {
                float rate;
                if (Single.TryParse(this.HumTxtBox.Text, out rate))
                    return rate;
                else
                    return 0.0f;
            }
            set
            {
                HumTxtBox.Text = String.Format("{0}", value);
            }
        }
        /// <summary>
        /// Gets or sets dehumidity gradient
        /// </summary>
        public float DryRate
        {
            get
            {
                float rate;
                if (Single.TryParse(this.DeHumTxtBox.Text, out rate))
                    return rate;
                else
                    return 0.0f;
            }
            set
            {
                DeHumTxtBox.Text = String.Format("{0}", value);
            }
        }
        /// <summary>
        /// Set nominal temperature
        /// </summary>
        public float SetTemperature
        {
            get
            {
                float temp;
                if (Single.TryParse(TemperatureTxt.Text, out temp))
                    return temp;
                else
                    return 0.0f;
            }
            set
            {
                TemperatureTxt.Text = String.Format("{0}", value);
            }
        }
        /// <summary>
        /// Set nominal humidity
        /// </summary>
        public float SetHumidity
        {
            get
            {
                float hum;
                if (Single.TryParse(HumidityTxt.Text, out hum))
                    return hum;
                else
                    return 0.0f;
            }
            set
            {
                HumidityTxt.Text = String.Format("{0}", value);
            }
        }

        /// <summary>
        /// Update GUI with current values
        /// </summary>
        /// <param name="temp">Current temperature</param>
        /// <param name="humidity">Current humidity</param>
        public void UpdateWeather(float temp, float humidity)
        {
            if (CurTempLbl.InvokeRequired)
            {
                CurTempLbl.Invoke(new MethodInvoker(delegate { CurTempLbl.Text = temp.ToString("00.00"); }));
                CurHumLbl.Invoke(new MethodInvoker(delegate { CurHumLbl.Text = humidity.ToString("00.00"); }));
            }
            else
            {
                CurTempLbl.Text = temp.ToString();
                CurHumLbl.Text = humidity.ToString();
            }
        }
        /// <summary>
        /// Clear GUI
        /// </summary>
        /// <param name="sender">Sender object</param>
        /// <param name="e">Arguemnts</param>
        private void ClimaChamberWnd_Load(object sender, EventArgs e)
        {
            this.COMportList.Items.Clear();
            this.COMportList.Items.AddRange(this._Controller.getAvailableCOMs());
        }
        /// <summary>
        /// Set nominal values
        /// </summary>
        /// <param name="sender">Sender object</param>
        /// <param name="e">Arguments</param>
        private void SetConditionsBtn_Click(object sender, EventArgs e)
        {
            iSTP_DebugConsole.DebugConsole.WriteLine("Temperature set point {0}", SetTemperature);
            this._Controller.SetTempHumi(SetTemperature, SetHumidity);
        }
        /// <summary>
        /// Turn on device
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void RunBtn_Click(object sender, EventArgs e)
        {
            this._Controller.Run();
        }
        /// <summary>
        /// Turn of device
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void StopBtn_Click(object sender, EventArgs e)
        {
            this._Controller.Stop();
        }
    }
}
