using System;
using System.Runtime.InteropServices;

namespace Rglib.Interop {
    /// <summary>
    /// Тип подключения
    /// </summary>
    public enum RG_ENDPOINT_TYPE : byte {
        /// <summary>
        /// Что-то непонятное, неизвестное
        /// </summary>
        CTE_UNKNOWN = 0x00,
        /// <summary>
        /// USB HID
        /// </summary>
        CTE_USBHID = 0x01,
        /// <summary>
        /// Последовательный порт
        /// </summary>
        CTE_SERIAL = 0x02       
    }

    /// <summary>
    /// Структура определяющая параметры подключения
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct RG_ENDPOINT {
        /// <summary>
        /// Тип конечной точки, согласно RG_CONNECTION_TYPE
        /// Определяет используемый механизм подключения.
        /// </summary>
        [MarshalAs(UnmanagedType.U1)] public RG_ENDPOINT_TYPE Type;

        /// <summary>
        /// Строка подключения (31 символов ASCII + null символ)
        /// </summary>
        [MarshalAs(UnmanagedType.LPStr)] public string Address;
    }

    /// <summary>
    /// Структура определяющая параметры подключения
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct RG_ENDPOINT_INFO {
        /// <summary>
        /// Тип конечной точки, согласно RG_CONNECTION_TYPE
        /// Определяет используемый механизм подключения.
        /// </summary>
        [MarshalAs(UnmanagedType.U1)] public RG_ENDPOINT_TYPE Type;

        /// <summary>
        /// Строка подключения (31 символов ASCII + null символ)
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
        public string Address;

        /// <summary>
        /// Строка подключения (31 символов ASCII + null символ)
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
        public string FriendlyName;
    }

    /// <summary>
    /// Тип устройства
    /// </summary>
    public enum RG_DEVICE_TYPE : byte {
        /// <summary>
        /// Неизвесное устройство
        /// </summary>
        DTE_UNKNOWN = 0x00,

        /// <summary>
        /// Мултиформатный считыватель RDR-202
        /// </summary>
        DTE_RDR202 = 0x04,

        /// <summary>
        /// USB считыватель R10-EHT
        /// </summary>
        DTE_R10EHT = 0x0A,

        /// <summary>
        /// USB считыватель R10-MF
        /// </summary>
        DTE_R10MF = 0x0B,

        /// <summary>
        /// USB считыватель R15 Multi
        /// </summary>
        DTE_R15MULTI = 0x0F,

        /// <summary>
        /// USB считыватель R5-USB Multi
        /// </summary>
        DTE_R5USBMULTI = 0x10,

        /// <summary>
        /// USB считыватель R5-USB Multi Prof
        /// </summary>
        DRTE_R5USBMULTIPROF = 0x11,

        /// <summary>
        /// Считыватель RDR204-EH Key
        /// </summary>
        DTE_RDR204EH = 0x0C,

        /// <summary>
        /// Считыватель RDR204-MF Key
        /// </summary>
        DTE_RDR204MF = 0x0D,

        /// <summary>
        /// Считыватель RDR-102
        /// </summary>
        DTE_RDR102 = 0x0E,
    }

    /// <summary>
    /// Информация об устройстве
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct RG_DEVICE_INFO_EXT {
        /// <summary>
        /// Адрес устройства
        /// </summary>
        public byte Address;

        /// <summary>
        /// Серийный номер
        /// </summary>
        public UInt32 Serial;

        /// <summary>
        /// Значение для проверки на запрет прошивки
        /// </summary>
        public byte FirmwareUpdateLock;

        /// <summary>
        /// Тип устройства
        /// </summary>
        public byte Type;

        /// <summary>
        /// Версия прошивки
        /// </summary>
        public UInt16 Firmware;

        /// <summary>
        /// Флаги функциональных возможностей устройства
        /// </summary>
        public UInt32 Capabilities;
    }

    /// <summary>
    /// Флаги функциональности
    /// </summary>
    [Flags]
    public enum _E_RG_CAPABILITIES : uint {
        CFE_SUPPORT_HID_EM = 1,
        CFE_SUPPORT_TEMIC = 2,
        CFE_SUPPORT_COTAG = 4,
        CFE_SUPPORT_MIFARE = 8,

        CFE_SUPPORT_INF = 16,
        CFE_SUPPORT_NFC = 32,
        CFE_SUPPORT_NFC_PAY = 64,
        CFE_SUPPORT_BLE = 128,

