using Foundation;
using AsReaderDock4;
using UIKit;

namespace AsReaderDock_VS
{
    public class AsReaderDockManager: NSObject
    {
        public readonly AsReaderNFCDevice nfcDevice;
        public readonly AsReaderRFIDDevice rfidDevice;
        public readonly AsReaderBarcodeDevice barcodeDevice;

        public delegate void Plugged(bool plug);
        public delegate void ReaderConnected(int status);
        public delegate void ResponsePowerOnOff(bool isOn, bool isHWModeChange);
        public delegate void ReleasedTriggerButton();
        public delegate void PushedTriggerButton();
        public delegate void OnAsReaderTriggerKeyEventStatus(string status);
        public delegate void StartedReadScan(int status);
        public delegate void StopReadScan(int status);
        public delegate void AllDataReceived(NSData data);
        public delegate void BatteryReceived(int battery);
        public delegate void ErrorReceived(NSData errorCode);
        public delegate void UnknownCommandReceived(int commandCode);
        public delegate void ReceivedScanData(NSData readData);

        public Plugged plugged;
        public ReaderConnected readerConnected;
        public ResponsePowerOnOff responsePowerOnOff;
        public ReleasedTriggerButton releasedTriggerButton;
        public PushedTriggerButton pushedTriggerButton;
        public OnAsReaderTriggerKeyEventStatus onAsReaderTriggerKeyEventStatus;
        public StartedReadScan startedReadScan;
        public StopReadScan stopReadScan;
        public AllDataReceived allDataReceived;
        public BatteryReceived batteryReceived;
        public ErrorReceived errorReceived;
        public UnknownCommandReceived unknownCommandReceived;
        public ReceivedScanData receivedScanData;

        public delegate void EpcReceived(NSData epc, NSData tid);
        public delegate void PcEpcReceived(NSData pcEpc);
        public delegate void PcEpcRssiReceived(NSData pcEpc, int rssi);
        public delegate void RssiReceived(int rssi);
        public delegate void RssiThresholdReceived(int threshold);
        public delegate void DidSetOutputPowerLevel(int status);
        public delegate void DidSetChannelParamReceived(int statusCode);
        public delegate void DidSetAntiCollision(int status);
        public delegate void DidSetSession(int status);
        public delegate void DidSetBeep(int status);
        public delegate void DidSetStopCondition(int status);
        public delegate void ChannelReceived(int channel, int channelOffset);
        public delegate void AnticolParamReceived(int mode, int counter);
        public delegate void ModulationParamReceived(int blf, int rxMod, int dr);
        public delegate void DidSetModulation(int status);
        public delegate void TxPowerLevelReceived(NSData power);
        public delegate void RegionReceived(int region);
        public delegate void StopConditionsReceived(NSData data);
        public delegate void SelectParamReceived(NSData selParam);
        public delegate void QueryParamReceived(NSData qryParam);
        public delegate void OnOffTimeChanged();
        public delegate void FreqHPTableReceived(int status);
        public delegate void FhLbtReceived(NSData fhLb);
        public delegate void HoppingTableReceived(NSData table);
        public delegate void DidSetFreqHPTable(int status);
        public delegate void DidSetFhLbt(int status);
        public delegate void DidSetOptiFreqHPTable(int status);
        public delegate void DidSetFHmodeChanged();
        public delegate void ResponseGetFHmode();
        public delegate void RfidModuleVersionReceived();
        public delegate void ReaderInfoReceived(NSData data);
        public delegate void RfidOnOffTimeReceived(NSData data);
        public delegate void WrittenReceived(int statusCode);
        public delegate void SessionReceived(int session);
        public delegate void TagMemoryReceived(NSData data);
        public delegate void KilledReceived(int statusCode);
        public delegate void LockedReceived(int statusCode);
        public delegate void RegisteryItemReceived(NSData item);
        public delegate void GenericReceived(NSData data);
        public delegate void ResponseReboot(int status);
        public delegate void UpdatedRegistry(int statusCode);
        public delegate void ResponseFWData(NSData FWData);
        public delegate void RfidDataReceived(NSData data);
        public delegate void ResponseSetLeakage(int status);
        public delegate void PcEpcSensorDataReceived(NSData pcEpc, NSData sensorData, int rssi);

