// UnifiedPOSのイベントを表すメソッドの引数がCamelケースではなくPascalケースになっていますが、
// これはWSDLでの命名を踏襲しているからです。
// 新たに追加したものは、MSDNのクラスライブラリ開発のデザインガイドに従います。
// privateなフィールドに関しては上記デザインガイドに記述がないですが、
// パラメータやauto変数との区別を目的に、"_"をプレフィクスしたcamelケースを用います。
// このコードはサンプルです。
// シングルトンで動作させるように宣言されているため、staticメソッドで、デリゲートを伝播させます。

using System;
using System.Collections.Generic;
using System.ServiceModel;

//サンプルコードでは、個々のクラスがどの名前空間・アセンブリに
//属しているのか表現するため、あえてusingは使用しない。
//using UnifiedPOS.ScannerEvents;

namespace Console_ScannerConsumerBiDirectionSample
{
    [ServiceBehavior(Namespace = "http://www.nrf-arts.org/UnifiedPOS/ScannerEvents/", InstanceContextMode = InstanceContextMode.Single)]
    public class ScannerEventService : UnifiedPOS.ScannerEvents.V1_4.ScannerEvent
    {
        Dictionary<int, string> StatusConvertToString = new Dictionary<int, string>()
            {
                { UnifiedPOS.ScannerEvents.V1_4.Status.SUE_POWER_OFF, "PowerOff" },
                { UnifiedPOS.ScannerEvents.V1_4.Status.SUE_POWER_OFFLINE, "PowerOffline" },
                { UnifiedPOS.ScannerEvents.V1_4.Status.SUE_POWER_OFF_OFFLINE, "PowerOffOffline" },
                { UnifiedPOS.ScannerEvents.V1_4.Status.SUE_POWER_ONLINE, "PowerOnline" },
                { UnifiedPOS.ScannerEvents.V1_4.Status.SUE_UF_COMPLETE, "UpdateFirmwareComplete" },
                { UnifiedPOS.ScannerEvents.V1_4.Status.SUE_UF_COMPLETE_DEV_NOT_RESTORED, "UpdateFirmwareCompleteDeviceNotRestored" },
                { UnifiedPOS.ScannerEvents.V1_4.Status.SUE_UF_FAILED_DEV_NEEDS_FIRMWARE, "UpdateFirmwareFailedDeviceNeedsFirmware" },
                { UnifiedPOS.ScannerEvents.V1_4.Status.SUE_UF_FAILED_DEV_OK, "UpdateFirmwareFailedDeviceOk" },
                { UnifiedPOS.ScannerEvents.V1_4.Status.SUE_UF_FAILED_DEV_UNKNOWN, "UpdateFirmwareFailedDeviceUnknown" },
                { UnifiedPOS.ScannerEvents.V1_4.Status.SUE_UF_FAILED_DEV_UNRECOVERABLE, "UpdateFirmwareFailedDeviceUnrecoverable" },
                { UnifiedPOS.ScannerEvents.V1_4.Status.SUE_UF_PROGRESS, "UpdateFirmwareProgress" },
            };

        public delegate void DataEventHandler(string ConsumerID, string Source, int EventID, DateTime TimeStamp, int Status);


        static DataEventHandler dataEventHandler;
        public static void SetDataEventHandler(DataEventHandler handler)
        {
            dataEventHandler = handler;
        }


        public void DataEvent(string ConsumerID, string Source, int EventID, DateTime TimeStamp, int Status)
        {
            Console.WriteLine("{0}, {1}, BiDirectional:DataEvent, {2}", EventID, TimeStamp, Status);
            if (dataEventHandler != null) dataEventHandler(ConsumerID, Source, EventID, TimeStamp, Status);
        }

        public UnifiedPOS.ScannerEvents.V1_4.DirectIOData DirectIOEvent(string ConsumerID, string Source, int EventID, DateTime TimeStamp, int EventNumber, int Data, object Obj)
        {
            Console.WriteLine("{0}, {1}, DirectIOEvent, {2}, {3}, {4}", EventID, TimeStamp, EventNumber, Data, Obj);
            return new UnifiedPOS.ScannerEvents.V1_4.DirectIOData();
        }

        public UnifiedPOS.ScannerEvents.V1_4.ErrorResponse ErrorEvent(string ConsumerID, string Source, int EventID, DateTime TimeStamp, UnifiedPOS.ScannerEvents.V1_4.ErrorCode ErrorCode, int ErrorCodeExtended, UnifiedPOS.ScannerEvents.V1_4.ErrorLocus ErrorLocus, UnifiedPOS.ScannerEvents.V1_4.ErrorResponse ErrorResponse)
        {
            Console.WriteLine("{0}, {1}, ErrorEvent, {2}, {3}, {4}, {5}", EventID, TimeStamp, ErrorCode, ErrorCodeExtended, ErrorLocus, ErrorResponse);
            return UnifiedPOS.ScannerEvents.V1_4.ErrorResponse.ER_CLEAR;
        }

        public void StatusUpdateEvent(string ConsumerID, string Source, int EventID, DateTime TimeStamp, int Status)
        {
            int p = UnifiedPOS.ScannerEvents.V1_4.Status.SUE_UF_PROGRESS;
            Console.WriteLine("{0}, {1}, StatusUpdateEvent, {2}", EventID, TimeStamp, (Status > p && Status < p + 100) ? StatusConvertToString[p] + " + " + (Status - p) : StatusConvertToString[Status]);
        }

        public UnifiedPOS.ScannerEvents.V1_4.DataContainedEventData DataContainedEvent(string ConsumerID, string Source, int EventID, DateTime TimeStamp, int Status, UnifiedPOS.ScannerEvents.V1_4.ParameterList Parameters)
        {
            Console.WriteLine("{0}, {1}, BiDirectional:DataContainedEvent, {2}", EventID, TimeStamp, Status);

            UnifiedPOS.ScannerEvents.V1_4.DataContainedEventData data = new UnifiedPOS.ScannerEvents.V1_4.DataContainedEventData();
            data.EventID = EventID;
            data.CallClearInputProperties = true;
            data.SetDataEventEnabled = true;

            return data;
        }
    }
}
