using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Linq;
using MercatorApi;
using MercatorExtensions;
using MercatorUi;
using MercatorDatabase;
using System.IO.Ports;
using MercatorUi.SelfScan;

// <ReferenceInclude >"System.IO.Ports.dll"</ReferenceInclude>

namespace SelfScan
{
    public class Customizer : MercatorUi.ICustomizers.ISelfScanStarted
    {
        public void SelfScanStarted(MercatorUi.SelfScan.SelfScan selfScan)
        {
            selfScan.Disposing += SelfScan_Disposing;
            string barCodePort = selfScan.ConfigurationManagerAppSettings["BarCodePort"];
            if (!string.IsNullOrEmpty(barCodePort))
                selfScan.BarcodeReader = new DataLogicScan(selfScan, barCodePort);
        }

        private void SelfScan_Disposing(object sender, EventArgs e)
        {
            MercatorUi.SelfScan.SelfScan selfScan = (MercatorUi.SelfScan.SelfScan)sender;
            if (selfScan.BarcodeReader is DataLogicScan dataLogicScan)
                dataLogicScan.Close();
        }
    }

    public class DataLogicScan : BarcodeReader
    {
        private SerialPort serialPort = null;

        public DataLogicScan(MercatorUi.SelfScan.SelfScan selfScan, string barCodePort)
            : base(selfScan)
        {
            try
            {
                serialPort = new SerialPort(barCodePort)
                {
                    BaudRate = 9600,
                    Parity = Parity.None,
                    StopBits = StopBits.One,
                    DataBits = 8
                };
                serialPort.Open();
                if (!serialPort.IsOpen)
                    return;
                if (barCodePort.StartsWith("COM", StringComparison.InvariantCultureIgnoreCase))
                {
                    serialPort.ReadTimeout = 1000;
                    serialPort.WriteTimeout = 1000;
                }
                serialPort.DataReceived += serialPort_DataReceived;
            }
            catch (Exception ex)
            {
                MercatorUi.Globals.ApiLogDelegate("DataLogicScan Init : " + ex.ToString());
            }
            return;
        }

        public void Close()
        {
            if (serialPort != null)
            {
                SetEnabled(false);
                serialPort.Dispose();
                serialPort = null;
            }
        }

        public override void SetEnabled(bool enabled)
        {
            if (serialPort != null)
            {
                byte[] buffer = Api.StringToBytes(enabled ? "E" : "D");
                try { serialPort.Write(buffer, 0, buffer.Length); }
                catch (Exception ex)
                {
                    MercatorUi.Globals.ApiLogDelegate("DataLogicScan SetEnabled : " + ex.ToString());
                }
            }
        }

        private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            string result = "";
            try
            {
                byte[] bb = new Byte[serialPort.BytesToRead];
                int n = serialPort.Read(bb, 0, serialPort.BytesToRead);
                Array.Resize(ref bb, n);
                result = Api.BytesToString(bb);
                OnScanSuccessful(result.Substring(1).TrimEnd());
            }
            catch (Exception ex)
            {
                MercatorUi.Globals.ApiLogDelegate("DataLogicScan DataReceived : " + ex.ToString());
            }
        }
    }
}