using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Android.Bluetooth;
using Android.OS;
using Android.Util;
using Java.Lang;
using Java.Util;

namespace FiscalPrinterSDK
{
    public class FiscalCommAndroid : FiscalComm
    {
        private BluetoothSocket com = null;

        public FiscalCommAndroid(BluetoothSocket _socket) : base()
        {
            com = _socket;
        }
        public override void Connect()
        {
            //Close();
            com.Connect();
        }

        //public void Connect(BluetoothSocket socket)
        //{
        //    //Close();
        //    ThreadPool.QueueUserWorkItem(delegate
        //    {
        //com.Connect();
        //    }, null);
        //}

        public override void Close()
        {
            if (com != null)
                com.Close();
            com = null;
        }

        private byte[] readBuf = new byte[1024];

        public override void ClearReceive()
        {

            while (true)
            {
                try
                {
                    //com.getInputStream();
                    if (!com.InputStream.IsDataAvailable())
                        break;
                    com.InputStream.ReadByte();
                    continue;
                }
                catch
                {
                    break;
                }
            }
        }

        public static string HexToString(byte[] data)
        {
            if (data == null)
                return "";
            return HexToString(data, 0, data.Length);
        }
        public static string HexToString(byte[] data, int offset, int length)
        {
            return HexToString(data, offset, length, null, null);
        }
        public static string HexToString(byte[] data, int offset, int length, string byteDelimiter, string bytePrefix)
        {
            return HexToString(data, offset, length, byteDelimiter, bytePrefix, 0);
        }
        public static string HexToString(byte[] data, int offset, int length, string byteDelimiter, string bytePrefix, int splitBytes)
        {
            string HEX = "0123456789ABCDEF";
            int byteSize = 2;
            if (!string.IsNullOrEmpty(byteDelimiter))
                byteSize += byteDelimiter.Length;
            if (!string.IsNullOrEmpty(bytePrefix))
                byteSize += bytePrefix.Length;
            System.Text.StringBuilder sb = new System.Text.StringBuilder(byteSize * length);

            for (int i = 0, split = 0; i < length; i++, split++)
            {
                if (splitBytes != 0 && split == splitBytes)
                {
                    sb.Append(System.Environment.NewLine);
                    split = 0;
                }
                if (!string.IsNullOrEmpty(bytePrefix))
                    sb.Append(bytePrefix);
                sb.Append(HEX[(data[offset + i] >> 4) & 0x0f]);
                sb.Append(HEX[data[offset + i] & 0x0f]);
                if (i < (length - 1) && !string.IsNullOrEmpty(byteDelimiter))
                    sb.Append(byteDelimiter);
            }
            return sb.ToString();
        }

        public override byte[] Read(int maxLength, int timeout)
        {

            int read = 0;
            int len = 0;
            byte[] r = new byte[maxLength];

            int endTime = System.Environment.TickCount + timeout;
            while (read < maxLength)
            {
                if (!com.InputStream.IsDataAvailable())
                {
                    if (System.Environment.TickCount > endTime) throw new TimeoutException();
                    System.Threading.Thread.Sleep(1);
                    continue;
                }
                int toRead = maxLength - read;
                
                len = com.InputStream.Read(readBuf, 0, toRead);
                Array.Copy(readBuf, 0, r, read, len);
                read += len;
            }

            return r;
        }

        public override void Write(byte[] data, uint len, int timeout)
        {
            com.OutputStream.Write(data, 0, (int)len);
        }

    }
}