        public EpcReceived epcReceived;
        public PcEpcReceived pcEpcReceived;
        public PcEpcRssiReceived pcEpcRssiReceived;
        public RssiReceived rssiReceived;
        public RssiThresholdReceived rssiThresholdReceived;
        public DidSetOutputPowerLevel didSetOutputPowerLevel;
        public DidSetChannelParamReceived didSetChannelParamReceived;
        public DidSetAntiCollision didSetAntiCollision;
        public DidSetSession didSetSession;
        public DidSetBeep didSetBeep;
        public DidSetStopCondition didSetStopCondition;
        public ChannelReceived channelReceived;
        public AnticolParamReceived anticolParamReceived;
        public ModulationParamReceived modulationParamReceived;
        public DidSetModulation didSetModulation;
        public TxPowerLevelReceived txPowerLevelReceived;
        public RegionReceived regionReceived;
        public StopConditionsReceived stopConditionsReceived;
        public SelectParamReceived selectParamReceived;
        public QueryParamReceived queryParamReceived;
        public OnOffTimeChanged onOffTimeChanged;
        public FreqHPTableReceived freqHPTableReceived;
        public FhLbtReceived fhLbtReceived;
        public HoppingTableReceived hoppingTableReceived;
        public DidSetFreqHPTable didSetFreqHPTable;
        public DidSetFhLbt didSetFhLbt;
        public DidSetOptiFreqHPTable didSetOptiFreqHPTable;
        public DidSetFHmodeChanged didSetFHmodeChanged;
        public ResponseGetFHmode responseGetFHmode;
        public RfidModuleVersionReceived rfidModuleVersionReceived;
        public ReaderInfoReceived readerInfoReceived;
        public RfidOnOffTimeReceived rfidOnOffTimeReceived;
        public WrittenReceived writtenReceived;
        public SessionReceived sessionReceived;
        public TagMemoryReceived tagMemoryReceived;
        public KilledReceived killedReceived;
        public LockedReceived lockedReceived;
        public RegisteryItemReceived registeryItemReceived;
        public GenericReceived genericReceived;
        public ResponseReboot responseReboot;
        public UpdatedRegistry updatedRegistry;
        public ResponseFWData responseFWData;
        public RfidDataReceived rfidDataReceived;
        public ResponseSetLeakage responseSetLeakage;
        public PcEpcSensorDataReceived pcEpcSensorDataReceived;

        public delegate void BarcodeDataReceived(NSData data);
        public delegate void ReceiveFactoryReset(int status);
        public delegate void AckUserCommandReceived(NSData rawData);

        public BarcodeDataReceived barcodeDataReceived;
        public ReceiveFactoryReset receiveFactoryReset;
        public AckUserCommandReceived ackUserCommandReceived;

        public delegate void NfcDataReceived(NSData data);
        public delegate void NfcReadMultiBlockReceived(NSObject[] dataArray, SDK4StatusCode statusCode);
        public delegate void NfcWriteSingleBlockStatusCode(SDK4StatusCode statusCode);
        public delegate void NfcWriteBytesStatusCode(SDK4StatusCode statusCode);

        public NfcDataReceived nfcDataReceived;
        public NfcReadMultiBlockReceived nfcReadMultiBlockReceived;
        public NfcWriteSingleBlockStatusCode nfcWriteSingleBlockStatusCode;
        public NfcWriteBytesStatusCode nfcWriteBytesStatusCode;

        static AsReaderDockManager uniqueInstance;

        static readonly object locker = new object();

