#!D:/IDE/anaconda3/envs/Microscope_Scan python
# -*- coding: UTF-8 -*-
"""
@FileName：CameraFocusingPool.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.Levels                                         import *
from AppCore.Requests                                       import *
from AppInterfaces.EventInterfaces                          import AppEventInterface
from AppCore.AppDBModels.SlideModels.SlideModelInterface    import SlideModelInterface

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

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

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

    def initConnect(self):
        super(CameraFocusingPool, 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(CameraFocusingPool, self).initValue()
        self.initPools()
        self.is_async = False

    def SendEvent(self, value, **args):
        self.AppendItem.emit(value)
        isAsync: bool = args.get('isAsync', False)
        if not isAsync:
            AppTimeLoop.processGlobalEvents(100)


    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.getSlideGrabNumber(item)
            if item.hasImageSource and self.hasSendFocusing:
                self.sendfocusing.SendEvent(item.copy())
        except Exception as e:
            AppUtils.print_Exception(e)


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

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

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

    def initSendFocusing (self):
        if not self.hasSendFocusing:
            from AppBackEnd.BackEndEventBus.SlideFocusingPool import SlideFocusingPool
            self.SendFocusing = SlideFocusingPool.GetInstance()

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

    @property
    def sendfocusing (self) -> AppEventInterface     :
        return None if not self.hasSendFocusing else self.SendFocusing         #

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

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

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