#!D:/IDE/anaconda3/envs/Microscope_Scan python
# -*- coding: UTF-8 -*-
"""
@FileName：HardWareManagerInterface.py
@Description：
@Author：XSH
@Time：2025/11/11 16:19
@Department：研发部
@Copyright：©2025 乐辰生物
"""
from PyQt5 import Qt
from abc import abstractmethod
from AppInterfaces.ReaderInterface import ReaderInterface
from AppInterfaces.ManagerInterface import ManagerInterface
from AppInterfaces.ReaderInterfaces import *
from AppInterfaces.ImplInterfaces import *

class HardWareManagerInterface(ManagerInterface):
    Camera      : CameraReaderInterface     #
    Motion      : MotionReaderInterface     #
    ScanCode    : ScanCodeReaderInterface   #
    WebSocket   : WebReaderInterface        #
    StatusTimer : Qt.QTimer                 #
    Index       : int                       #
    @property
    @abstractmethod
    def isValid(self) -> bool:
        pass

    @property
    @abstractmethod
    def isAvailable(self) -> bool:
        raise Exception('Interface Instance error')

    @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.hasWebSocket else self.WebSocket

    @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.hasMotion else self.motion.detection


    @property
    def axis_x(self) -> AxisImplInterface:
        return self.manipulator.AxisX if self.hasAxisX else None

    @property
    def axis_y(self) -> AxisImplInterface:
        return self.manipulator.AxisY if self.hasAxisY else None

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

    @property
    def scan_x(self) -> AxisImplInterface:
        return self.manipulator.ScanX if self.hasScanX else None

    @property
    def scan_y(self) -> AxisImplInterface:
        return self.manipulator.ScanY if self.hasScanY else None

    @property
    def slow_x(self) -> AxisImplInterface:
        return self.manipulator.SlowX if self.hasSlowX else None

    @property
    def slow_y(self) -> AxisImplInterface:
        return self.manipulator.SlowY if self.hasSlowY else None

    @property
    def drop_x(self) -> AxisImplInterface:
        return self.manipulator.DropX if self.hasDropX else None

    @property
    def drop_y(self) -> AxisImplInterface:
        return self.manipulator.DropY if self.hasDropY else None

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

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

    @property
    def hasAxisX(self) -> bool:
        return False if not self.hasManipulator else self.manipulator.hasAxisX

    @property
    def hasAxisY(self) -> bool:
        return False if not self.hasManipulator else self.manipulator.hasAxisY

    @property
    def hasAxisH(self) -> bool:
        return False if not self.hasManipulator else self.manipulator.hasAxisH

    @property
    def hasScanX(self) -> bool:
        return False if not self.hasManipulator else self.manipulator.hasScanX

    @property
    def hasScanY(self) -> bool:
        return False if not self.hasManipulator else self.manipulator.hasScanY

    @property
    def hasSlowX(self) -> bool:
        return False if not self.hasManipulator else self.manipulator.hasSlowX

    @property
    def hasSlowY(self) -> bool:
        return False if not self.hasManipulator else self.manipulator.hasSlowY

    @property
    def hasDropX(self) -> bool:
        return False if not self.hasManipulator else self.manipulator.hasDropX

    @property
    def hasDropY(self) -> bool:
        return False if not self.hasManipulator else self.manipulator.hasDropY

    @property
    def hasTrayZ(self) -> bool:
        return False if not self.hasManipulator else self.manipulator.hasAxisZ

    @property
    def hasDetector(self) -> bool:
        return False if not self.hasManipulator else self.manipulator.hasDetector

    @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 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 hasWebSocket   (self) -> bool:
        return hasattr(self, 'WebSocket'    ) and isinstance(self.WebSocket   , 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 initHitBot(self):
        pass

    @abstractmethod
    def initScanCode(self):
        pass

    @abstractmethod
    def initWebSocket(self):
        pass

    @abstractmethod
    def initDevices(self):
        pass

    @abstractmethod
    def UpdateDeviceStatus(self):
        pass

    @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 waitForHitBotHome(self) -> bool:
        pass

    @abstractmethod
    def waitForMotionHome(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 changedObjective(self, level: int, is_lower_limit: bool = True, maxcount: int = 3) -> int:
        pass


    @abstractmethod
    def SlotStatusTimerTimeOut(self):
        pass

    @property
    def isWebServerAvailable(self) -> bool:
        return self.hasWebSocket 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 isDetectorAvailable(self) -> bool:
        return self.hasDetector and self.detector.isAvailable