        public static AsReaderDockManager sharedInstance()
        {
            if (uniqueInstance == null)
            {
                lock (locker)
                {
                    if (uniqueInstance == null)
                    {
                        uniqueInstance = new AsReaderDockManager();
                    }
                }
            }
            return uniqueInstance;
        }
        public AsReaderDockManager()
        {
            MyAsReaderDeviceDelegate deviceDelegate = new MyAsReaderDeviceDelegate(this);
            MyAsReaderRFIDDeviceDelegate rfidDeviceDelegate = new MyAsReaderRFIDDeviceDelegate(this);
            MyAsreaderBarcodeDeviceDelegate barcodeDeviceDelegate = new MyAsreaderBarcodeDeviceDelegate(this); 
            MyAsReaderNFCDeviceDelegate nfcDeviceDelegate = new MyAsReaderNFCDeviceDelegate(this);

            nfcDevice = (AsReaderNFCDevice)AsReaderNFCDevice.SharedInstance();
            nfcDevice.DelegateDevice = deviceDelegate;
            nfcDevice.DelegateNFC = nfcDeviceDelegate;

            rfidDevice = (AsReaderRFIDDevice)AsReaderRFIDDevice.SharedInstance();
            rfidDevice.DelegateDevice = deviceDelegate;
            rfidDevice.DelegateRFID = rfidDeviceDelegate;

            barcodeDevice = (AsReaderBarcodeDevice)AsReaderBarcodeDevice.SharedInstance();
            barcodeDevice.DelegateDevice = deviceDelegate;
            barcodeDevice.DelegateBarcode = barcodeDeviceDelegate;
        }

        class MyAsReaderDeviceDelegate:AsReaderDeviceDelegate
        {
            readonly AsReaderDockManager dockManager;
            
            public MyAsReaderDeviceDelegate(AsReaderDockManager manager)
            {
                dockManager = manager;
            }
            public override void Plugged(bool plug)
            {
                if (dockManager.plugged != null) dockManager.plugged(plug);
            }
            public override void ReaderConnected(int status)
            {
                if (dockManager.readerConnected != null) dockManager.readerConnected(status);
            }

            public override void ResponsePowerOnOff(bool isOn, bool isHWModeChange)
            {
                if (dockManager.responsePowerOnOff != null) dockManager.responsePowerOnOff(isOn, isHWModeChange);
            }
            public override void ReleasedTriggerButton()
            {
                if (dockManager.releasedTriggerButton != null) dockManager.releasedTriggerButton();
            }
            public override void PushedTriggerButton()
            {
                if (dockManager.pushedTriggerButton != null) dockManager.pushedTriggerButton();
            }
            public override void OnAsReaderTriggerKeyEventStatus(string status)
            {
                if (dockManager.onAsReaderTriggerKeyEventStatus != null) dockManager.onAsReaderTriggerKeyEventStatus(status);
            }
            public override void StartedReadScan(int status)
            {
                if (dockManager.startedReadScan != null) dockManager.startedReadScan(status);
            }
            public override void StopReadScan(int status)
            {
                if (dockManager.stopReadScan != null) dockManager.stopReadScan(status);
            }
            public override void AllDataReceived(NSData data)
            {
                if (dockManager.allDataReceived != null) dockManager.allDataReceived(data);
            }
            public override void BatteryReceived(int battery)
            {
                if (dockManager.batteryReceived != null) dockManager.batteryReceived(battery);
            }
            public override void ErrorReceived(NSData errorCode)
            {
                if (dockManager.errorReceived != null) dockManager.errorReceived(errorCode);
            }
            public override void UnknownCommandReceived(int commandCode)
            {
                if (dockManager.unknownCommandReceived != null) dockManager.unknownCommandReceived(commandCode);
            }
            public override void ReceivedScanData(NSData readData)
            {
                if (dockManager.receivedScanData != null) dockManager.receivedScanData(readData);
            }
            public override void CheckTriggerStatus(string strStatus)
            {
                //throw new System.NotImplementedException();
            }
            

        }

        class MyAsReaderRFIDDeviceDelegate : AsReaderRFIDDeviceDelegate
        {
            readonly AsReaderDockManager dockManager;

            public MyAsReaderRFIDDeviceDelegate(AsReaderDockManager manager)
            {
                dockManager = manager;
            }
            public override void
                EpcReceived(NSData epc, NSData tid)
            {
                if (dockManager.epcReceived != null) dockManager.epcReceived(epc,tid);
            }
            public override void PcEpcReceived(NSData pcEpc)
            {
                if (dockManager.pcEpcReceived != null) dockManager.pcEpcReceived(pcEpc);
            }
            public override void PcEpcRssiReceived(NSData pcEpc, int rssi)
            {
                if (dockManager.pcEpcRssiReceived != null) dockManager.pcEpcRssiReceived(pcEpc,rssi);
            }
            public override void RssiReceived(int rssi)
            {
                if (dockManager.rssiReceived != null) dockManager.rssiReceived(rssi);
            }
            public override void RssiThresholdReceived(int threshold)
            {
                if (dockManager.rssiThresholdReceived != null) dockManager.rssiThresholdReceived(threshold);
            }

