WingMan – Rev 1

Subversion Repositories:
Rev:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using WingMan.Communication;
using WingMan.Host;

namespace WingMan
{
    public partial class Form1 : Form
    {
        private MQTTServer MQTTServer { get; set; } = new MQTTServer();

        private MQTTClient MQTTClient { get; set; } = new MQTTClient();

        private SemaphoreSlim MQTTServerSemaphore {get; set;} =  new SemaphoreSlim(1, 1);

        private SemaphoreSlim MQTTClientSemaphore { get; set; } = new SemaphoreSlim(1, 1);

        public Form1()
        {
            InitializeComponent();
        }

        private void AddressTextBoxClick(object sender, EventArgs e)
        {
            Address.BackColor = Color.Empty;
        }

        private void PortTextBoxClick(object sender, EventArgs e)
        {
            Port.BackColor = Color.Empty;
        }

        private async void HostButtonClickAsync(object sender, EventArgs e)
        {
            // Stop the MQTT server if it is running.
            if (MQTTServer.ServerRunning)
            {
                await StopServer();
                toolStripStatusLabel.Text = Properties.Strings.Server_stopped;
                HostButton.BackColor = Color.Empty;

                ConnectButton.Enabled = true;
                return;
            }

            if (!ValidateAddressPort(out var ipAddress, out var port))
                return;

            // Start the MQTT server.
            await StartServer(ipAddress, port);
            toolStripStatusLabel.Text = Properties.Strings.Server_started;
            HostButton.BackColor = Color.Aquamarine;

            ConnectButton.Enabled = false;
        }

        private bool ValidateAddressPort(out IPAddress address, out int port)
        {
            address = IPAddress.Any;
            port = 0;

            if (string.IsNullOrEmpty(Address.Text) &&
                string.IsNullOrEmpty(Port.Text))
            {
                Address.BackColor = Color.LightPink;
                Port.BackColor = Color.LightPink;
                return false;
            }

            if (!IPAddress.TryParse(Address.Text, out address))
            {
                Address.BackColor = Color.LightPink;
                return false;
            }

            if (!uint.TryParse(Port.Text, out var uPort))
            {
                Port.BackColor = Color.LightPink;
                return false;
            }

            port = (int) uPort;

            Address.BackColor = Color.Empty;
            Port.BackColor = Color.Empty;

            return true;
        }

        private async Task StartServer(IPAddress ipAddress, int port)
        {
            await MQTTServerSemaphore.WaitAsync();
            try
            {
                await MQTTServer.Start(ipAddress, port);
            }
            finally
            {
                MQTTServerSemaphore.Release();
            }
        }

        private async Task StopServer()
        {
            await MQTTServerSemaphore.WaitAsync();
            try
            {
                await MQTTServer.Stop();
            }
            finally
            {
                MQTTServerSemaphore.Release();
            }
        }

        private async void ConnectButtonClickAsync(object sender, EventArgs e)
        {
            if (MQTTClient.ClientRunning)
            {
                await StopClient();
                ConnectButton.Text = Properties.Strings.Connect;
                ConnectButton.BackColor = Color.Empty;

                HostButton.Enabled = true;
                return;
            }

            if (!ValidateAddressPort(out var ipAddress, out var port))
                return;

            await StartClient(ipAddress, port);

            toolStripStatusLabel.Text = Properties.Strings.Client_started;
            ConnectButton.Text = Properties.Strings.Disconnect;
            ConnectButton.BackColor = Color.Aquamarine;

            HostButton.Enabled = false;
        }

        private async Task StopClient()
        {
            await MQTTClientSemaphore.WaitAsync();
            try
            {
                await MQTTClient.Stop();
            }
            finally
            {
                MQTTClientSemaphore.Release();
            }
        }

        private async Task StartClient(IPAddress ipAddress, int port)
        {
            await MQTTClientSemaphore.WaitAsync();
            try
            {
                await MQTTClient.Start(ipAddress, port);
            }
            finally
            {
                MQTTClientSemaphore.Release();
            }
        }
    }
}