        CFE_SUPPORT_TM_W = 256,
        CFE_SUPPORT_RBUS = 512,
        CFE_SUPPORT_RS485 = 1024,
        CFE_SUPPORT_USB = 2048,

        CFE_HAS_MEMORY = 4096,
        CFE_HAS_KEYBOARD = 8192,
        CFE_HAS_CLOCK = 16384,
        CFE_HAS_TERMO = 32768,

        CFE_HAS_RELAY = 65536,
        CFE_READER = 131072,
        CFE_CONTROLLER = 262144,
        CFE_SUPPORT_ODSP = 524288,
    }

    /// <summary>
    /// Типы статуса устройства
    /// </summary>
    public enum RG_STATUS_TYPE : byte {
        /// <summary>
        /// Неизвестный статус/неопределенный
        /// </summary>
        STE_UNKNOWN = 0,

        /// <summary>
        /// Нет приложенной карты
        /// </summary>
        STE_NO_CARD = 1,

        /// <summary>
        /// Карта без памяти или нет профилей в памяти
        /// </summary>
        STE_CARD = 9,

        /// <summary>
        /// Карта с памятью и успешная авторизация
        /// </summary>
        STE_CARD_AUTH = 26,

        /// <summary>
        /// Карта с памятью, но произошла ошибка доступа к памяти
        /// </summary>
        STE_CARD_NO_AUTH = 10
    }

    /// <summary>
    /// Коды семейств карт
    /// </summary>
    public enum RG_CARD_FAMILY_CODE : byte {
        /// <summary>
        /// Код с клавиатуры
        /// </summary>
        CFCE_PIN = 1,

        /// <summary>
        /// Temic
        /// </summary>
        CFCF_TEMIC = 2,

        /// <summary>
        /// HID
        /// </summary>
        CFCE_HID = 4,

        /// <summary>
        /// Em-Marine
        /// </summary>
        CFCE_EM = 8,

        /// <summary>
        /// Indala
        /// </summary>
        CFCF_INDALA = 16,

        /// <summary>
        /// Cotag/Bewator
        /// </summary>
        CFCE_COTAG = 32,

        /// <summary>
        /// Mifare
        /// </summary>
        CFCE_MIFARE = 64,

        /// <summary>
        /// Все карты
        /// </summary>
        CF_ALL = CFCE_PIN | CFCF_TEMIC | CFCE_HID | CFCE_EM | CFCF_INDALA | CFCE_COTAG | CFCE_MIFARE
    }

    /// <summary>
    /// Коды типов карт
    /// </summary>
    public enum RG_CARD_TYPE_CODE : byte {
        /// <summary>
        /// PIN код склавиатуры
        /// </summary>
        CTCE_PIN = 0x00,

        /// <summary>
        /// Карта Temic
        /// </summary>
        CTCE_TEMIC = 0x01,

        /// <summary>
        /// Карта HID
        /// </summary>
        CTCE_HID = 0x02,

        /// <summary>
        /// Карта Em-Marine
        /// </summary>
        CTCE_EM = 0x03,

        /// <summary>
        /// Карта Indala
        /// </summary>
        CTCE_INDALA = 0x04,

        /// <summary>
        /// Карта COTAG
        /// </summary>
        CTCE_COTAG = 0x05,

        /// <summary>
        /// Карта MIFARE DESFire EV1
        /// </summary>
        CTCE_MF_DESFIRE = 0x06,

        /// <summary>
        /// Карта MIFARE Ultralight
        /// </summary>
        CTCE_MF_UL = 0x07,

        /// <summary>
        /// Карта MIFARE Mini
        /// </summary>
        CTCE_MF_MINI = 0x08,

        /// <summary>
        /// Карта MIFARE Classic 1K / MIFARE Plus EV1 2K SL1
        /// </summary>
        CTCE_MF_CL1K_PL2K = 0x09,

        /// <summary>
        /// Карта MIFARE Classic 4K / MIFARE Plus EV1 4K SL1
        /// </summary>
        CTCE_MF_CL4K_PL4K = 0x0A,

        /// <summary>
        /// Карта MIFARE Plus 2K SL2
        /// </summary>
        CTCE_MF_PL2K_SL2 = 0x0B,

        /// <summary>
        /// Карта MIFARE Plus 4K SL2
        /// </summary>
        CTCE_MF_PL4K_SL2 = 0x0C,