            public override void DidSetOutputPowerLevel(int status)
            {
                if (dockManager.didSetOutputPowerLevel != null) dockManager.didSetOutputPowerLevel(status);
            }
            public override void DidSetChannelParamReceived(int statusCode)
            {
                if (dockManager.didSetChannelParamReceived != null) dockManager.didSetChannelParamReceived(statusCode);
            }
            public override void DidSetAntiCollision(int status)
            {
                if (dockManager.didSetAntiCollision != null) dockManager.didSetAntiCollision(status);
            }
            public override void DidSetSession(int status)
            {
                if (dockManager.didSetSession != null) dockManager.didSetSession(status);
            }
            public override void DidSetBeep(int status)
            {
                if (dockManager.didSetBeep != null) dockManager.didSetBeep(status);
            }
            public override void DidSetStopCondition(int status)
            {
                if (dockManager.didSetStopCondition != null) dockManager.didSetStopCondition(status);
            }
            public override void ChannelReceived(int channel, int channelOffset)
            {
                if (dockManager.channelReceived != null) dockManager.channelReceived(channel,channelOffset);
            }
            public override void AnticolParamReceived(int mode, int counter)
            {
                if (dockManager.anticolParamReceived != null) dockManager.anticolParamReceived(mode,counter);
            }
            public override void ModulationParamReceived(int blf, int rxMod, int dr)
            {
                if (dockManager.modulationParamReceived != null) dockManager.modulationParamReceived(blf, rxMod, dr);
            }
            public override void DidSetModulation(int status)
            {
                if (dockManager.didSetModulation != null) dockManager.didSetModulation(status);
            }
            public override void TxPowerLevelReceived(NSData power)
            {
                if (dockManager.txPowerLevelReceived != null) dockManager.txPowerLevelReceived(power);
            }
            public override void RegionReceived(int region)
            {
                if (dockManager.regionReceived != null) dockManager.regionReceived(region);
            }
            public override void StopConditionsReceived(NSData data)
            {
                if (dockManager.stopConditionsReceived != null) dockManager.stopConditionsReceived(data);
                }
            public override void SelectParamReceived(NSData selParam)
            {
                if (dockManager.selectParamReceived != null) dockManager.selectParamReceived(selParam);
            }
            public override void QueryParamReceived(NSData qryParam)
            {
                if (dockManager.queryParamReceived != null) dockManager.queryParamReceived(qryParam);
            }
            public override void OnOffTimeChanged()
            {
                if (dockManager.onOffTimeChanged != null) dockManager.onOffTimeChanged();
            }
            public override void FreqHPTableReceived(int status)
            {
                if (dockManager.freqHPTableReceived != null) dockManager.freqHPTableReceived(status);
            }
            public override void FhLbtReceived(NSData fhLb)
            {
                if (dockManager.fhLbtReceived != null) dockManager.fhLbtReceived(fhLb);
            }
            public override void HoppingTableReceived(NSData table)
            {
                if (dockManager.hoppingTableReceived != null) dockManager.hoppingTableReceived(table);
            }
            public override void DidSetFreqHPTable(int status)
            {
                if (dockManager.didSetFreqHPTable != null) dockManager.didSetFreqHPTable(status);
            }
            public override void DidSetFhLbt(int status)
            {
                if (dockManager.didSetFhLbt != null) dockManager.didSetFhLbt(status);
            }
            public override void DidSetOptiFreqHPTable(int status)
            {
                if (dockManager.didSetOptiFreqHPTable != null) dockManager.didSetOptiFreqHPTable(status);
            }
            public override void DidSetFHmodeChanged()
            {
                if (dockManager.didSetFHmodeChanged != null) dockManager.didSetFHmodeChanged();
            }
            public override void ResponseGetFHmode()
            {
                if (dockManager.responseGetFHmode != null) dockManager.responseGetFHmode();
            }
            public override void RfidModuleVersionReceived()
            {
                if (dockManager.rfidModuleVersionReceived != null) dockManager.rfidModuleVersionReceived();
            }
            public override void ReaderInfoReceived(NSData data)
            {
                if (dockManager.readerInfoReceived != null) dockManager.readerInfoReceived(data);
            }
            public override void RfidOnOffTimeReceived(NSData data)
            {
                if (dockManager.rfidOnOffTimeReceived != null) dockManager.rfidOnOffTimeReceived(data);
            }
            public override void WrittenReceived(int statusCode)
            {
                if (dockManager.writtenReceived != null) dockManager.writtenReceived(statusCode);
            }
            public override void SessionReceived(int session)
            {
                if (dockManager.sessionReceived != null) dockManager.sessionReceived(session);
            }
            public override void TagMemoryReceived(NSData data)
            {
                if (dockManager.tagMemoryReceived != null) dockManager.tagMemoryReceived(data);
            }
            public override void KilledReceived(int statusCode)
            {
                if (dockManager.killedReceived != null) dockManager.killedReceived(statusCode);
            }
            public override void LockedReceived(int statusCode)
            {
                if (dockManager.lockedReceived != null) dockManager.lockedReceived(statusCode);
            }
            public override void RegisteryItemReceived(NSData item)
            {
                if (dockManager.registeryItemReceived != null) dockManager.registeryItemReceived(item);
            }
            public override void GenericReceived(NSData data)
            {
                if (dockManager.genericReceived != null) dockManager.genericReceived(data);
            }
            public override void ResponseReboot(int status)
            {
                if (dockManager.responseReboot != null) dockManager.responseReboot(status);
            }
            public override void UpdatedRegistry(int statusCode)
            {
                if (dockManager.updatedRegistry != null) dockManager.updatedRegistry(statusCode);
            }
            public override void ResponseFWData(NSData FWData)
            {
                if (dockManager.responseFWData != null) dockManager.responseFWData(FWData);
            }
            public override void RfidDataReceived(NSData data)
            {
                if (dockManager.rfidDataReceived != null) dockManager.rfidDataReceived(data);
            }
            public override void ResponseSetLeakage(int status)
            {
                if (dockManager.responseSetLeakage != null) dockManager.responseSetLeakage(status);
            }
            public override void PcEpcSensorDataReceived(NSData pcEpc, NSData sensorData, int rssi)
            {
                if (dockManager.pcEpcSensorDataReceived != null) dockManager.pcEpcSensorDataReceived(pcEpc, sensorData, rssi);
            }
        }
        class MyAsreaderBarcodeDeviceDelegate:AsreaderBarcodeDeviceDelegate
        {
            readonly AsReaderDockManager dockManager;

