#!D:/IDE/anaconda3/envs/Microscope_Scan python
# -*- coding: UTF-8 -*-
"""
@FileName：AppStatusSetting.py
@Description：
@Author：XSH
@Time：2025/11/12 12:05
@Department：研发部
@Copyright：©2025 乐辰生物
"""
from PyQt5 import Qt
import asyncio
from qasync import QEventLoop, asyncSlot
from datetime import date, datetime
from AppInterfaces.ConfigureInterfaces import StatusConfigInterface
from AppInterfaces.SingletonInterface import SingletonInterface
from AppInterfaces.GlobalInterface import GlobalInterface
from AppInterfaces.AppTimeLoop import AppTimeLoop
from AppUtils.AppUtils import AppUtils
from AppCore.Levels import *
from decimal import Decimal


class AppStatusSetting(StatusConfigInterface, SingletonInterface):
    Locker  : Qt.QMutex         = Qt.QMutex         ()


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



    def __init__(self, *args, **kwargs):
        super(AppStatusSetting, self).__init__()
        self.initialization('AppStatusSetting')

    def initValue(self):
        super(AppStatusSetting, self).initValue()
        self.ID                       = None
        self.ObjectiveLevel           = None
        self.ChamberGroupNumber       = None
        self.ChamberRowNumber         = None
        self.TrayNumber               = None
        self.RowNumber                = None
        self.ColNumber                = None
        self.ScanStatus               = None
        self.RunStatus                = None
        self.Template_ID              = None
        self.PreferredClassifier_ID   = None
        self.PreviewClassifier_ID     = None
        self.CollectClassifier_ID     = None
        self.User_ID                  = None
        self.OperatingStatus_ID       = None
        self.CodeString               = None
        self.ScanningDateTime         = None
        self.StopScanningDateTime     = None
        self.Microscope                 = 0
        self.WebSocket                  = 0
        self.HitBot                     = 0
        self.AxisX                      = 0
        self.AxisY                      = 0
        self.TrayZ                      = 0
        self.TrayH                      = 0
        self.Camera                     = 0
        self.ColorCamera                = 0
        self.ScanCode                   = 0
        self.Oil                        = 0
        self.Chamber                    = 0
        self.Buzzer                     = 0
        self.Door                       = 0
        self.TrayStatus                 = 0
        self.AutoScanMode               = 1
        self.JumpScanning               = 0
        self.CameraModel                = None

    def getChamberSlide(self, chamber_number: int, row_number: int) -> 'SlideModelInterface':
        """获取当前片仓玻片对象"""
        from AppCore.AppDBModels.SlideModels.ChamberStatusModel import ChamberStatusModel
        return ChamberStatusModel.getStatusModel(chamber_number, row_number)

    def getSlideScanTemplate(self, chamber_number: int, row_number: int) -> ('ScanTemplate', 'Previewsettings', 'Collectsettings'):
        """获取当前扫描玻片模板类"""
        from AppCore.DBModels import ScanTemplate, Previewsettings, Collectsettings, CustomScanningModel
        Template    : ScanTemplate                #
        Preview     : Previewsettings             #
        Collect     : Collectsettings             #
        Template, Preview, Collect = CustomScanningModel.template(chamber_number, row_number)
        return Template, Preview, Collect

    def setScanningSlide(self, chamber_number: int, row_number: int, tray_number: int, objective: int, level: int,templateID: int, codestring: str):
        """设置当前扫描玻片信息"""
        from AppCore.DBModels import ScanStatusModel, ChamberStatusModel, ScanTemplate
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.ChamberGroupNumber     = chamber_number  #
        self.ChamberRowNumber       = row_number  #
        self.TrayNumber             = tray_number  #
        self.CodeString             = codestring  #
        self.Template_ID            = templateID  #
        self.ObjectiveLevel         = objective  #
        self.ScanStatus             = level  #

        ScanStatusModel.setCurrentScanningTrayNumber(self.ChamberGroupNumber, self.ChamberRowNumber, self.TrayNumber, self.ObjectiveLevel, self.Template_ID, self.CodeString)
        ScanStatusModel.setScanStatus(self.ScanStatus)
        Template: ScanTemplate = ScanTemplate.Primary(self.Template_ID)
        if isinstance(Template, ScanTemplate):
            self.PreviewClassifier_ID = Template.previewsettings_ID
            self.CollectClassifier_ID = Template.collectsettings_ID
        ChamberStatusModel.setCurrentScanningStatus(self.ChamberGroupNumber, self.ChamberRowNumber, self.ScanStatus, self.Template_ID)


    def setCollectCount(self, chamber_number: int, row_number: int, tray_number: int, objective: int, collectcount: int):
        from AppCore.DBModels import ChamberStatusModel, SpecimenCountModel
        ChamberStatusModel.setCollectCount(chamber_number, row_number, tray_number, objective, collectcount)
        item: ChamberStatusModel = ChamberStatusModel.getStatusModel(chamber_number, row_number)
        SpecimenCountModel.setCollectCount(chamber_number, row_number, tray_number, objective, collectcount, item.CodeString, item.SpecimenNumber, item.SlideNumber)



    def setPreviewCount(self, chamber_number: int, row_number: int, tray_number: int, objective: int, previewcount: int):
        from AppCore.DBModels import ChamberStatusModel, SpecimenCountModel
        ChamberStatusModel.setPreviewCount(chamber_number, row_number, tray_number, objective, previewcount)
        item: ChamberStatusModel = ChamberStatusModel.getStatusModel(chamber_number, row_number)
        SpecimenCountModel.setPreviewCount(chamber_number, row_number, tray_number, objective, previewcount, item.CodeString, item.SpecimenNumber, item.SlideNumber)



    def setTrayFocusingCount(self, level: int, focusingNumber: int):
        from AppCore.AppDBModels.TrayModels.TrayModel import TrayModel
        TrayModel.setFocusingCount(level, focusingNumber)


    def getTrayFocusingCount(self, level: int) -> int:
        from AppCore.AppDBModels.TrayModels.TrayModel import TrayModel
        return TrayModel.getFocusingCount(level)

    """片仓状态"""
    def InitTrayStatus(self, chamber_number: int):
        from AppCore.AppDBModels.SlideModels.ChamberStatusModel import ChamberStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        ChamberStatusModel.InitCheckStatus(chamber_number)

    def InitChamberStatus(self):
        from AppCore.AppDBModels.SlideModels.ChamberStatusModel import ChamberStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        ChamberStatusModel.InitAllCheckStatus()

    def GetTrayDetectorStatus(self, chamber_number: int, row_number: int = 1, **args) -> int:
        from AppCore.AppDBModels.SlideModels.ChamberStatusModel import ChamberStatusModel
        return ChamberStatusModel.IsCheckAvailable(chamber_number, row_number)

    def GetChamberStatus(self, chamber_number: int, **args) -> int:
        from AppCore.AppDBModels.SlideModels.ChamberStatusModel import ChamberStatusModel
        row_number: int
        isCheckStatus: bool = False
        for row_number in range(1, 5):
            isCheckStatus = ChamberStatusModel.IsCheckAvailable(chamber_number, row_number)
            if isCheckStatus:
                break
        return isCheckStatus

    def SetTrayDetectorStatus(self, chamber_number: int, status: (int, bool)):
        from AppCore.AppDBModels.SlideModels.ChamberStatusModel import ChamberStatusModel
        return ChamberStatusModel.setChamberTrayStatus(chamber_number, status)

    def SetTraySlideDetectorStatus(self, chamber_number: int, row_number: int, status: (int, bool)):
        from AppCore.AppDBModels.SlideModels.ChamberStatusModel import ChamberStatusModel
        return ChamberStatusModel.setChamberTraySlideStatus(chamber_number, row_number, status)

    def SetChamberDetectorStatus(self, status: list[int]):
        from AppCore.AppDBModels.SlideModels.ChamberStatusModel import ChamberStatusModel
        return ChamberStatusModel.setChamberDetectorStatus(status)

    def UpdateScanStatus(self):
        from AppCore.AppDBModels.StateModels.ScanStatusModel import ScanStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        try:
            self.as_field(ScanStatusModel.first().to_field())
            self.ScanningDateTime       = None
            self.StopScanningDateTime   = None
        except Exception as e:
            AppUtils.print_Exception(e)
        pass


    def UpdateOperatingStatus(self):
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        try:
            self.as_field(OperatingStatusModel.first().to_field())
        except Exception as e:
            AppUtils.print_Exception(e)
        pass


    def getCameraModel(self, level: int) -> 'CameraInterface':
        from AppCore.AppDBModels.CameraModels.CameraModel import CameraModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.CameraModel = CameraModel.getConfig(level)
        return self.CameraModel

    def setCameraModel(self, level: int):
        from AppCore.AppDBModels.CameraModels.CameraModel import CameraModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.CameraModel = CameraModel.getConfig(level)

    def hasOperating(self) -> bool:
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        return OperatingStatusModel.isAvailable()


    def setRunStatus(self, status: int):
        from AppCore.AppDBModels.StateModels.ScanStatusModel import ScanStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.RunStatus = int(status) if status in RunStatusLevel.all() else self.RunStatus



    def getRunStatus(self) -> int:
        from AppCore.AppDBModels.StateModels.ScanStatusModel import ScanStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.RunStatus = ScanStatusModel.getRunStatus()
        return self.RunStatus

    def setPause(self, enable: (int, bool)):
        from AppCore.AppDBModels.StateModels.ScanStatusModel import ScanStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.RunStatus = RunStatusLevel.PauseRunning if isinstance(enable, (bool, int)) and enable else RunStatusLevel.Running
        ScanStatusModel.setRunStatus(self.RunStatus)

    def setExit(self, enable: (int, bool) = True):
        from AppCore.AppDBModels.StateModels.ScanStatusModel import ScanStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.RunStatus = RunStatusLevel.ExitRunning if isinstance(enable, (bool, int)) and enable else RunStatusLevel.Running
        ScanStatusModel.setRunStatus(self.RunStatus)

    def setRunning(self, enable: (int, bool) = True):
        from AppCore.AppDBModels.StateModels.ScanStatusModel import ScanStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.RunStatus = RunStatusLevel.Running if isinstance(enable, (bool, int)) and enable else RunStatusLevel.ExitRunning

        ScanStatusModel.setRunStatus(self.RunStatus)

    @property
    def isPause(self) -> bool:
        from AppCore.AppDBModels.StateModels.ScanStatusModel import ScanStatusModel
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        self.RunStatus = ScanStatusModel.getRunStatus()
        return self.RunStatus == RunStatusLevel.PauseRunning

    @property
    def isExit(self) -> bool:
        from AppCore.AppDBModels.StateModels.ScanStatusModel import ScanStatusModel
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        self.RunStatus = ScanStatusModel.getRunStatus()
        return self.RunStatus == RunStatusLevel.ExitRunning

    @property
    def isRunning(self) -> bool:
        from AppCore.AppDBModels.StateModels.ScanStatusModel import ScanStatusModel
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        self.RunStatus = ScanStatusModel.getRunStatus()
        return self.RunStatus == RunStatusLevel.Running

    @property
    def isRunAvailable(self) -> bool:
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        return OperatingStatusModel.isAvailable()


    def updateRunAvailable(self):
        self.setRunStatus(RunStatusLevel.Running if self.isRunAvailable else RunStatusLevel.ExitRunning)


    def initModuleAvailable(self):
        # self.setMicroscopeAvailable (False)
        self.setManipulatorAvailable(False)
        self.setCameraAvailable     (False)
        self.setJumpScanning        (False)
        self.setWebSocketAvailable  (False)
        self.setBuzzerAvailable     (False)
        self.setExit                (True )



    def setMicroscopeAvailable(self, enable: (int, bool)):
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.Microscope = 1 if isinstance(enable, (int, bool)) and enable else 0
        OperatingStatusModel.setMicroscopeAvailable(self.Microscope)

    def isManipulatorAvailable(self) -> int:
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        return OperatingStatusModel.isManipulatorAvailable()

    def setManipulatorAvailable(self, enable: (int, bool)):
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        _enable: int = 1 if isinstance(enable, (int, bool)) and enable else 0
        self.AxisX = _enable
        self.AxisY = _enable
        self.TrayZ = _enable
        self.TrayH = _enable
        return OperatingStatusModel.setManipulatorAvailable(enable)

    def setWebSocketAvailable(self, enable: (int, bool)):
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.WebSocket = 1 if isinstance(enable, (int, bool)) and enable else 0
        OperatingStatusModel.setWebSocketAvailable(self.WebSocket)

    
    def setHitBotAvailable(self, enable: (int, bool)):
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.HitBot = 1 if isinstance(enable, (int, bool)) and enable else 0
        OperatingStatusModel.setHitBotAvailable(self.HitBot)

    
    def setAxisXAvailable(self, enable: (int, bool)):
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.AxisX = 1 if isinstance(enable, (int, bool)) and enable else 0
        OperatingStatusModel.setAxisXAvailable(self.AxisX)

    
    def setAxisYAvailable(self, enable: (int, bool)):
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.AxisY = 1 if isinstance(enable, (int, bool)) and enable else 0
        OperatingStatusModel.setAxisYAvailable(self.AxisY)

    
    def setTrayZAvailable(self, enable: (int, bool)):
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.TrayZ = 1 if isinstance(enable, (int, bool)) and enable else 0
        OperatingStatusModel.setTrayZAvailable(self.TrayZ)

    
    def setTrayHAvailable(self, enable: (int, bool)):
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.TrayH = 1 if isinstance(enable, (int, bool)) and enable else 0
        OperatingStatusModel.setTrayHAvailable(self.TrayH)

    
    def setCameraAvailable(self, enable: (int, bool)):
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.Camera = 1 if isinstance(enable, (int, bool)) and enable else 0
        OperatingStatusModel.setCameraAvailable(self.Camera)

    
    def setColorCameraAvailable(self, enable: (int, bool)):
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.ColorCamera = 1 if isinstance(enable, (int, bool)) and enable else 0
        OperatingStatusModel.setColorCameraAvailable(self.ColorCamera)

    
    def setScanCodeAvailable(self, enable: (int, bool)):
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.ScanCode = 1 if isinstance(enable, (int, bool)) and enable else 0
        OperatingStatusModel.setScanCodeAvailable(self.ScanCode)

    
    def setOilAvailable(self, enable: (int, bool)):
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.Oil = 1 if isinstance(enable, (int, bool)) and enable else 0
        OperatingStatusModel.setOilAvailable(self.Oil)

    
    def setChamberAvailable(self, enable: (int, bool)):
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.Chamber = 1 if isinstance(enable, (int, bool)) and enable else 0
        OperatingStatusModel.setChamberAvailable(self.Chamber)

    
    def setBuzzerAvailable(self, enable: (int, bool)):
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.Buzzer = 1 if isinstance(enable, (int, bool)) and enable else 0
        OperatingStatusModel.setBuzzerAvailable(self.Buzzer)

    
    def setDoorAvailable(self, enable: (int, bool)):
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.Door = 1 if isinstance(enable, (int, bool)) and enable else 0
        OperatingStatusModel.setDoorAvailable(self.Door)

    
    def setTrayStatus(self, enable: (int, bool)):
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.TrayStatus = 1 if isinstance(enable, (int, bool)) and enable else 0
        OperatingStatusModel.setTrayStatus(self.TrayStatus)

    
    def setAutoScanMode(self, enable: (int, bool)):
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.AutoScanMode = 1 if isinstance(enable, (int, bool)) and enable else 0
        OperatingStatusModel.setAutoScanMode(self.AutoScanMode)

    
    def setJumpScanning(self, enable: (int, bool)):
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.JumpScanning = 1 if isinstance(enable, (int, bool)) and enable else 0
        OperatingStatusModel.setJumpScanning(self.JumpScanning)

    @property
    def isMicroscopeAvailable(self) -> int:
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        self.Microscope = OperatingStatusModel.isMicroscopeAvailable()
        return self.Microscope

    @property
    def isWebSocketAvailable(self) -> int:
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        self.WebSocket = OperatingStatusModel.isWebSocketAvailable()
        return self.WebSocket

    @property
    def isHitBotAvailable(self) -> int:
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        self.HitBot = OperatingStatusModel.isHitBotAvailable()
        return self.HitBot

    @property
    def isAxisXAvailable(self) -> int:
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        self.AxisX = OperatingStatusModel.isAxisXAvailable()
        return self.AxisX

    @property
    def isAxisYAvailable(self) -> int:
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        self.AxisY = OperatingStatusModel.isAxisYAvailable()
        return self.AxisY

    @property
    def isTrayZAvailable(self) -> int:
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        self.TrayZ = OperatingStatusModel.isTrayZAvailable()
        return self.TrayZ

    @property
    def isTrayHAvailable(self) -> int:
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        self.TrayH = OperatingStatusModel.isTrayHAvailable()
        return self.TrayH

    @property
    def isCameraAvailable(self) -> int:
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        self.Camera = OperatingStatusModel.isCameraAvailable()
        return self.Camera

    @property
    def isColorCameraAvailable(self) -> int:
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        self.ColorCamera = OperatingStatusModel.isColorCameraAvailable()
        return self.ColorCamera

    @property
    def isScanCodeAvailable(self) -> int:
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        self.ScanCode = OperatingStatusModel.isScanCodeAvailable()
        return self.ScanCode

    @property
    def isOilAvailable(self) -> int:
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        self.Oil = OperatingStatusModel.isOilAvailable()
        return self.Oil

    @property
    def isChamberAvailable(self) -> int:
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        self.Chamber = OperatingStatusModel.isChamberAvailable()
        return self.Chamber

    @property
    def isBuzzerAvailable(self) -> int:
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        self.Buzzer = OperatingStatusModel.isBuzzerAvailable()
        return self.Buzzer

    @property
    def isDoorAvailable(self) -> int:
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        self.Door = OperatingStatusModel.isDoorAvailable()
        return self.Door

    @property
    def isTrayStatus(self) -> int:
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        self.TrayStatus = OperatingStatusModel.isTrayStatus()
        return self.TrayStatus

    @property
    def isAutoScanMode(self) -> int:
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        self.AutoScanMode = OperatingStatusModel.isAutoScanMode()
        return self.AutoScanMode

    @property
    def isJumpScanning(self) -> int:
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        self.JumpScanning = OperatingStatusModel.isJumpScanning()
        return self.JumpScanning

    def clearWarning(self):
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.Buzzer    = RunStatusLevel.ExitRunning
        OperatingStatusModel.setBuzzerAvailable(self.Buzzer)

    def setWarning(self, enable: (int, bool)):
        from AppCore.AppDBModels.StateModels.OperatingStatusModel import OperatingStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.Buzzer     = RunStatusLevel.BuzzerWarning if isinstance(enable, (bool, int)) and enable else RunStatusLevel.ExitRunning   #
        OperatingStatusModel.setBuzzerAvailable(self.Buzzer)
    
    def setSlideTableAlreadyScanned(self, level: int):
        from AppCore.AppDBModels.DBModels import TraySlideModel, AlreadyScannedModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        try:
            slide: TraySlideModel = TraySlideModel.getTraySlideItem(level)
            if slide is None:
                return
            item: AlreadyScannedModel = AlreadyScannedModel.instance(**slide.to_field(False))
            item.ID = None
            AlreadyScannedModel.append_all([item])
        except Exception as e:
            pass

    
    def waitForPauseRunning(self, waittimes: int = 30000):
        _waittimes: int = max(30000, waittimes) if isinstance(waittimes, int) else 30000
        endtime: Qt.QDateTime = Qt.QDateTime.currentDateTime().addMSecs(_waittimes)
        isPauseRunning: bool
        while True:
            isPauseRunning = self.isPause
            if not isPauseRunning:
                break
            if Qt.QDateTime.currentDateTime() > endtime:
                break
            AppTimeLoop.processGlobalEvents(3000)
        return isPauseRunning

    
    def waitForExitRunning(self, waittimes: int = 30000):
        isExitRunning: bool
        isExitRunning = self.isExit
        if isExitRunning:
            AppTimeLoop.processGlobalEvents(3000)
            isExitRunning = self.isExit
        if isExitRunning:
            self.setScanningStatus(ScanStatusLevel.FinishScanning_Status)

        return isExitRunning

    
    def waitForRunning(self, waittimes: int = 1000):
        _waittimes: int = max(1000, waittimes)
        isRunning: bool = self.hasOperating()
        if not isRunning:
            AppTimeLoop.processGlobalEvents(_waittimes)
            isRunning = self.hasOperating()

        # self.setRunning(isRunning)
        return isRunning


    def setScanningStatus(self, level: int):
        from AppCore.AppDBModels.DBModels import ScanStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.ScanStatus = level if level in ScanStatusLevel.all() else ScanStatusLevel.Default_Status
        ScanStatusModel.setScanStatus(self.ScanStatus)


    def getScanningStatus(self) -> int:
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        return self.ScanStatus if self.hasScanStatus else ScanStatusLevel.Default_Status


    @property
    def scanning_level(self) -> int:
        Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        return self.ScanStatus if self.hasScanStatus else ScanStatusLevel.Default_Status

    def setScanningDateTime     (self, value: (Qt.QDateTime, datetime)):
        from AppCore.AppDBModels.StateModels.ScanStatusModel import ScanStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        if isinstance(value, Qt.QDateTime):
            self.ScanningDateTime     = value.toPyDateTime()
        elif isinstance(value, datetime):
            self.ScanningDateTime     = value
        else:
            self.ScanningDateTime     = None
        ScanStatusModel.setScanningDateTime(self.ScanningDateTime)

    def setStopScanningDateTime (self, value: (Qt.QDateTime, datetime)):
        from AppCore.AppDBModels.StateModels.ScanStatusModel import ScanStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        if isinstance(value, Qt.QDateTime):
            self.StopScanningDateTime = value.toPyDateTime()
        elif isinstance(value, datetime):
            self.StopScanningDateTime = value
        else:
            self.StopScanningDateTime = None
        ScanStatusModel.setStopScanningDateTime(self.StopScanningDateTime)

    def setTrayTableSlide(self, chamber_number: int, row_number: int, tray_number: int, **args):
        from AppCore.DBModels import ScanStatusModel, ChamberStatusModel, CustomScanningModel, ScanTemplate
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.ChamberGroupNumber = chamber_number    #
        self.ChamberRowNumber   = row_number        #
        self.TrayNumber         = tray_number       #
        if isinstance(args.get('CodeString', None), str):
            self.CodeString     = args.get('CodeString', None)
        if isinstance(args.get('codestring', None), str):
            self.CodeString     = args.get('codestring', None)
        if isinstance(args.get('codestring', None), str):
            self.CodeString     = args.get('codestring', None)
        if isinstance(args.get('codestring', None), str):
            self.CodeString     = args.get('codestring', None)
        if isinstance(args.get('templateID', None), int):
            self.Template_ID    = args.get('templateID', None)
        if isinstance(args.get('objective', None), int):
            self.ObjectiveLevel = args.get('objective', None)
        if isinstance(args.get('ScanStatus', None), int):
            self.ScanStatus = args.get('ScanStatus', None)
        if isinstance(args.get('Level', None), int):
            self.ScanStatus = args.get('Level', None)
        if isinstance(args.get('level', None), int):
            self.ScanStatus = args.get('level', None)
        ScanStatusModel.setCurrentScanningTrayNumber(self.ChamberGroupNumber, self.ChamberRowNumber, self.TrayNumber, self.ObjectiveLevel, self.Template_ID, self.CodeString)
        ScanStatusModel.setScanStatus(self.ScanStatus)
        Template: ScanTemplate = CustomScanningModel.getTemplate(self.ChamberGroupNumber, self.ChamberRowNumber)
        if isinstance(Template, ScanTemplate):
            self.Template_ID = Template.ID
            self.PreviewClassifier_ID = Template.previewsettings_ID
            self.CollectClassifier_ID = Template.collectsettings_ID
        ChamberStatusModel.setCurrentScanningStatus(self.ChamberGroupNumber, self.ChamberRowNumber, self.ScanStatus, self.Template_ID)

    def changedChamberScanningStatus(self, chamber_number: int, row_number: int, level: int):
        from AppCore.DBModels import ChamberStatusModel
        ChamberStatusModel.setScanningStatus(chamber_number, row_number, level)

    """是否可以取片"""

    def isPickAvailable(self, chamber_number: int, row_number: int = 1) -> int:
        from AppCore.DBModels import ChamberStatusModel
        return ChamberStatusModel.IsPickAvailable(chamber_number, row_number)

    """是否可以放片"""

    def isPlaceAvailable(self, chamber_number: int, row_number: int = 1) -> int:
        from AppCore.DBModels import ChamberStatusModel
        return ChamberStatusModel.IsPickAvailable(chamber_number, row_number)

    def changedScanningStatus(self, chamber_number: int, row_number: int, tray_number: int, level: int, codestring: str = None, objective: int = None):
        from AppCore.DBModels import ChamberStatusModel, ScanStatusModel, CustomScanningModel, ScanTemplate
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.ChamberGroupNumber = chamber_number #
        self.ChamberRowNumber   = row_number     #
        self.TrayNumber         = tray_number    #
        self.ScanStatus         = level          #
        self.CodeString         = codestring     #
        self.ObjectiveLevel     = objective   if isinstance(objective, int) else ObjectiveLevel.Objective1   #
        Template: ScanTemplate = CustomScanningModel.getTemplate(self.ChamberGroupNumber, self.ChamberRowNumber)
        if isinstance(Template, ScanTemplate):
            self.Template_ID = Template.ID
            self.PreviewClassifier_ID = Template.previewsettings_ID
            self.CollectClassifier_ID = Template.collectsettings_ID
        ScanStatusModel.changedScanningStatus(self.ChamberGroupNumber, self.ChamberRowNumber, self.TrayNumber, self.ScanStatus, self.CodeString, self.ObjectiveLevel)
        ChamberStatusModel.setCurrentScanningStatus(self.ChamberGroupNumber, self.ChamberRowNumber, self.ScanStatus, self.Template_ID)


    def changedTrayScanningStatus(self, chamber_number: int, level: int, objective: int = None):
        from AppCore.DBModels import ChamberStatusModel, ScanStatusModel
        Locker: Qt.QWriteLocker = Qt.QWriteLocker(self.IOLocker)
        self.ChamberGroupNumber = chamber_number    #
        self.ScanStatus         = level             #
        self.ObjectiveLevel     = objective   if isinstance(objective, int) else ObjectiveLevel.Objective1   #
        if not self.hasScanningDateTime:
            self.ScanningDateTime = datetime.now()
        ScanStatusModel.changedScanningStatus(self.ChamberGroupNumber, self.ChamberRowNumber, self.TrayNumber, self.ScanStatus, self.CodeString, self.ObjectiveLevel)
        ChamberStatusModel.setGroupScanningStatus(self.ChamberGroupNumber, self.ScanStatus)

    def result_chamber_status(self) -> list[dict[str, object]]:
        from AppCore.DBModels import ChamberStatusModel
        item: ChamberStatusModel
        buffer : list[dict[str, object]] = []
        items: list = ChamberStatusModel.all()
        if not isinstance(items, (list, tuple)):
            return buffer

        try:
            buffer = [item.to_field() for item in items if isinstance(item, ChamberStatusModel)]
        except Exception as e:
            AppUtils.print_Exception(e)
        return buffer

    def pushtemplate(self):
        try:
            from AppCore.DBModels import ScanTemplate, TrayModel, Collectsettings, Previewsettings
            trayModel: TrayModel = TrayModel.getTrayConfig(self.TrayNumber)
            if not isinstance(trayModel, TrayModel):
                trayModel = TrayModel.getConfig(ModuleLevel.ModuleTraySlide1)
            template: ScanTemplate = ScanTemplate.get(ScanTemplate.ID == self.Template_ID)
            if not isinstance(template, ScanTemplate):
                template = ScanTemplate.getMinPrimaryItem()
            Collect: Collectsettings = Collectsettings.Primary(template.collectsettings_ID) if template is not None and template.has_collectsettings_ID else None
            Preview: Previewsettings = Previewsettings.Primary(template.previewsettings_ID) if template is not None and template.has_previewsettings_ID else None
            buffer: dict = {'TrayModel'     : trayModel.to_save_field() if trayModel    is not None else {},
                            'Template'      : template.to_field()       if template     is not None else {},
                            'Collectsettings': Collect.to_field()       if Collect      is not None else {},
                            'Previewsettings': Preview.to_field()       if Preview      is not None else {},
                            }
            return buffer
        except Exception as e:
            AppUtils.print_Exception(e)
            return {}

    def scanningstatus(self) -> dict[str, object]:
        buffer: dict[str, object] = {}
        try:
            from AppCore.Levels import ObjectiveLevel

            buffer['ObjectiveLevel'           ] = ObjectiveLevel.toUiString(self.ObjectiveLevel)                                                        #     '　当前物镜　　　'
            buffer['ChamberGroupNumber'       ] = self.ChamberGroupNumber                                                                               #     '　片仓组号　　　'
            buffer['ChamberRowNumber'         ] = self.ChamberRowNumber                                                                                 #     '　片仓行号　　　'
            buffer['TrayNumber'               ] = self.TrayNumber                                                                                       #     '　载玻台号　　　'
            buffer['RowNumber'                ] = self.RowNumber                                                                                        #     '　玻片行号　　　'
            buffer['ColNumber'                ] = self.ColNumber                                                                                        #     '　玻片列号　　　'
            buffer['ScanStatus'               ] = self.ScanStatus                                                                                       #     '　扫描状态　　　'
            buffer['RunStatus'                ] = self.RunStatus                                                                                        #     '　运行状态　　　'
            buffer['Template_ID'              ] = self.Template_ID                                                                                      #     '　模板序号　　　'
            buffer['PreferredClassifier_ID'   ] = self.PreferredClassifier_ID                                                                           #     '　优选器序号　　'
            buffer['PreviewClassifier_ID'     ] = self.PreviewClassifier_ID                                                                             #     '　预选器序号　　'
            buffer['CollectClassifier_ID'     ] = self.CollectClassifier_ID                                                                             #     '　采集器序号　　'
            buffer['User_ID'                  ] = self.User_ID                                                                                          #     '　当前账号　　　'
            buffer['OperatingStatus_ID'       ] = self.OperatingStatus_ID                                                                               #     '　当前状态　　　'
            buffer['CodeString'               ] = self.CodeString                                                                                       #     '　玻片二维码　　'
            buffer['HitBot'                   ] = self.HitBot                                                                                           #     '　机械臂状态　　'
            buffer['Microscope'               ] = self.Microscope                                                                                       #     '　显微镜状态　　'
            buffer['WebSocket'                ] = self.WebSocket                                                                                        #     '　网络服务状态　'
            buffer['AxisX'                    ] = self.AxisX                                                                                            #     '载玻台Ｘ轴状态　'
            buffer['AxisY'                    ] = self.AxisY                                                                                            #     '载玻台Ｙ轴状态　'
            buffer['Camera'                   ] = self.Camera                                                                                           #     '　扫描器状态　　'
            buffer['ScanCode'                 ] = self.ScanCode                                                                                         #     '　扫描器状态　　'
            buffer['Oil'                      ] = self.Oil                                                                                              #     '　镜油管状态　　'
            buffer['Chamber'                  ] = self.Chamber                                                                                          #     '　载玻片片仓状态'
            buffer['Buzzer'                   ] = self.Buzzer                                                                                           #     '　蜂鸣器器状态　'
            buffer['Tray1'                    ] = self.Tray1                                                                                            #     '载玻台１号位状态'
            buffer['Tray2'                    ] = self.Tray2                                                                                            #     '载玻台２号位状态'
            buffer['ScanningDateTime'         ] = self.ScanningDateTime     .timestamp() if self.hasScanningDateTime     else None                      #     '　开始时间　　　'
            buffer['StopScanningDateTime'     ] = self.StopScanningDateTime .timestamp() if self.hasStopScanningDateTime else None                      #     '　停止时间　　　'
        except Exception as e:
            pass
        return buffer

    @classmethod
    def get_slide_tray_position_xy(cls, RowNumber: int, ColNumber: int, Position_X: float, Position_Y: float, StepX: float, StepY: float) -> (float, float):
        x = float(round(Decimal(f'{Position_X}') - Decimal(f'{abs(StepX)}') * (RowNumber - 1), 4))
        y = float(round(Decimal(f'{Position_Y}') + Decimal(f'{abs(StepY)}') * (ColNumber - 1), 4))
        return x, y

AppStatus: AppStatusSetting = AppStatusSetting.GetInstance()