        /// <summary>
        /// Карта MIFARE Plus SL3
        /// </summary>
        CTCE_MF_SL3 = 0x0D,

        /// <summary>
        /// Карта SmartMX 4K
        /// </summary>
        CTCE_SMX4K = 0x0E,

        /// <summary>
        /// Карта SmartMX 1K
        /// </summary>
        CTCE_SMX1K = 0x0F,

        /// <summary>
        /// Мобила с PAY
        /// </summary>
        CTCE_PAY = 0xFD,
        /// <summary>
        /// Мобила с приложением
        /// </summary>
        CTCE_MOBILE = 0xFE
    }

    /// <summary>
    /// Информация о карте
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1, Size = 8)]
    public struct RG_CARD_INFO {
        /// <summary>
        /// Код типа карты
        /// </summary>
        public byte Type;

        /// <summary>
        /// UID карты, формат и точный размер зависят непосредственно от типа карты
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
        public byte[] Uid;
    }

    /// <summary>
    /// Информация о карте
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1, Size = 17)]
    public struct RG_CARD_MEMORY {
        /// <summary>
        /// Номер блока или профиля, в зависимости от места использования
        /// </summary>
        public byte ProfileOrBlockNum;

        /// <summary>
        /// Данные блока
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
        public byte[] BlockData;
    }

    /// <summary>
    /// Флаги определяющие механизм авторизации карт Mifare
    /// </summary>
    [Flags]
    public enum RG_CARD_AUTH_FLAGS : byte {
        /// <summary>
        /// Если установлен, авторизация Mifare Classic будет произодиться по ключу B. Иначе по ключу А
        /// </summary>
        CAF_CLASSIC_KEY_B = 1,
        CAF_GENERATED_KEY = 1,


        /// <summary>
        /// Если установлен, авторизация Mifare Plus будет произодиться по ключу B. Иначе по ключу А
        /// </summary>
        CAF_PLUS_KEY_B = 2,
        CAF_PRESENT_KEY = 2,

        /// <summary>
        /// Если установлен, будет использован механизм авторизации для карты SL3, иначе SL1/CLassic
        /// </summary>
        CAF_PLUS_SL3 = 4,
        CAF_EMITED_KEY = 4,

        CAF_USE_PAY = 32,
        CAF_USE_APP = 64,
    };

    /// <summary>
    /// Информация о карте
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1, Size = 23)]
    public struct RG_CARD_AUTH_PARAMS {
        /// <summary>
        /// Флаги авторизации, согласно RG_CARD_AUTH_FLAGS
        /// </summary>
        public byte Flags;
        /// <summary>
        /// Данные блока
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
        public byte[] ClassicKey;
        /// <summary>
        /// Данные блока
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
        public byte[] PlusKey;
    }

    /// <summary>
    /// Информация о карте
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1, Size = 5)]
    public struct RG_CODOGRAMM {
        /// <summary>
        /// Длинна кодограммы в битах (0...32, 1бит = 100мс индикации)
        /// </summary>
        public byte Length;
        /// <summary>
        /// Тело кодограммы, (1бит = 100мс индикации)
        /// </summary>
        public UInt32 Body;
    }

    /// <summary>
    /// Приоритет выполнения кодограммы
    /// </summary>
    public enum RG_CODOGRAMM_PRIORITY : byte {
        /// <summary>
        /// Фоновая индикация
        /// </summary>
        CPE_BACKGROUND = 0,
        /// <summary>
        /// Циклическая индикация
        /// </summary>
        CPE_CYCLIC_LO,
        /// <summary>
        /// Циклическая индикация с вышим приоритетом
        /// </summary>
        CPE_CYCLIC_HI,
        /// <summary>
        /// Разовая индикация
        /// </summary>
        CPE_ONCE_LO,
        /// <summary>
        /// Разовая индикация с высшим приоритетом
        /// </summary>
        CPE_ONCE_HI
    }

    /// <summary>
    /// Типы событий
    /// </summary>
    public enum RG_DEVICE_EVENT_TYPE : uint {
        UNKNOWN_EVENT = 0,
        /// <summary>
        /// К считывателю приложена карта.
        /// В качестве данных события возвращает указатель на RG_CARD_INFO
        /// </summary>
        CARD_PLACED_EVENT = 2,
        /// <summary>
        /// Карта убрана из поля считывателя
        /// </summary>
        CARD_REMOVED_EVENT = 4,
    }
}
