using System;
using System.Collections.Generic;
//using System.Linq;
using System.Threading;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;

using Wayne.FDCPOSLibrary;
using Wayne.FDCPOSInterface;

namespace Wayne.OptInterface
{
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IOptInterfaceServer
    {
        [DispId(1)]
        void Add(string workstationID, string applicationSender, int requestId, string deviceType, int iOptId, string overallResult);

        [DispId(2)]
        void Remove(string workstationID, string applicationSender, int requestId, string deviceType, int iOptId, string overallResult);

        [DispId(3)]
        void Write(string workstationID, string applicationSender, int requestId, string deviceType, int iOptId, string overallResult);


        [DispId(30)]
        void DeviceStateChange(string deviceType, int iOptId, int state, int substate);

        [DispId(31)]
        void Read(string deviceType, int iOptId, byte[] message);

    }

    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    [Guid("7535B28E-35FA-41ae-9EFD-B376CDDC988C")]
    public interface IOptInterfaceServerEvents
    {
        [DispId(1)]
        void OnAddSerialPortReq(string workstationID, string applicationSender, int requestId, string deviceType, int iOptId, int port, int baudRate, int dataBit, int stopBit, int parity);

        [DispId(2)]
        void OnAddTCPReq(string workstationID, string applicationSender, int requestId, string deviceType, int iOptId, string address, int port);

        [DispId(3)]
        void OnRemoveReq(string workstationID, string applicationSender, int requestId, string deviceType, int iOptId);

        [DispId(4)]
        void OnWriteReq(string workstationID, string applicationSender, int requestId, string deviceType, int iOptId, byte[] message);
    }


    [Guid("27D28888-3354-4004-8620-BF328BC1BB65")]
    [ClassInterface(ClassInterfaceType.None)]
    [ComVisible(true)]
    [ProgId("OptInterface.OptInterfaceServer")]
    [ComSourceInterfaces(typeof(IOptInterfaceServerEvents))]
    public class OptInterfaceServer : IOptInterfaceServer
    {
        //public static IOptInterfaceServer CreateOptInterface()
        //{
        //    return optInterfaceServer;
        //}

        //public static OptInterfaceServer optInterfaceServer = null;
        private FDCPOSInterfaceServer fdcposInterface;

        public OptInterfaceServer(FDCPOSInterfaceServer _fdcposInterface)
        {
            fdcposInterface = _fdcposInterface;
        }

        public delegate void OnAddSerialPortReqTarget(string workstationID, string applicationSender, int requestID, string deviceType, int deviceId, int port, int baudRate, int dataBit, int stopBit, int parity);
        public delegate void OnAddTCPReqTarget(string workstationID, string applicationSender, int requestID, string deviceType, int deviceId, string address, int port);
        public delegate void OnRemoveReqTarget(string workstationID, string applicationSender, int requestID, string deviceType, int deviceId);
        public delegate void OnWriteReqTarget(string workstationID, string applicationSender, int requestID, string deviceType, int deviceId, byte[] message);

        public event OnAddSerialPortReqTarget OnAddSerialPortReq;
        public event OnAddTCPReqTarget OnAddTCPReq;
        public event OnRemoveReqTarget OnRemoveReq;
        public event OnWriteReqTarget OnWriteReq;


        #region ServiceRequests
        public void AddSerialPortReq(string workstationID, string applicationSender, int requestID, string deviceType, int deviceId, int port, int baudRate, int dataBit, int stopBit, int parity)
        {
            //FDCPOSManager.tracer.WriteLine("init");
            if (OnAddSerialPortReq != null)
            {
                OnAddSerialPortReq(workstationID, applicationSender, requestID, deviceType, deviceId, port, baudRate, dataBit, stopBit, parity);
            }
            //FDCPOSManager.tracer.WriteLine("end");
        }

        public void AddTCPReq(string workstationID, string applicationSender, int requestID, string deviceType, int deviceId, string address, int port)
        {
            //FDCPOSManager.tracer.WriteLine("init");
            if (OnAddTCPReq != null)
            {
                OnAddTCPReq(workstationID, applicationSender, requestID, deviceType, deviceId, address, port);
            }
            //FDCPOSManager.tracer.WriteLine("end");
        }

        public void RemoveReq(string workstationID, string applicationSender, int requestID, string deviceType, int deviceId)
        {
            //FDCPOSManager.tracer.WriteLine("init");
            if (OnRemoveReq != null)
            {
                OnRemoveReq(workstationID, applicationSender, requestID, deviceType, deviceId);
            }
            //FDCPOSManager.tracer.WriteLine("end");
        }

        public void WriteReq(string workstationID, string applicationSender, int requestID, string deviceType, int deviceId, byte[] message)
        {
            //FDCPOSManager.tracer.WriteLine("init");
            if (OnWriteReq != null)
            {
                OnWriteReq(workstationID, applicationSender, requestID, deviceType, deviceId, message);
            }
            //FDCPOSManager.tracer.WriteLine("end");
        }
        #endregion


        #region ServiceResponses
        public void Add(string workstationID, string applicationSender, int requestId, string deviceType, int deviceId, string overallResult)
        {
            fdcposInterface.messages.OptAdd(workstationID, applicationSender, requestId, deviceType, deviceId, overallResult);
        }

        public void Remove(string workstationID, string applicationSender, int requestId, string deviceType, int deviceId, string overallResult)
        {
            fdcposInterface.messages.OptRemove(workstationID, applicationSender, requestId, deviceType, deviceId, overallResult);
        }

        public void Write(string workstationID, string applicationSender, int requestId, string deviceType, int deviceId, string overallResult)
        {
            fdcposInterface.messages.OptWrite(workstationID, applicationSender, requestId, deviceType, deviceId, overallResult);
        }
        #endregion


        #region FDCMessages
        public void DeviceStateChange(string deviceType, int deviceId, int logicalState, int logicalSubState)
        {
            LogicalDeviceState logicalDeviceState = (logicalState == 1) ? LogicalDeviceState.FDC_READY : LogicalDeviceState.FDC_OFFLINE;
            fdcposInterface.messages.DeviceStateChange(deviceType, deviceId, logicalDeviceState, logicalDeviceState, "", "", "", 0, 0, 0, 0);
        }

        public void Read(string deviceType, int deviceId, byte[] message)
        {
            fdcposInterface.messages.OptRead(deviceType, deviceId, message);
        }
        #endregion
    }
}