from .uicl_types import *
from ..lib_helper import OS_Requirements, lib_method_wrapper


UICL_CURRENT_VERSION = 1
UICL = OS_Requirements("UICL").get_lib()


class UICLError(Exception):
    def __init__(self, message, errors=None):
        super().__init__(message)
        self.errors = errors


def UICL_GetRequiredBufferSize(dest_image: UICL_Image):
    _UICL_GetRequiredBufferSize = lib_method_wrapper(UICL.UICL_GetRequiredBufferSize, [POINTER(UICL_Image)], c_int64)

    return _UICL_GetRequiredBufferSize(byref(dest_image))


def UICL_Convert(src_image: UICL_Image, dest_image: UICL_Image):
    _UICL_Convert = lib_method_wrapper(UICL.UICL_Convert, [POINTER(UICL_Image), POINTER(UICL_Image)], UICL_RESULT)

    return _UICL_Convert(byref(src_image), byref(dest_image))


def UICL_SaveToFile(src_image: UICL_Image, file_name, image_file_format):
    _UICL_SaveToFile = lib_method_wrapper(UICL.UICL_SaveToFile, [c_char_p, POINTER(UICL_Image), c_int], UICL_RESULT)

    return _UICL_SaveToFile(c_char_p(file_name.encode('utf-8')), byref(src_image), image_file_format)


def UICL_CalculateCRC16(src_image: UICL_Image, crc: UICL_CRC16):
    _UICL_CalculateCRC16 = lib_method_wrapper(UICL.UICL_CalculateCRC16, [POINTER(UICL_Image), POINTER(UICL_CRC16)],
                                              UICL_RESULT)

    return _UICL_CalculateCRC16(byref(src_image), byref(crc))


def UICL_GeneratePattern(src_image: UICL_Image, pattern_type: int):
    _UICL_GeneratePattern = lib_method_wrapper(UICL.UICL_GeneratePattern, [POINTER(UICL_Image), c_int],
                                               UICL_RESULT)

    return _UICL_GeneratePattern(byref(src_image), pattern_type)


def UICL_GeneratePattern_3Tap(src_image: UICL_Image, pattern_type: int):
    _UICL_GeneratePattern_3Tap = lib_method_wrapper(UICL.UICL_GeneratePattern_3Tap, [POINTER(UICL_Image), c_int],
                                                    UICL_RESULT)

    return _UICL_GeneratePattern_3Tap(byref(src_image), pattern_type)


def UICL_FreeImage(src_image: UICL_Image):
    _UICL_DeleteImage = lib_method_wrapper(UICL.UICL_FreeImage, [ POINTER(UICL_Image) ],
                                           UICL_RESULT)

    return _UICL_DeleteImage(byref(src_image))


def UICL_AllocImage(image_params: UICL_ImageParameters) -> UICL_Image:
    _UICL_AllocateImage = lib_method_wrapper(UICL.UICL_AllocImage,
                                             [POINTER(UICL_ImageParameters), POINTER(UICL_Image)],
                                             UICL_RESULT)

    image = UICL_Image()

    result = _UICL_AllocateImage(byref(image_params), byref(image))

    if result < UICL_SUCCESS:
        raise UICLError(f"Cannot allocate image. Error code: {result}")

    return image