            public MyAsreaderBarcodeDeviceDelegate(AsReaderDockManager manager)
            {
                dockManager = manager;
            }
            public override void BarcodeDataReceived(NSData data)
            {
                if (dockManager.barcodeDataReceived != null) dockManager.barcodeDataReceived(data);
            }
            public override void ReceiveFactoryReset(int status)
            {
                if (dockManager.receiveFactoryReset != null) dockManager.receiveFactoryReset(status);
            }
            public override void AckUserCommandReceived(NSData rawData)
            {
                if (dockManager.ackUserCommandReceived != null) dockManager.ackUserCommandReceived(rawData);
            }
        }
        class MyAsReaderNFCDeviceDelegate:AsReaderNFCDeviceDelegate
        {
            readonly AsReaderDockManager dockManager;

            public MyAsReaderNFCDeviceDelegate(AsReaderDockManager manager)
            {
                dockManager = manager;
            }
            public override void NfcDataReceived(NSData data)
            {
                if (dockManager.nfcDataReceived != null) dockManager.nfcDataReceived(data);
            }
            public override void NfcReadMultiBlockReceived(NSObject[] dataArray, SDK4StatusCode statusCode)
            {
                if (dockManager.nfcReadMultiBlockReceived != null) dockManager.nfcReadMultiBlockReceived(dataArray, statusCode);
            }
            public override void NfcWriteSingleBlockStatusCode(SDK4StatusCode statusCode)
            {
                if (dockManager.nfcWriteSingleBlockStatusCode != null) dockManager.nfcWriteSingleBlockStatusCode(statusCode);
            }
            public override void NfcWriteBytesStatusCode(SDK4StatusCode statusCode)
            {
                if (dockManager.nfcWriteBytesStatusCode != null) dockManager.nfcWriteBytesStatusCode(statusCode);
            }
        }
    }
}
