import enum
from ctypes import (CFUNCTYPE, POINTER, byref, c_char, c_int32, c_uint8,
                    c_void_p, cast, create_string_buffer, pointer)

from components.Automation.BDaq import *
buffer = {}

out_data =[0b00000101,0b00000101]
class ErrorCode(Enum):
    # <summary>
    # The operation is completed successfully.
    # </summary>
    Success = 0

    # ************************************************************************
    # warning
    # ************************************************************************
    # <summary>
    # The interrupt resource is not available.
    # </summary>
    WarningIntrNotAvailable = 0xA0000000

    # <summary>
    # The parameter is out of the range.
    # </summary>
    WarningParamOutOfRange = 0xA0000001

    # <summary>
    # The property value is out of range.
    # </summary>
    WarningPropValueOutOfRange = 0xA0000002

    # <summary>
    # The property value is not supported.
    # </summary>
    WarningPropValueNotSpted = 0xA0000003

    # <summary>
    # The property value conflicts with the current state.
    # </summary>
    WarningPropValueConflict = 0xA0000004

    # <summary>
    # The value range of all channels in a group should be same,
    # such as 4~20mA of PCI-1724.
    # </summary>
    WarningVrgOfGroupNotSame = 0xA0000005

    # <summary>
    # Some properties of a property set are failed to be written into device.
    #
    # </summary>
    WarningPropPartialFailed = 0xA0000006

    # <summary>
    # The operation had been stopped.
    #
    # </summary>
    WarningFuncStopped = 0xA0000007

    # <summary>
    # The operation is time-out.
    #
    # </summary>
    WarningFuncTimeout = 0xA0000008

    # <summary>
    # The cache is over-run.
    #
    # </summary>
    WarningCacheOverflow = 0xA0000009

    # <summary>
    # The channel is burn-out.
    #
    # </summary>
    WarningBurnout = 0xA000000A

    # <summary>
    # The current data record is end.
    #
    # </summary>
    WarningRecordEnd = 0xA000000B

    # <summary>
    # The specified profile is not valid.
    #
    # </summary>
    WarningProfileNotValid = 0xA000000C

    # ***********************************************************************
    # error
    # ***********************************************************************
    # <summary>
    # The handle is NULL or its type doesn't match the required operation.
    # </summary>
    ErrorHandleNotValid = 0xE0000000

    # <summary>
    # The parameter value is out of range.
    # </summary>
    ErrorParamOutOfRange = 0xE0000001

    # <summary>
    # The parameter value is not supported.
    # </summary>
    ErrorParamNotSpted = 0xE0000002

    # <summary>
    # The parameter value format is not the expected.
    # </summary>
    ErrorParamFmtUnexpted = 0xE0000003

    # <summary>
    # Not enough memory is available to complete the operation.
    # </summary>
    ErrorMemoryNotEnough = 0xE0000004

    # <summary>
    # The data buffer is null.
    # </summary>
    ErrorBufferIsNull = 0xE0000005

    # <summary>
    # The data buffer is too small for the operation.
    # </summary>
    ErrorBufferTooSmall = 0xE0000006

    # <summary>
    # The data length exceeded the limitation.
    # </summary>
    ErrorDataLenExceedLimit = 0xE0000007

    # <summary>
    # The required function is not supported.
    # </summary>
    ErrorFuncNotSpted = 0xE0000008

    # <summary>
    # The required event is not supported.
    # </summary>
    ErrorEventNotSpted = 0xE0000009

    # <summary>
    # The required property is not supported.
    # </summary>
    ErrorPropNotSpted = 0xE000000A

    # <summary>
    # The required property is read-only.
    # </summary>
    ErrorPropReadOnly = 0xE000000B

    # <summary>
    # The specified property value conflicts with the current state.
    # </summary>
    ErrorPropValueConflict = 0xE000000C

    # <summary>
    # The specified property value is out of range.
    # </summary>
    ErrorPropValueOutOfRange = 0xE000000D

    # <summary>
    # The specified property value is not supported.
    # </summary>
    ErrorPropValueNotSpted = 0xE000000E

    # <summary>
    # The handle hasn't own the privilege of the operation the user wanted.
    # </summary>
    ErrorPrivilegeNotHeld = 0xE000000F

    # <summary>
    # The required privilege is not available because someone else had own it.
    # </summary>
    ErrorPrivilegeNotAvailable = 0xE0000010

    # <summary>
    # The driver of specified device was not found.
    # </summary>
    ErrorDriverNotFound = 0xE0000011

    # <summary>
    # The driver version of the specified device mismatched.
    # </summary>
    ErrorDriverVerMismatch = 0xE0000012

    # <summary>
    # The loaded driver count exceeded the limitation.
    # </summary>
    ErrorDriverCountExceedLimit = 0xE0000013

    # <summary>
    # The device is not opened.
    # </summary>
    ErrorDeviceNotOpened = 0xE0000014

    # <summary>
    # The required device does not exist.
    # </summary>
    ErrorDeviceNotExist = 0xE0000015

    # <summary>
    # The required device is unrecognized by driver.
    # </summary>
    ErrorDeviceUnrecognized = 0xE0000016

    # <summary>
    # The configuration data of the specified device is lost or unavailable.
    # </summary>
    ErrorConfigDataLost = 0xE0000017

    # <summary>
    # The function is not initialized and can't be started.
    # </summary>
    ErrorFuncNotInited = 0xE0000018

    # <summary>
    # The function is busy.
    # </summary>
    ErrorFuncBusy = 0xE0000019

    # <summary>
    # The interrupt resource is not available.
    # </summary>
    ErrorIntrNotAvailable = 0xE000001A

    # <summary>
    # The DMA channel is not available.
    # </summary>
    ErrorDmaNotAvailable = 0xE000001B

    # <summary>
    # Time out when reading/writing the device.
    # </summary>
    ErrorDeviceIoTimeOut = 0xE000001C

    # <summary>
    # The given signature does not match with the device current one.
    # </summary>
    ErrorSignatureNotMatch = 0xE000001D

    # <summary>
    # The function cannot be executed while the buffered AI is running.
    # </summary>
    ErrorFuncConflictWithBfdAi = 0xE000001E

    # <summary>
    # The value range is not available in single-ended mode.
    # </summary>
    ErrorVrgNotAvailableInSeMode = 0xE000001F

    # <summary>
    # The value range is not available in 50omh input impedance mode..
    # </summary>
    ErrorVrgNotAvailableIn50ohmMode = 0xE0000020

    # <summary>
    # The coupling type is not available in 50omh input impedance mode..
    # </summary>
    ErrorCouplingNotAvailableIn50ohmMode = 0xE0000021

    # <summary>
    # The coupling type is not available in IEPE mode.
    # </summary>
    ErrorCouplingNotAvailableInIEPEMode = 0xE0000022

    # <summary>
    # The Communication is failed when reading/writing the device.
    # </summary>
    ErrorDeviceCommunicationFailed = 0xE0000023

    # <summary>
    # The device's 'fix number' conflicted with other device's
    # </summary>
    ErrorFixNumberConflict = 0xE0000024

    # <summary>
    # The Trigger source conflicted with other trigger configuration
    # </summary>
    ErrorTrigSrcConflict = 0xE0000025

    # <summary>
    # All properties of a property set are failed to be written into device.
    # </summary>
    ErrorPropAllFailed = 0xE0000026

    # <summary>
    # Undefined error
    # </summary>
    ErrorUndefined = 0xE000FFFF

    @staticmethod
    def lookup(value):
        value = value & 0xFFFFFFFF
        for code in ErrorCode:
            if value == code.value:
                return code
        return ErrorCode.ErrorUndefined

