#!D:/IDE/anaconda3/envs/Microscope_Scan python
# -*- coding: UTF-8 -*-
"""
@FileName：HardWareManagerInterface.py
@Description：
@Author：XSH
@Time：2025/11/15 11:54
@Department：研发部
@Copyright：©2025 乐辰生物
"""
from PyQt5                              import Qt
from abc                                import abstractmethod
from AppSettings.Settings               import RECODE_FAILURE, RECODE_SUCCEED
from AppUtils import AppUtils
from AppInterfaces.ManagerInterface     import ManagerInterface
from AppInterfaces.ImplInterface                                    import ImplInterface                            #
from AppInterfaces.AppImplInterfaces.ModBusImplInterface            import ModBusImplInterface                      #
from AppInterfaces.AppImplInterfaces.ModBusPoolInterface            import ModBusPoolInterface                      #
from AppInterfaces.AppImplInterfaces.DetectionImplInterface         import DetectionImplInterface                   #
from AppInterfaces.AppImplInterfaces.HookImplInterface              import HookImplInterface                        #
from AppInterfaces.AppImplInterfaces.AxisImplInterface              import AxisImplInterface                        #
from AppInterfaces.AppImplInterfaces.CameraImplInterface            import CameraImplInterface                      #
from AppInterfaces.AppImplInterfaces.ScanCodeImplInterface          import ScanCodeImplInterface                    #
from AppInterfaces.AppImplInterfaces.LMicroscopeInterface           import LMicroscopeInterface                     #
from AppInterfaces.AppImplInterfaces.ZMicroscopeInterface           import ZMicroscopeInterface                     #
from AppInterfaces.AppImplInterfaces.WebClientInterface             import WebClientInterface                       #
from AppInterfaces.AppImplInterfaces.WebServerInterface             import WebServerInterface                       #
from AppInterfaces.ReaderInterface                                  import ReaderInterface                          #
from AppInterfaces.AppReaderInterfaces.CameraReaderInterface        import CameraReaderInterface                    #
from AppInterfaces.AppReaderInterfaces.ScanCodeReaderInterface      import ScanCodeReaderInterface                  #
from AppInterfaces.AppReaderInterfaces.WebReaderInterface           import WebReaderInterface                       #
from AppInterfaces.AppReaderInterfaces.MicroscopeReaderInterface    import MicroscopeReaderInterface                #
from AppInterfaces.AppReaderInterfaces.ManipulatorReaderInterface   import ManipulatorReaderInterface               #
from AppInterfaces.AppReaderInterfaces.MotionReaderInterface        import MotionReaderInterface                    #

