using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RogerMfReaderExample.RUD3;
using RogerMfReaderExample;
using Microsoft.Win32.SafeHandles; 

namespace RogerMfReaderExample.RUD3
{
    class UsbReader
    {
        private static UInt32 readTimeOut = 1000;
        private static UInt32 writeTimeOut = 100;
        private static Boolean Connect;
        private static IntPtr Handle = new IntPtr();
        private static UInt32 returnLibrary;
        private rud3 ter = new rud3();

        public UsbReader()
        {
            Connect = false;
            Handle = IntPtr.Zero;
            returnLibrary = rud3.RUD3_OK;
        }

        //Check if connect
        public Boolean IsConnect
        {
            get
            {
                if ((Connect = true) && (Handle != IntPtr.Zero))
                    return true;
                else
                    return false;
            }
        }
        //Version
        public String getLibraryVersion()
        {
            StringBuilder libraryVer = new StringBuilder(64);

            try
            {
                returnLibrary = rud3.rud3LibVer(libraryVer, libraryVer.MaxCapacity);

                if (returnLibrary != rud3.RUD3_OK)
                    return String.Empty;
                else
                    return libraryVer.ToString();

            }
            catch (Exception e)
            {
                message(e.Message);
                return String.Empty;
            }
            finally
            {
                message();
            }
        }

        //Search for all devices return serian numbers
        public List<String[]> getDevices()
        {
            UInt32 deviceCount = 0;
            List<String[]> allRud3 = new List<String[]>();
            StringBuilder serialNr = new StringBuilder(126);
            StringBuilder description = new StringBuilder(126);
            StringBuilder port = new StringBuilder(126);

            try
            {
                returnLibrary = rud3.rud3GetDeviceCount(ref deviceCount);       //Search all RUD3

                if (returnLibrary == rud3.RUD3_OK)
                {
                    for (UInt32 i = 0; i < deviceCount; i++)
                    {
                        serialNr.Clear();
                        description.Clear();
                        port.Clear();

                        returnLibrary = rud3.rud3GetSerialNumber(i, serialNr);                              //Get serial Number

                        if(returnLibrary == rud3.RUD3_OK)
                        {
                            returnLibrary = rud3.rud3GetDescriptionBySerialNumber(serialNr, description);   //Get decription

                            if (returnLibrary == rud3.RUD3_OK)
                            {
                                returnLibrary = rud3.rud3GetPort(serialNr, port);                           //Get port
                            }

                        }

                        if (returnLibrary == rud3.RUD3_OK)
                        {   
                            //Add to list
                            String[] data = new String[] { serialNr.ToString(), description.ToString(), port.ToString() };
                            allRud3.Add(data);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                message(e.Message);
                
            }
            finally 
            {
               message();
                
            }

            return allRud3;
        }

        //Connect to device
        public Boolean connect(String serialNumber)
        {
            StringBuilder serialNr = new StringBuilder(serialNumber);
            
            try
            {
                returnLibrary = rud3.rud3Open(ref Handle, serialNr);
               
                if (returnLibrary == rud3.RUD3_OK)
                    Connect = true;
                else
                    Connect = false;
                
            }
            catch (Exception e)
            {
                Connect = false; 
                message(e.Message);
                
            }
            finally
            {
                message();

            }

            return Connect;
        }

        //Disconnect
        public Boolean disconnect()
        {
            try
            {
                returnLibrary = rud3.rud3Close(ref Handle);

                if (returnLibrary == rud3.RUD3_OK)
                {
                    Connect = false;
                    Handle = IntPtr.Zero;
                }
             

            }
            catch (Exception e)
            {
                Connect = false;
                message(e.Message);

            }
            finally
            { 
                message();
               
            }

            return !Connect;
        }

        //Read
        public String read(  )
        {
            StringBuilder readBuf = new StringBuilder(64);
            UInt32 readedData = 0;
           
            try
            {
                returnLibrary = rud3.rud3Read(ref Handle, readBuf, 64, out readedData, readTimeOut);

                if (returnLibrary == rud3.RUD3_OK)
                {
                    readBuf.Length = (Int32)readedData;
                }
                   
            }
            catch (Exception e)
            {
                Connect = false;
                message(e.Message);

            }
            finally
            {
                message();
               
            }

            return readBuf.ToString();
        }

        //Write
        public Boolean write(String data)
        {
            Boolean readReturn = false;
            UInt32 writeData;

            try
            {
                returnLibrary = rud3.rud3Write(ref Handle, data, (UInt32)data.Length, out writeData, writeTimeOut);

                if (returnLibrary == rud3.RUD3_OK)
                    readReturn = true;
                else
                    readReturn = false;
            }
            catch (Exception e)
            {
                Connect = false;
                message(e.Message);

            }
            finally
            {
                message();

            }

            return readReturn;
        }

        //Message convert
        private void message()
        {
            switch (returnLibrary)
            {
                case rud3.RUD3_ERROR:
                    InfoBuffer.error("RogerRUD3 - library  function return error");
                    break;

                case rud3.RUD3_DEVICE_NOT_FOUND:
                    InfoBuffer.error("Rud-3 devices not found");
                    break;

                case rud3.RUD3_DEVICE_CANNOT_OPEN:
                    InfoBuffer.error("Rud-3 cann't open comunication chanel");
                    break;

                case rud3.RUD3_INVALID_BUFFER_SIZE:
                    InfoBuffer.error("Rud-3 invalid buffer size");
                    break;

                case rud3.RUD3_EPSO_ERROR:                          //Don't exist
                    InfoBuffer.error("Rud-3 epso error");
                    break;

                case rud3.RUD3_USB_HID_ERROR:                          
                    InfoBuffer.error("Rud-3 library usb hib error");
                    break;

                case rud3.RUD3_TIMEOUT:
                    InfoBuffer.error("Rud-3 TimeOut");
                    break;

                case rud3.RUD3_CARD_NOT_FOUND:
                    InfoBuffer.warning("Rud-3 new card not found");
                    break;

                case rud3.RUD3_DEVICE_CANNOT_CLOSE:
                    InfoBuffer.error("Rud-3 cann't close comunication chanel");
                    break;

                case rud3.RUD3_WRITE_ERROR:
                    InfoBuffer.error("Rud-3 write error");
                    break;

                case rud3.RUD3_READ_ERROR:
                    InfoBuffer.error("Rud-3 read error");
                    break;

                default:
                    break;
            }
            
            //Clear
            returnLibrary = rud3.RUD3_OK;

        }

        private void message(String msg)
        {
            InfoBuffer.error(msg);

            //Clear
            returnLibrary = rud3.RUD3_OK;
        }
    }
}
