using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Diagnostics;
using EMDServer.Core.Devices;

namespace EMDServer.Core
{
    class DeviceManager
    {
        #region Class variables
        // ----------------------------------------
        private List<Device> deviceList;
        private List<DeviceConnection> deviceConnections;
        // ----------------------------------------
        #endregion

        #region Public methods
        // ----------------------------------------
        /// <summary>
        /// Create a new instance of the class
        /// </summary>
        public DeviceManager()
        {
            deviceList = new List<Device>();
            deviceConnections = new List<DeviceConnection>();

            //Debug.WriteLine("DEVICEMANAGER - Instantiated!");
        }

        /// <summary>
        /// Adds a new device to the list of known devices
        /// </summary>
        /// <param name="d">Device to add to the list</param>
        public void addDevice(Device d)
        {
            lock (deviceList)
            {
                deviceList.Add(d);                
            }

            //Debug.WriteLine("DEVICEMANAGER - Device added: " + d.DeviceId);
        }

        /// <summary>
        /// Creates a new connection between an input and an 
        /// output device
        /// </summary>
        /// <param name="id1">int id of input device</param>
        /// <param name="id2">int id of output device</param>
        /// <param name="active">bool value which indicates whether or not the connection is active</param>
        public void connectDevices(int devId1, int devId2, bool active)
        {
            lock (deviceConnections)
            {
                deviceConnections.Add(new DeviceConnection(devId1, devId2, active));
            }

            //Debug.WriteLine("DEVICEMANAGER - Devices connected: " + devId1 + " --> " + devId2);
        }

        /// <summary>
        /// Returns the Device with the appropriate id
        /// </summary>
        /// <param name="id">int id of desired Device</param>
        /// <returns>Device with appropriate id</returns>
        public Device getDevice(int id)
        {
            Device result = null;

            lock (deviceList)
            {
                foreach (Device d in deviceList)
                {
                    if (d.DeviceId == id)
                    {
                        result = d;
                        break;
                    }
                }
            }
            //if( result != null)
                //Debug.WriteLine("DEVICEMANAGER - Device returned: " + result.DeviceId);
            
            return result;
        }

        /// <summary>
        /// Returns a list of all output Devices connected
        /// to the input Device with the appropriate id
        /// </summary>
        /// <param name="id">int id of input Device</param>
        /// <returns>List with associated output devices</returns>
        public List<Device> getConnectedDevices(int id)
        {
            List<Device> result = new List<Device>();

            lock (deviceConnections)
            {
                foreach (DeviceConnection dc in deviceConnections)
                {
                    if (dc.DevId1 == id)
                    {
                        result.Add(this.getDevice(dc.DevId2));
                        //Debug.WriteLine("DEVICEMANAGER - Connected Device returned: " + id + " --> " + dc.DevId2);
                    }
                    else if (dc.DevId2 == id)
                    {
                        result.Add(this.getDevice(dc.DevId1));
                        //Debug.WriteLine("DEVICEMANAGER - Connected Device returned: " + id + " --> " + dc.DevId1);
                    }
                }
            }            

            return result;
        }

        /// <summary>
        /// Removes the Device with appropriate id from the 
        /// list of known devices
        /// </summary>
        /// <param name="id">int id of Device to remove</param>
        /// <returns>bool value which indicates whether operation was successful</returns>
        public bool removeDevice(int id)
        {
            bool result = false;

            lock (deviceList)
            {
                foreach (Device d in deviceList)
                {
                    if (d.DeviceId == id)
                    {
                        deviceList.Remove(d);
                        result = true;

                        //Debug.WriteLine("DEVICEMANAGER - Device removed: " + id);
                        
                        break;
                    }
                }
            }

            lock (deviceConnections)
            {
                foreach (DeviceConnection dc in deviceConnections)
                {
                    if (dc.DevId1 == id || dc.DevId2 == id)
                    {
                        deviceConnections.Remove(dc);
                    }
                }
            }

            return result;
        }

        /// <summary>
        /// Clears the whole list of known devices
        /// </summary>
        public void clearDevices()
        {
            lock (deviceList)
            {
                deviceList.Clear();
            }

            //Debug.WriteLine("DEVICEMANAGER - Devices cleared!");
        }

        /// <summary>
        /// Adds a Device on which the dim button has been pressed
        /// to the appropriate list. The value of this Devices
        /// will be incremented --> start dimming
        /// </summary>
        /// <param name="id">int id of the input Device</param>
        public void addButtonPressedDevice(int id)
        {
            Button button = ((Button)getDevice(id));
            if (button != null)
            {
                button.buttonPressed();
                //Debug.WriteLine("DEVICEMANAGER - Button pressed: " + id);
            }
            else
            {
                //Debug.WriteLine("DEVICEMANAGER - Button wasn't present: " + id);
            }
        }

        /// <summary>
        /// Removes a Device on which the dim button has been released
        /// from the list --> stop dimming
        /// </summary>
        /// <param name="id">int id of the input Device</param>
        public void removeButtonPressedDevice(int id)
        {
            Button button = ((Button)getDevice(id));
            if (button != null)
            {
                button.buttonReleased();
                //Debug.WriteLine("DEVICEMANAGER - Button released: " + id);
            }
            else
            {
                //Debug.WriteLine("DEVICEMANAGER - Button wasn't present: " + id);
            }
        }

        /// <summary>
        /// Toggles switch
        /// </summary>
        /// <param name="id">int id of the input Device</param>
        public void ToggleSwitch(int id)
        {
            EMDServer.Core.Devices.Switch button = ((EMDServer.Core.Devices.Switch)getDevice(id));
            if (button != null)
            {
                button.Toggle();
                //Debug.WriteLine("DEVICEMANAGER - Switch toggled: " + id);
            }
            else
            {
                //Debug.WriteLine("DEVICEMANAGER - Switch wasn't present: " + id);
            }
        }
        // ----------------------------------------
        #endregion
    }
}
