using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Diagnostics;
using EMDServer.Common;
using EMDHardwareClientSimulation.Core.Devices;
using EMDHardwareClientSimulation.Connection.RS232;
using System.Windows.Forms;

namespace EMDHardwareClientSimulation.Core
{
    public class MainController
    {
        #region Class variables
        // ----------------------------------------
        private static MainController mc;

        private iEMDConnection rs232Interface;
        private CommandProcessor cmdProcessor;

        private List<Device> deviceList;
        private frmEMDHWClientSimulation ui;

        public frmEMDHWClientSimulation Ui
        {
            get { return ui; }
            set { ui = value; }
        }
        // ----------------------------------------
        #endregion

        #region Publid methods
        // ----------------------------------------
        public static MainController getInstance()
        {
            if (mc == null)
            {
                mc = new MainController();
            }

            return mc;
        }

        private MainController()
        {
            deviceList = new List<Device>();

            initInterfaces();
            initDevices();            

            cmdProcessor = new CommandProcessor();
            cmdProcessor.setMainController(this);
        }

        public void SendCommand(Command cmd)
        {
            this.rs232Interface.sendCommand(cmd);            
        }

        public Device GetDeviceById(int id)
        {
            Device result = null;

            foreach (Device d in deviceList)
            {
                if (d.DeviceId == id)
                {
                    result = d;
                    break;
                }
            }

            return result;
        }

        public void buttonPressed(int id)
        {
            ((EMDHardwareClientSimulation.Core.Devices.Button)this.GetDeviceById(id)).buttonPressed();
        }

        public void buttonReleased(int id)
        {
            ((EMDHardwareClientSimulation.Core.Devices.Button)this.GetDeviceById(id)).buttonReleased();
        }

        public void toggleSwitch(int id)
        {
            ((EMDHardwareClientSimulation.Core.Devices.Switch)this.GetDeviceById(id)).Toggle();            
        }

        public void Exit()
        {
            this.rs232Interface.closeConnection();
        }
        // ----------------------------------------
        #endregion

        #region Private methods
        // ----------------------------------------
        private void initInterfaces() 
        {
            rs232Interface = new RS232Interface();
            rs232Interface.openConnection();
            rs232Interface.cmdReceived += new EventHandler<CommandHandler>(emdInterface_cmdReceived);
        }

        private void initDevices()
        {
            // Button 1
            deviceList.Add(new EMDHardwareClientSimulation.Core.Devices.Button(110, rs232Interface));
            // Button 2
            deviceList.Add(new EMDHardwareClientSimulation.Core.Devices.Button(111, rs232Interface));
            // Switch
            deviceList.Add(new EMDHardwareClientSimulation.Core.Devices.Switch(112, rs232Interface));
            // Bruno
            deviceList.Add(new EMDHardwareClientSimulation.Core.Devices.Switch(113, rs232Interface));
            deviceList.Add(new Dimmer(10, rs232Interface));
            deviceList.Add(new PowerMeter(11, rs232Interface));
            deviceList.Add(new Dimmer(20, rs232Interface));
            deviceList.Add(new PowerMeter(21, rs232Interface));

            foreach (Device d in deviceList)
            {
                d.setMainController(this);
            }
        }
        // ----------------------------------------
        #endregion

        #region Eventhandler
        // ----------------------------------------
        /// <summary>
        /// Issues an event as soon as a new command message
        /// has been arrived
        /// </summary>
        private void emdInterface_cmdReceived(object sender, CommandHandler cmdHandler)
        {
            cmdProcessor.processCommand(cmdHandler.cmd, (iEMDConnection)sender);
        }
        // ----------------------------------------
        #endregion
    }
}
