#!D:/IDE/anaconda3/envs/Microscope_Scan python
# -*- coding: UTF-8 -*-
"""
@FileName：CameraScanningPool.py
@Description：
@Author：XSH
@Time：2025/11/15 11:53
@Department：研发部
@Copyright：©2025 乐辰生物
"""
from PyQt5                                                  import Qt
from AppInterfaces.utils                                    import *
from AppUtils.utils                                         import *
from AppCore.Requests                                       import *
from AppCore.Levels                                         import *
from AppInterfaces.EventInterfaces                          import AppEventInterface
from AppCore.AppDBModels.SlideModels.SlideModelInterface    import SlideModelInterface

from AppInterfaces.ReaderInterfaces                         import CameraReaderInterface
class CameraScanningPool(Qt.QThread, AppEventInterface, SingletonInterface):
    AppendItem      : Qt.pyqtSignal             = Qt.pyqtSignal(object)
    _IOLocker       : Qt.QReadWriteLock         = Qt.QReadWriteLock()
    Locker          : Qt.QMutex                 = Qt.QMutex()
    SendScanning    : AppEventInterface         # 图像显示线程
    ReadCamera      : CameraReaderInterface     # 网络发送线程

    @classmethod
    def GetInstance(cls, *args, **kwargs) -> 'CameraScanningPool':
        return super(CameraScanningPool, cls).GetInstance(*args, **kwargs)

    def __init__(self, parent: Qt.QObject = None):
        super(CameraScanningPool, self).__init__(parent=parent)
        self.Initialization('DataOnlyDrawPool', self, parent)
        self.Mode = EventLevel.OnlyDrawMode

        # self.Start()

    def initConnect(self):
        super(CameraScanningPool, self).initConnect()
        TYPE: Qt.Qt.ConnectionType = Qt.Qt.ConnectionType(Qt.Qt.AutoConnection | Qt.Qt.UniqueConnection)
        self.AppendItem.connect(slot=self.SlotAppendItem, type=TYPE)


    def initValue(self):
        super(CameraScanningPool, self).initValue()
        self.initPools()
        self.is_async = False

    def SendEvent(self, value, **args):
        self.AppendItem.emit(value)
        AppTimeLoop.processGlobalEvents(200)

    def StartWork(self):
        self.initPools  ()
        self.Start      ()

    def StopWork(self):
        pass

    def StartFocusing(self, isShowFocusing: bool = True, **args):
        self.initPools  ()
        if not self.readCamera.IsGrabbing:
            self.readCamera.StartGrabbing()
        self.Start      ()


    def StopFocusing(self, isShowFocusing: bool = True, **args):
        pass


    def appendItem(self, item, *args, **kwargs):
        if not self.isRunning():
            self.is_running = True
            self.start(Qt.QThread.NormalPriority)
        if isinstance(item, SlideModelInterface):
            with self.condition:
                self.DataBuffer.put(item)
                self.condition.notify_all()

    def Start(self):
        if self.isRunning():
            return
        self.initPools()
        self.is_running = True
        self.start(Qt.QThread.NormalPriority)

    def run(self) -> None:
        self.process()

    def WaitDone(self, item, *args, **kwargs):
        if not isinstance(item, SlideModelInterface):
            return
        self.initPools()
        try:
            # if not self.readCamera.IsGrabbing:
            #     self.readCamera.StartFocusing(item.ObjectiveLevel)
            self.readCamera.getFocusingNumpy(item=item, classifier=None)
            # print(self.__class__.__name__, self.index, item.hasImageSource)
            self.sendScanning.SendEvent(item)
        except Exception as e:
            AppUtils.print_Exception(e)


    def initPools(self):
        self.initSendScanning   ()
        self.initReadCamera     ()

    def delePools(self):
        self.SendScanning       = None
        self.ReadCamera         = None


    @property
    def isAvailable(self) -> bool:
        return self.isRunning() and self.hasReadCamera and self.hasSendScanning

    def initSendScanning (self):
        if not self.hasSendScanning:
            from AppBackEnd.BackEndEventBus.SlideScanningPool import SlideScanningPool
            self.SendScanning = SlideScanningPool.GetInstance()

    def initReadCamera   (self):
        if not self.hasReadCamera  :
            from AppCore.AppReaders.CameraReader import CameraReader
            self.ReadCamera   = CameraReader.GetInstance()

    @property
    def sendScanning (self) -> AppEventInterface     :
        return None if not self.hasSendScanning else self.SendScanning         #

    @property
    def readCamera   (self) -> CameraReaderInterface :
        return None if not self.hasReadCamera   else self.ReadCamera           #

    @property
    def hasSendScanning    (self) -> bool:
        return hasattr(self, 'SendScanning') and isinstance(self.SendScanning    , AppEventInterface    )

    @property
    def hasReadCamera      (self) -> bool:
        return hasattr(self, 'ReadCamera'  ) and isinstance(self.ReadCamera      , CameraReaderInterface)