class HardWareManagerInterface(ManagerInterface):
    IOLocker        : Qt.QReadWriteLock = Qt.QReadWriteLock()
    Camera          : CameraReaderInterface           # 相机模块
    Motion          : MotionReaderInterface           # 运动模块
    ScanCode        : ScanCodeReaderInterface         # 扫码模块
    WebServer       : WebReaderInterface              # 服务接口
    StatusTimer     : Qt.QTimer                       # 定时模块
    Index           : int                             # 定时序号
    Heartbeat       : bool                            # 心跳状态

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

    @property
    def isHeartbeat(self) -> bool:
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        return self.hasHeatBeat and self.Heartbeat

    def setHeartbeat(self, enable: (bool, int) =  True):
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.Heartbeat = True if isinstance(enable, (bool, int)) and enable else False

    @property
    def statustimer(self) -> Qt.QTimer:
        return None if not self.hasStatusTimer else self.StatusTimer

    @property
    def index(self) -> int:
        return 0 if not self.hasIndex else self.Index

    @property
    def camera(self) -> CameraReaderInterface:
        return None if not self.hasCamera else self.Camera

    @property
    def motion(self) -> MotionReaderInterface:
        return None if not self.hasMotion else self.Motion


    @property
    def scancode(self) -> ScanCodeReaderInterface:
        return None if not self.hasScanCode else self.ScanCode

    @property
    def webserver(self) -> WebReaderInterface:
        return None if not self.hasWebServer else self.WebServer


    @property
    def axis_z(self) -> AxisImplInterface:
        return self.manipulator.axis_z if self.hasAxisZ else None

    @property
    def axis_h(self) -> HookImplInterface:
        return self.manipulator.axis_h if self.hasAxisH else None


    @property
    def hasAxisZ(self):
        return self.hasManipulator and self.manipulator.hasAxisZ

    @property
    def hasAxisH(self) -> bool:
        return self.hasManipulator and self.manipulator.hasAxisH




    @property
    def manipulator(self) -> ManipulatorReaderInterface:
        return None if not self.hasMotion else self.motion.manipulator

    @property
    def microscope(self) -> MicroscopeReaderInterface:
        return None if not self.hasMotion else self.motion.microscope

    @property
    def detection(self) -> DetectionImplInterface:
        return None if not self.hasManipulator else self.manipulator.detector

    @property
    def manager(self) -> ModBusPoolInterface:
        return None if not self.hasMotion else self.motion.manager

    @property
    def hasManipulator(self) -> bool:
        return self.hasMotion and self.motion.hasManipulator

    @property
    def hasMicroscope(self) -> bool:
        return self.hasMotion and self.motion.hasMicroscope

    @property
    def hasDetection(self) -> bool:
        return self.hasManipulator and self.manipulator.hasDetector

    @property
    def hasManagerPool(self) -> bool:
        return self.hasMotion and self.motion.hasManager

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

    @property
    def hasMotion(self) -> bool:
        return hasattr(self, 'Motion') and isinstance(self.Motion, MotionReaderInterface)


    @property
    def hasScanCode(self) -> bool:
        return hasattr(self, 'ScanCode') and isinstance(self.ScanCode, ScanCodeReaderInterface)


    @property
    def hasWebServer(self) -> bool:
        return hasattr(self, 'WebServer') and isinstance(self.WebServer, WebReaderInterface)

    @property
    def hasStatusTimer(self) -> bool:
        return hasattr(self, 'StatusTimer') and isinstance(self.StatusTimer, Qt.QTimer)

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

    @abstractmethod
    def initStatusTimer(self):
        pass

    @abstractmethod
    def initCamera(self):
        pass

    @abstractmethod
    def initMotion(self):
        pass


    @abstractmethod
    def initScanCode(self):
        pass

    @abstractmethod
    def initWebServer(self):
        pass

    @abstractmethod
    def initDevices(self):
        pass

    @abstractmethod
    def UpdateDeviceStatus(self):
        pass


    def StartStatusTimer(self):
        if not self.hasStatusTimer:
            self.initStatusTimer()
        self.statustimer.start()

    def StopStatusTimer(self):
        if not self.hasStatusTimer:
            return
        if self.statustimer.isActive():
            self.statustimer.stop()

    @abstractmethod
    def waitForManipulatorHome(self) -> bool:
        pass

    @abstractmethod
    def waitForMicroscopeHome(self) -> bool:
        pass

    @abstractmethod
    def waitForDetectionHome(self) -> bool:
        pass

    @abstractmethod
    def waitForSlideTableHome(self) -> bool:
        pass


    @abstractmethod
    def waitForMotionHome(self) -> bool:
        pass

    @abstractmethod
    def waitmoveForSafe(self) -> bool:
        pass

    @abstractmethod
    def waitForDeviceHome(self) -> bool:
        pass

    @abstractmethod
    def waitForStartSocketServer(self) -> bool:
        pass

    @abstractmethod
    def waitForCamera(self) -> bool:
        pass

    @abstractmethod
    def waitForScanCode(self) -> bool:
        pass

    @abstractmethod
    def CodeScanning(self, waittimes: int = 3000) -> (int, str):
        pass

    @abstractmethod
    def getCurrentObjective(self, maxcount: int = 3) -> (int, int):
        pass

    @abstractmethod
    def changedObjective(self, level: int, is_lower_limit: bool = True, maxcount: int = 3) -> int:
        pass

    @abstractmethod
    def changedOilStatus(self, enable: (bool, int), maxcount: int = 3) -> int:
        pass



    @abstractmethod
    def SlotStatusTimerTimeOut(self):
        pass

    @property
    def isWebServerAvailable(self) -> bool:
        return self.hasWebServer and self.webserver.isAvailable

    @property
    def isCameraAvailable(self) -> bool:
        return self.hasCamera and self.camera.isAvailable


    @property
    def isScanCodeAvailable(self) -> bool:
        return self.hasScanCode and self.ScanCode.isAvailable

    @property
    def isManipulatorAvailable(self) -> bool:
        return self.hasManipulator and self.manipulator.isAvailable

    @property
    def isMicroscopeAvailable(self) -> bool:
        return self.hasMicroscope and self.microscope.isAvailable

    @property
    def isDetectionAvailable(self) -> bool:
        return self.hasDetection and self.detection.isAvailable