def _insert(byte, n=1):
    for i in range(byte, byte + n):
        if i not in buffer:
            buffer[i] = 0b11111111


@CFUNCTYPE(c_int32, c_void_p, c_int32, c_int32, POINTER(c_char))
def InstantDiCtrl_ReadAny(useless, start_byte, n, out_buffer):
    for byte in range(start_byte, start_byte + n):
        out_buffer[byte] = out_data[byte]
    return 0


@CFUNCTYPE(c_int32, c_void_p, c_int32, c_int32, c_char)
def InstantDoCtrl_WriteBit(useless, byte, bit, val):
    _insert(byte)
    b = int(int.from_bytes(val, "big") != 0) << bit
    buffer[byte] &= 0b11111111 & ~(1 << bit)
    buffer[byte] |= b
    return ErrorCode.Success


@CFUNCTYPE(c_void_p)
def AdxInstantDiCtrlCreate(*args):
    return None


@CFUNCTYPE(c_int32, c_void_p, c_void_p)
def InstantDiCtrl_setSelectedDevice(*args):
    return 0


@CFUNCTYPE(c_void_p)
def AdxInstantDoCtrlCreate(*args):
    return None


@CFUNCTYPE(c_int32, c_void_p, c_void_p)
def InstantDoCtrl_setSelectedDevice(*args):
    return 0


@CFUNCTYPE(c_void_p, c_void_p)
def InstantDoCtrl_getPortDirection(*args):
    return pointer((c_void_p * 3)())


@CFUNCTYPE(c_int32, c_void_p, c_uint8)
def PortDirection_setDirection(*args):
    return 0
