#!D:/IDE/anaconda3/envs/Microscope_Scan python
# -*- coding: UTF-8 -*-
"""
@FileName：ManipulatorReaderInterface.py
@Description：
@Author：XSH
@Time：2025/11/11 15:03
@Department：研发部
@Copyright：©2025 乐辰生物
"""
from abc import abstractmethod
from AppSettings.Settings import *
from AppInterfaces.AppImplInterfaces.ModBusPoolInterface import ModBusImplInterface
from AppInterfaces.AppImplInterfaces.AxisImplInterface import AxisImplInterface
from AppInterfaces.AppImplInterfaces.DetectionImplInterface import DetectionImplInterface, ModBusPoolInterface
from AppInterfaces.AppImplInterfaces.HookImplInterface import HookImplInterface
from AppInterfaces.ReaderInterface import ReaderInterface
from AppUtils.HardWareUnit import HardWareUnit
class ManipulatorReaderInterface(ReaderInterface):
    Manager     : ModBusPoolInterface
    AxisX       : AxisImplInterface
    AxisY       : AxisImplInterface
    AxisZ       : AxisImplInterface
    AxisH       : HookImplInterface
    ScanX       : AxisImplInterface
    ScanY       : AxisImplInterface
    SlowX       : AxisImplInterface
    SlowY       : AxisImplInterface
    DropX       : AxisImplInterface
    DropY       : AxisImplInterface
    Detector    : DetectionImplInterface
    @property
    def hasManager(self) -> bool:
        return hasattr(self, 'Manager') and isinstance(self.Manager, ModBusPoolInterface)

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


    def isValid(self) -> bool:
        return self.hasParameter and self.hasManager and self.hasLevel

    def IsOpen(self) -> bool:
        pass

    def setManager(self, manager: ModBusPoolInterface):
        self.Manager = manager
        if self.hasAxisX       :
            self.AxisX       .setManager(self.manager)
        if self.hasAxisY       :
            self.AxisY       .setManager(self.manager)
        if self.hasAxisZ       :
            self.AxisZ       .setManager(self.manager)
        if self.hasAxisH       :
            self.AxisH       .setManager(self.manager)
        if self.hasScanX       :
            self.ScanX       .setManager(self.manager)
        if self.hasScanY       :
            self.ScanY       .setManager(self.manager)
        if self.hasSlowX       :
            self.SlowX       .setManager(self.manager)
        if self.hasSlowY       :
            self.SlowY       .setManager(self.manager)
        if self.hasDropX       :
            self.DropX       .setManager(self.manager)
        if self.hasDropY       :
            self.DropY       .setManager(self.manager)
        if self.hasDetector    :
            self.Detector    .setManager(self.manager)




    @property
    def isDisable(self) -> bool:
        return not self.isValid() or not self.IsOpen()

    @property
    def isAvailable(self) -> bool:
        return self.IsOpen()

    def Open(self, **args) -> int:
        self.initManager()
        if not self.IsOpen():
            self.Manager.Open()
        return RECODE_SUCCEED if self.IsOpen else RECODE_FAILURE

    def Close(self, **args) -> int:
        if self.hasManager:
            self.Manager.Close()

        return RECODE_SUCCEED if not self.IsOpen else RECODE_FAILURE

    @abstractmethod
    def initManager(self, **args):
        raise Exception('Interface Instance error')

    @abstractmethod
    def deleManager(self, **args):
        raise Exception('Interface Instance error')

    @abstractmethod
    def Transmit(self, **args) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def Received(self, **args) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def Send(self, **args) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def Read(self, **args) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def WaitDone(self, **args) -> int:
        raise Exception('Interface Instance error')

    def ReOpen(self, timeOut: int = 1000, **args) -> int:
        self.Close(timeOut=timeOut, **args)
        return self.Open(timeOut=timeOut, **args)

    def isTrayAvailable(self) -> int:
        isWrong: int = RECODE_FAILURE
        if self.hasAxisH:
            isWrong = self.axis_h.isTrayAvailable()
        return isWrong

    def position_x(self) -> (int, float):
        return HardWareUnit.get_axis_position(self.axis_x)


    def position_xy(self) -> (int, float, float):
        isWrong, x, y = HardWareUnit.get_axis_position_xy(self.axis_x, self.axis_y)
        return isWrong, x, y


    def position_y(self) -> (int, float):
        return HardWareUnit.get_axis_position(self.axis_y)


    def position_z(self) -> (int, float):
        return HardWareUnit.get_axis_position(self.axis_z)


    def position_h(self) -> (int, float):
        return HardWareUnit.get_axis_position(self.axis_h)


    def home_x(self) -> int:
        return HardWareUnit.axis_home(self.axis_x)


    def home_y(self) -> int:
        return HardWareUnit.axis_home(self.axis_y)


    def home_z(self) -> int:
        return HardWareUnit.axis_home(self.axis_z)


    def home_h(self) -> int:
        return HardWareUnit.axis_home(self.axis_h)

    def home_xy(self, **args) -> int:
        return HardWareUnit.axis_home_xy(self.axis_y, self.axis_x)


    def waithome_x(self) -> int:
        return HardWareUnit.axis_waithome(self.axis_x)


    def waithome_y(self) -> int:
        return HardWareUnit.axis_waithome(self.axis_y)


    def waithome_z(self) -> int:
        return HardWareUnit.axis_waithome(self.axis_z)


    def waithome_h(self) -> int:
        return HardWareUnit.axis_waithome(self.axis_h)

    def rel_move_x(self, position: (int, float), **args) -> int:
        return HardWareUnit.axis_rel_move(self.axis_x, position, **args)


    def rel_waitmove_x(self, position: (int, float), **args) -> int:
        return HardWareUnit.axis_rel_waitmove(self.axis_x, position, **args)


    def rel_move_y(self, position: (int, float), **args) -> int:
        return HardWareUnit.axis_rel_move(self.axis_y, position, **args)


    def rel_waitmove_y(self, position: (int, float), **args) -> int:
        return HardWareUnit.axis_rel_waitmove(self.axis_y, position, **args)


    def rel_move_z(self, position: (int, float), **args) -> int:
        return HardWareUnit.axis_rel_move(self.axis_z, position, **args)


    def rel_waitmove_z(self, position: (int, float), **args) -> int:
        return HardWareUnit.axis_rel_waitmove(self.axis_z, position, **args)

    def rel_move_xy(self, x_position: (int, float), y_position: (int, float), **args) -> int:
        return HardWareUnit.axis_rel_move_xy(self.axis_x, self.axis_y, x_position, y_position)

    def rel_waitmove_xy(self, x_position: (int, float), y_position: (int, float), **args) -> int:
        return HardWareUnit.axis_rel_waitmove_xy(self.axis_x, self.axis_y, x_position, y_position)


    def move_x(self, position: (int, float), **args) -> int:
        return HardWareUnit.axis_move(self.axis_x, position, **args)


    def waitmove_x(self, position: (int, float), **args) -> int:
        return HardWareUnit.axis_waitmove(self.axis_x, position, **args)


    def move_y(self, position: (int, float), **args) -> int:
        return HardWareUnit.axis_move(self.axis_y, position, **args)


    def waitmove_y(self, position: (int, float), **args) -> int:
        return HardWareUnit.axis_waitmove(self.axis_y, position, **args)


    def move_z(self, position: (int, float), **args) -> int:
        return HardWareUnit.axis_move(self.axis_z, position, **args)


    def waitmove_z(self, position: (int, float), **args) -> int:
        return HardWareUnit.axis_waitmove(self.axis_z, position, **args)


    def move_h(self, position: (int, float), **args) -> int:
        return RECODE_FAILURE


    def waitmove_h(self, position: (int, float), **args) -> int:
        return RECODE_FAILURE


    def waithome_xy(self, **args) -> int:
        return HardWareUnit.axis_waithome_xy(self.axis_y, self.axis_x)


    def move_xy(self, xPosition: (float, int), yPosition: (float, int), **args) -> int:
        return HardWareUnit.axis_move_xy(self.axis_x, self.axis_y, xPosition, yPosition)


    def waitmove_xy(self, xPosition: (float, int), yPosition: (float, int), **args) -> int:
        return HardWareUnit.axis_waitmove_xy(self.axis_x, self.axis_y, xPosition, yPosition)

    def reload_velocity(self, **args):
        isWrong: int = RECODE_FAILURE

    def reload_axis_speed(self, **args):
        HardWareUnit.axis_xy_load_velocity(self.axis_x, self.axis_y)

    def reload_scan_speed(self, isSlow: bool = False, **args):
        if isSlow:
            HardWareUnit.axis_xy_load_velocity(self.slow_x, self.slow_y)
        else:
            HardWareUnit.axis_xy_load_velocity(self.scan_x, self.scan_y)

    def reload_oil_speed(self, **args):
        HardWareUnit.axis_xy_load_velocity(self.drop_x, self.drop_y)

    def reload_anointing_speed(self, **args):
        HardWareUnit.axis_xy_load_velocity(self.drop_x, self.drop_y)

    def reset_scanning(self, x: (int, float), y: (int, float), **args) -> int:
        isWrong: int = HardWareUnit.axis_waitmove_xy(self.axis_x, self.axis_y, x, y)
        HardWareUnit.axis_xy_load_velocity(self.scan_x, self.scan_y)
        return isWrong

    def reset_oiling(self, x: (int, float), y: (int, float), **args) -> int:
        HardWareUnit.axis_xy_load_velocity(self.drop_x, self.drop_y)
        return HardWareUnit.axis_waitmove_xy(self.drop_x, self.drop_y, x, y)

    def reset_moving(self, x: (int, float), y: (int, float), **args) -> int:
        HardWareUnit.axis_xy_load_velocity(self.axis_x, self.axis_y)
        return HardWareUnit.axis_waitmove_xy(self.axis_x, self.axis_y, x, y)

    def reset_slow_scanning(self, x: (int, float), y: (int, float), **args) -> int:
        isWrong: int = HardWareUnit.axis_waitmove_xy(self.slow_x, self.slow_y, x, y)
        HardWareUnit.axis_xy_load_velocity(self.scan_x, self.scan_y)
        return isWrong

    def start_dropoiling(self, x: (float, int), y: (float, int), **args):
        isWrong: int = HardWareUnit.axis_waitmove_xy(self.axis_x, self.axis_y, x, y)
        HardWareUnit.axis_xy_load_velocity(self.drop_x, self.drop_y)
        return isWrong

    def start_anointing_xy(self, x: (float, int), y: (float, int), **args):
        isWrong: int = HardWareUnit.axis_waitmove_xy(self.axis_x, self.axis_y, x, y)
        HardWareUnit.axis_xy_load_velocity(self.drop_x, self.drop_y)
        return isWrong

    def start_scanning_xy(self, x: (float, int), y: (float, int), **args) -> int:
        isWrong: int = HardWareUnit.axis_waitmove_xy(self.axis_x, self.axis_y, x, y)
        HardWareUnit.axis_xy_load_velocity(self.scan_x, self.scan_y)
        return isWrong

    def start_focusing_xy(self, x: (float, int), y: (float, int), **args) -> int:
        HardWareUnit.axis_xy_load_velocity(self.axis_x, self.axis_y)
        isWrong: int = HardWareUnit.axis_waitmove_xy(self.axis_x, self.axis_y, x, y)
        return isWrong

    def start_droping_xy(self, x: (float, int), y: (float, int), **args) -> int:
        HardWareUnit.axis_xy_load_velocity(self.drop_x, self.drop_y)
        isWrong: int = HardWareUnit.axis_waitmove_xy(self.axis_x, self.axis_y, x, y)
        return isWrong

    def waitmove_scanning_xy(self, x: (float, int), y: (float, int), **args) -> (int, str):
        begin: Qt.QDateTime = Qt.QDateTime.currentDateTime()
        isWrong: int = HardWareUnit.axis_waitmove_xy(self.axis_x, self.axis_y, x, y)
        return isWrong, f'移动XY时长{begin.msecsTo(Qt.QDateTime.currentDateTime())}ms'

    def waitmove_slow_scanning_xy(self, x: (float, int), y: (float, int), **args) -> (int, str):
        begin: Qt.QDateTime = Qt.QDateTime.currentDateTime()
        isWrong: int = HardWareUnit.axis_waitmove_xy(self.axis_x, self.axis_y, x, y)
        return isWrong, f'移动XY时长{begin.msecsTo(Qt.QDateTime.currentDateTime())}ms'

    def waitmove_focusing_xy(self, x: (float, int), y: (float, int), **args) -> (int, str):
        begin: Qt.QDateTime = Qt.QDateTime.currentDateTime()
        isWrong: int = HardWareUnit.axis_waitmove_xy(self.axis_x, self.axis_y, x, y)
        return isWrong, f'移动XY时长{begin.msecsTo(Qt.QDateTime.currentDateTime())}ms'

    def waitmove_droping_xy(self, x: (float, int), y: (float, int), **args) -> (int, str):

        begin: Qt.QDateTime = Qt.QDateTime.currentDateTime()
        isWrong: int = HardWareUnit.axis_waitmove_xy(self.drop_x, self.drop_y, x, y)

        return isWrong, f'移动XY时长{begin.msecsTo(Qt.QDateTime.currentDateTime())}ms'

    def waitmove_anointing_xy(self, x: (float, int), y: (float, int), **args) -> (int, str):
        begin: Qt.QDateTime = Qt.QDateTime.currentDateTime()
        isWrong: int = HardWareUnit.axis_waitmove_xy(self.drop_x, self.drop_y, x, y)
        return isWrong, f'移动XY时长{begin.msecsTo(Qt.QDateTime.currentDateTime())}ms'

    def waitmove_celling_xy(self, x: (float, int), y: (float, int), **args) -> (int, str):
        begin: Qt.QDateTime = Qt.QDateTime.currentDateTime()
        isWrong: int = HardWareUnit.axis_waitmove_xy(self.axis_x, self.axis_y, x, y)
        return isWrong, f'移动XY时长{begin.msecsTo(Qt.QDateTime.currentDateTime())}ms'

    def setScanMoveEnable(self, enable: bool):
       return HardWareUnit.axis_move_enable_xy(self.scan_x, self.scan_y, enable)


    def setMoveEnable(self, enable: bool):
        return HardWareUnit.axis_move_enable_xy(self.axis_x, self.axis_y, enable)


    def setSlowEnable(self, enable: bool):
        return HardWareUnit.axis_move_enable_xy(self.slow_x, self.slow_y, enable)

    @abstractmethod
    def initAxisX   (self):
        raise Exception('Interface Instance error')

    @abstractmethod
    def initAxisY   (self):
        raise Exception('Interface Instance error')

    @abstractmethod
    def initAxisH   (self):
        raise Exception('Interface Instance error')

    @abstractmethod
    def initScanX   (self):
        raise Exception('Interface Instance error')

    @abstractmethod
    def initScanY   (self):
        raise Exception('Interface Instance error')

    @abstractmethod
    def initSlowX   (self):
        raise Exception('Interface Instance error')

    @abstractmethod
    def initSlowY   (self):
        raise Exception('Interface Instance error')

    @abstractmethod
    def initDropX   (self):
        raise Exception('Interface Instance error')

    @abstractmethod
    def initDropY   (self):
        raise Exception('Interface Instance error')

    @abstractmethod
    def initDetector(self):
        raise Exception('Interface Instance error')

    @abstractmethod
    def initAxisZ(self):
        raise Exception('Interface Instance error')

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

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

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

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

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

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

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

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

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

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

    @property
    def hasAxisX (self) -> bool:
        return hasattr(self, 'AxisX') and isinstance(self.AxisX, AxisImplInterface)

    @property
    def hasAxisY (self) -> bool:
        return hasattr(self, 'AxisY') and isinstance(self.AxisY, AxisImplInterface)

    @property
    def hasAxisH (self) -> bool:
        return hasattr(self, 'AxisH') and isinstance(self.AxisH, HookImplInterface)

    @property
    def hasScanX (self) -> bool:
        return hasattr(self, 'ScanX') and isinstance(self.ScanX, AxisImplInterface)

    @property
    def hasScanY (self) -> bool:
        return hasattr(self, 'ScanY') and isinstance(self.ScanY, AxisImplInterface)

    @property
    def hasSlowX (self) -> bool:
        return hasattr(self, 'SlowX') and isinstance(self.SlowX, AxisImplInterface)

    @property
    def hasSlowY (self) -> bool:
        return hasattr(self, 'SlowY') and isinstance(self.SlowY, AxisImplInterface)

    @property
    def hasDropX (self) -> bool:
        return hasattr(self, 'DropX') and isinstance(self.DropX, AxisImplInterface)

    @property
    def hasDropY (self) -> bool:
        return hasattr(self, 'DropY') and isinstance(self.DropY, AxisImplInterface)

    @property
    def hasAxisZ(self) -> bool:
        return hasattr(self, 'AxisZ') and isinstance(self.AxisZ, AxisImplInterface)

    @property
    def hasDetector(self) -> bool:
        return hasattr(self, 'Detector') and isinstance(self.Detector, DetectionImplInterface)

    @property
    def handler(self) -> ModBusImplInterface:
        handler: ModBusImplInterface = None
        if self.isValid:
            handler = self.manager.handle
        return handler

    @property
    def readhandler(self) -> ModBusImplInterface:
        handler: ModBusImplInterface = None
        if self.isValid:
            handler = self.manager.readhandler
        return handler

    @property
    def detectorhandler(self) -> ModBusImplInterface:
        handler: ModBusImplInterface = None
        if self.isValid:
            handler = self.manager.detectorhandler
        return handler

    @property
    def slow_handler(self) -> ModBusImplInterface:
        handler: ModBusImplInterface = None
        if self.isValid:
            handler = self.manager.slow_handler
        return handler

    @property
    def scan_handler(self) -> ModBusImplInterface:
        handler: ModBusImplInterface = None
        if self.isValid:
            handler = self.manager.scan_handler
        return handler

    @property
    def drop_handler(self) -> ModBusImplInterface:
        handler: ModBusImplInterface = None
        if self.isValid:
            handler = self.manager.drop_handler
        return handler

    @property
    def hook_handler(self) -> ModBusImplInterface:
        handler: ModBusImplInterface = None
        if self.isValid:
            handler = self.manager.hook_handler
        return handler

