#!D:\IDE\Anaconda3\envs\Microscope_Scan python
# -*- coding: UTF-8 -*-
"""
 @Author: Administrator
 @FileName: CameraRequest.py
 @DateTime: 2025/4/8 20:48
 @SoftWare: PyCharm
 @Author  ：xsh
"""
import datetime
import sys
from PyQt5                              import Qt
from AppInterfaces.ModelInterface       import RequestModelInterface
from AppCore.Levels                     import *
from AppUtils.utils                     import *
from AppCore.Requests                   import *
from AppUtils.ImageUtils import ImageUtils
# from AppCore.AppAlgorithms.ImageAlgorithm import ImageAlgorithm
import numpy as np

class CameraRequest(RequestModelInterface):
    ResultNumber   : int
    ID             : int
    ImageSource    : np.ndarray
    ImageJson      : str
    StartTime      : datetime.datetime
    FinishTime     : datetime.datetime
    __slots__ = (
        'ResultNumber'      ,       # 返回状态
        'ID'                ,       # 图片序号
        'ImageSource'       ,       # 图片数据
        'ImageJson'         ,       # 图片数据
        'StartTime'         ,       # 开始时间
        'FinishTime'        ,       # 停止时间
    )
    __types__ = (
        int                 ,      # 返回状态
        int                 ,      # 图片序号
        np.ndarray          ,      # 图片数据
        str                 ,      # 玻片图片
        datetime.datetime   ,      # 开始时间
        datetime.datetime   ,      # 停止时间
    )
    def __init__(self, **args):
        super(CameraRequest, self).__init__()
        self.initialization("相机请求")
        self.initParameter(**args)


    @classmethod
    def xyz_instance(cls, **args) -> 'CameraRequest':
        result: cls = cls.__new__(cls)
        _args: dict[str, object] = {}
        _args['ResultNumber'    ] = args.get('ResultNumber'     , None)
        _args['ID'              ] = args.get('ID'               , None)
        _args['ImageSource'     ] = args.get('ImageSource'      , None)
        _args['ImageJson'       ] = args.get('ImageJson'        , None)
        _args['StartTime'       ] = args.get('StartTime'        , None)
        _args['FinishTime'      ] = args.get('FinishTime'       , None)
        result.__init__(**args)
        return result

    @classmethod
    def instance(cls, **args) -> 'CameraRequest':
        result: cls = cls.__new__(cls)
        result.__init__(**args)
        return result

    @classmethod
    def Instance(cls, **args) -> 'CameraRequest':
        result: cls = cls.__new__(cls)
        result.__init__(**args)
        return result

    @property
    def isAvailable(self) -> bool:
        return self.has_ImageSource and isinstance(self.ImageSource, np.ndarray)

    @property
    def hasImageSource(self) -> bool:
        return hasattr(self, 'ImageSource') and isinstance(self.ImageSource, np.ndarray)


    def toImage(self, w: int = -1, h: int = -1) -> np.ndarray:
        image: np.ndarray = ImageUtils.image_resize(self.ImageSource, w, h)
        return image

    def toQImage(self, w: int = -1, h: int = -1) -> Qt.QImage:
        image: Qt.QImage = ImageUtils.cv2_to_QImage(self.ImageSource, w, h)
        return image

    def toBase64(self, w: int = -1, h: int = -1) -> str:
        result: str
        if self.has_ImageSource:
            result = ImageUtils.image_to_base64(ImageUtils.image_resize(self.ImageSource, w, h))
        elif self.has_ImageJson:
            self.JsonToImage()
            result = ImageUtils.image_to_base64(ImageUtils.image_resize(self.ImageSource, w, h))
        else:
            result = ''
        return result

    def ImageToJson(self):
        if self.has_ImageSource:
            self.ImageJson = ImageUtils.image_to_base64(self.ImageSource)
        else:
            self.ImageJson = None
    def JsonToImage(self):
        if self.has_ImageJson:
            self.ImageSource = ImageUtils.base64_to_image(self.ImageJson)
        else:
            self.ImageSource = None

    def initParameter(self, **args):
        super(CameraRequest, self).initParameter(**args)
        if not isinstance(args, dict) or len(args) <= 0:
            return
        for index, _property in enumerate(self.__slots__):
            setattr(self, _property, args.get(_property, None))
        if not self.has_ImageSource :
            if self.has_ImageJson:
                self.JsonToImage()
        else:
            if not self.has_ImageJson:
                self.ImageToJson()
    def copy(self, isCopy: bool = True) -> 'CameraRequest':
        result = self.__class__ = self.__class__.__new__(self.__class__)
        result.__init__(**self.serialize())
        if isCopy:
            if self.has_ImageSource:
                result.ImageJson = self.toJson()
                result.JsonToImage()
            elif self.has_ImageJson:
                result.ImageJson = self.ImageJson
                result.JsonToImage()
        return result


    def initValue(self):
        super(CameraRequest, self).initValue()
        self.ResultNumber   = 0         # 返回状态
        self.ID             = 0         # 图片序号
        self.ImageSource    = None      # 图片数据
        self.ImageJson      = None      # 玻片图片
        self.StartTime      = datetime.datetime.now()      # 开始时间
        self.FinishTime     = datetime.datetime.now()      # 停止时间



    @property
    def has_ResultNumber (self) -> bool:
        return hasattr(self, 'ResultNumber') and isinstance(self.ResultNumber , int              )

    @property
    def has_ID           (self) -> bool:
        return hasattr(self, 'ID'          ) and isinstance(self.ID           , int              )

    @property
    def has_ImageSource  (self) -> bool:
        return hasattr(self, 'ImageSource' ) and isinstance(self.ImageSource  , np.ndarray       )

    @property
    def has_ImageJson    (self) -> bool:
        return hasattr(self, 'ImageJson'   ) and isinstance(self.ImageJson    , str              )


    @property
    def has_StartTime    (self) -> bool:
        return hasattr(self, 'StartTime'   ) and isinstance(self.StartTime    , datetime.datetime)

    @property
    def has_FinishTime   (self) -> bool:
        return hasattr(self, 'FinishTime'  ) and isinstance(self.FinishTime   , datetime.datetime)

