#!D:/IDE/anaconda3/envs python
# -*- coding: UTF-8 -*-
"""
 @Author: Administrator
 @FileName：SlideViews.py\n
 @DateTime: 2025/7/26 11:30\n
 @Author  ：xsh
"""
import sys
import cv2
import numpy as np
from decimal import Decimal
from PyQt5 import Qt
from qframelesswindow import FramelessWindow
from AppCore.DBModels import *
from AppCore.Levels import *
from AppCore.Readers import HitBotReader
from AppInterfaces.globalSlot import globalSlot, AppSlot
from AppSettings.AppGlobalStatus import AppGlobalStatus, global_status
from AppInterfaces.AppTimeLoop import AppTimeLoop
from utils import *
from AppInterfaces.UiInterface import UiInterface, AppUiProperty
from AppInterfaces.SingletonInterface import SingletonInterface
from AppHeadEnd.UiCommons import *
from AppCore.Requests import *
from AppCore.Contexts import HitBotData
from AppUtils.UiUtils import UiUtils
from AppBackEnd.AppScanningFlow import AppScanningFlow

class SlideViews(Qt.QWidget, UiInterface, SingletonInterface):
    Locker              : Qt.QMutex = Qt.QMutex()
    CameraParameter             : CameraInterface       #
    Business                    : AppScanningFlow       #
    MotionControl               : MotionControlView     #
    SlideData                   : DrawSlidesDataView    #
    Operation                   : SlideOperationView    #
    Stacked                     : Qt.QStackedLayout     #
    CameraView                  : CameraConfigView      #
    ObjectiveModelView          : DBModelView           #
    CameraModelModelView        : DBModelView           #
    TrayModelView               : DBModelView           #
    AnointingModelView          : DBModelView           #
    FocusingModelView           : DBModelView           #
    SlideCaseModelView          : SlideModelView        #
    CellModelView               : SlideModelView        #
    ChamberStatusModelView      : SlideModelView        #
    ImageModelView              : DBModelView           #
    Model                       : SlideModel            #
    CameraTimer                 : Qt.QTimer             #
    CurrentWidget               : Qt.QWidget
    OilSwitch                   : bool = False
    @classmethod
    def GetInstance(cls, *args, **kwargs) -> 'SlideViews':
        return super(SlideViews, cls).GetInstance(*args, **kwargs)

    def __init__(self, parent: Qt.QWidget = None):
        super(SlideViews, self).__init__(parent=parent)
        self.Initialization('SlideViews', self, parent)
        self.initWidgetStyle()
        self.flushPosition()
        self.flushFrame()
        self.initWindowIcon()
        self.setWindowTitle("载玻台调试")

    def initWidgetStyle(self):
        self.setStyleSheet(UiUtils.getWindowStyle())

    def initConnect(self):
        super(SlideViews, self).initConnect()
        TYPE: Qt.Qt.ConnectionType = Qt.Qt.ConnectionType(Qt.Qt.AutoConnection | Qt.Qt.UniqueConnection)
        self.MotionControl.valueChanged                             .connect(slot=self.SlotControlValueChanged                  , type=TYPE)
        self.MotionControl.z_move_range_Button              .clicked.connect(slot=self.SlotInitZMoveLimit                       , type=TYPE)
        self.MotionControl.camera_view_button               .clicked.connect(slot=self.SlotCameraConversion                     , type=TYPE)
        self.MotionControl.motion_init_button               .clicked.connect(slot=self.SlotMotionInitStatus                     , type=TYPE)
        self.MotionControl.camera_image_button              .clicked.connect(slot=self.SlotCameraImageButton                    , type=TYPE)
        self.MotionControl.oil_switch_button                .clicked.connect(slot=self.SlotOilSwitchButton                      , type=TYPE)
        self.Operation.SelectChamber.OtherFunctionButton    .clicked.connect(slot=self.SLotFocusingAndScanning                  , type=TYPE)
        self.Operation.Location.LocationButton              .clicked.connect(slot=self.SlotLocationLocationButton               , type=TYPE)
        self.Operation.Position.PositionButton              .clicked.connect(slot=self.SlotPositionPositionButton               , type=TYPE)
        self.Operation.ObjectiveChangedButton.UpButton      .clicked.connect(slot=self.SlotObjectiveChangedButtonUpButton       , type=TYPE)
        self.Operation.XChangedButton        .UpButton      .clicked.connect(slot=self.SlotXChangedButtonUpButton               , type=TYPE)
        self.Operation.YChangedButton        .UpButton      .clicked.connect(slot=self.SlotYChangedButtonUpButton               , type=TYPE)
        self.Operation.ZChangedButton        .UpButton      .clicked.connect(slot=self.SlotZChangedButtonUpButton               , type=TYPE)
        self.Operation.ObjectiveChangedButton.DownButton    .clicked.connect(slot=self.SlotObjectiveChangedButtonDownButton     , type=TYPE)
        self.Operation.XChangedButton        .DownButton    .clicked.connect(slot=self.SlotXChangedButtonDownButton             , type=TYPE)
        self.Operation.YChangedButton        .DownButton    .clicked.connect(slot=self.SlotYChangedButtonDownButton             , type=TYPE)
        self.Operation.ZChangedButton        .DownButton    .clicked.connect(slot=self.SlotZChangedButtonDownButton             , type=TYPE)

        self.SlideCaseModelView       .ActionMovesSignal                .connect(slot=self.SlotActionMovesSignal                    , type=TYPE)
        self.CellModelView            .ActionMovesSignal                .connect(slot=self.SlotCellModelActionMovesSignal           , type=TYPE)

        self.Operation.InitMotButton                        .clicked.connect(slot=self.SlotInitMotButton                        , type=TYPE)
        self.Operation.InitMicButton                        .clicked.connect(slot=self.SlotInitMicButton                        , type=TYPE)
        self.Operation.LowScanButton                        .clicked.connect(slot=self.SlotLowScanButton                        , type=TYPE)
        self.Operation.HigScanButton                        .clicked.connect(slot=self.SlotHigScanButton                        , type=TYPE)
        self.Operation.CameraButton                         .clicked.connect(slot=self.SlotCameraButton                         , type=TYPE)
        self.Operation.SaveImageButton                      .clicked.connect(slot=self.SlotSaveImageButton                      , type=TYPE)
        self.Operation.ObjectiveModelButton                 .clicked.connect(slot=self.SlotObjectiveModelButton                 , type=TYPE)
        self.Operation.CameraModelModelButton               .clicked.connect(slot=self.SlotCameraModelModelButton               , type=TYPE)
        self.Operation.TrayModelButton                      .clicked.connect(slot=self.SlotTrayModelButton                      , type=TYPE)
        self.Operation.AnointingModelButton                 .clicked.connect(slot=self.SlotAnointingModelButton                 , type=TYPE)
        self.Operation.FocusingModelButton                  .clicked.connect(slot=self.SlotFocusingModelButton                   , type=TYPE)
        self.Operation.SlideCaseModelButton                 .clicked.connect(slot=self.SlotSlideCaseModelButton                 , type=TYPE)
        self.Operation.CellModelButton                      .clicked.connect(slot=self.SlotCellModelButton                      , type=TYPE)
        self.Operation.ChamberStatusModelButton             .clicked.connect(slot=self.SlotChamberStatusModelButton             , type=TYPE)
        self.Operation.ImageModelButton                     .clicked.connect(slot=self.SlotImageModelButton                     , type=TYPE)
        self.Operation.DebugModeButton                      .clicked.connect(slot=self.SlotDebugModeButton                      , type=TYPE)




    def SlotStartScanningSignal(self, name):
        print(f'{name} 启动扫描')
        # self.SlowScanning()

    def SlotInitZMoveLimit(self):
        if not self.hasModel:
            self.initModel()

        Objective: ObjectiveModel
        if not self.Model.has_ObjectiveLevel:
            self.Model.ObjectiveLevel = ObjectiveLevel.ObjectiveNone
        self.initCameraParameter()

        Objective = ObjectiveModel.getObjectiveConfig(self.Model.ObjectiveLevel)
        if self.hasMotion:
            self.motion.set_z_range(Objective.Lower_Limit, Objective.Upper_Limit)

    def SlotOilSwitchButton(self):
        if not self.hasModel:
            self.initModel()
        if self.hasMotion:
            BeginOilDropingTimes            : int
            BeginOilDropingFinishWaitTimes  : int
            MiddleOilDropingTimes           : int
            MiddleOilDropingFinishWaitTimes : int
            BeginOilDropingSpeed            : int
            OilDropingSpeed                 : int
            BeginOilDropingTimes, BeginOilDropingFinishWaitTimes, BeginOilDropingSpeed = AnointingModel.getBeginOilDrippingTimeAndSpeed()
            MiddleOilDropingTimes, MiddleOilDropingFinishWaitTimes, OilDropingSpeed = AnointingModel.getMiddleOilDrippingTimeAndSpeed()
            self.motion.set_oil_speed(BeginOilDropingSpeed)
            if self.OilSwitch:
                self.MotionControl.oil_switch_button.setText("打开油泵　　")
            else:
                self.MotionControl.oil_switch_button.setText("关闭油泵　　")
            self.motion.oil_switch(not self.OilSwitch)
            self.OilSwitch = not self.OilSwitch


    def SlotInitMotButton                  (self):
        self.business.devices.waitForManipulatorHome()
        self.SlotPositionPositionButton ()
        pass
    def SlotInitMicButton                  (self):
        self.business.devices.waitForManipulatorHome()
        self.SlotPositionPositionButton()
        pass

    def SlotCameraImageButton(self):
        from AppCore.AppAlgorithms.ImageAlgorithm import ImageAlgorithm
        try:
            begin_times: Qt.QDateTime = Qt.QDateTime.currentDateTime()
            model: SlideModel = self.Model.copy()
            _camera_config: CameraModel = CameraModel.getObjectiveConfig(self.Model.ObjectiveLevel)
            IntegrationImages: list[np.ndarray] = []
            RIntegrationImages: list[np.ndarray]
            image: np.ndarray
            ExposureTimes: list[int] = IntegrationExposureTimes.ExposureTimes()
            if len(ExposureTimes) <= 0:
                ExposureTimes = [_camera_config.MidExposureTime] * 3
            self.camera.RequestMultipleArray(_camera_config, ExposureTimes, IntegrationImages)
            print(f'时间为: {begin_times.msecsTo(Qt.QDateTime.currentDateTime())}ms')
            RIntegrationImages = ImageAlgorithm.ProcessImages(IntegrationImages)
            print(f'预处理原图时间为: {begin_times.msecsTo(Qt.QDateTime.currentDateTime())}ms')
            if RIntegrationImages is None or len(RIntegrationImages) <= 0:
                return
            for image in IntegrationImages:
                self.CameraView.CameraUiSignal.emit('', ImageUtils.cv2_to_QImage(image, 800, 800))
                AppTimeLoop.processGlobalEvents(100)
            print(f'发送界面时间为: {begin_times.msecsTo(Qt.QDateTime.currentDateTime())}ms')
            _image: np.ndarray = ImageAlgorithm.ProcessIntegrationImages(RIntegrationImages)
            print(f'融合时间为: {begin_times.msecsTo(Qt.QDateTime.currentDateTime())}ms')
            if not isinstance(_image, np.ndarray):
                return
            self.CameraView.CameraUiSignal.emit('', ImageUtils.cv2_to_QImage(_image, 800, 800))
            AppTimeLoop.processGlobalEvents(200)
            _image = ImageAlgorithm.processImage(_image.copy())
            print(f'融合后清析度时间为: {begin_times.msecsTo(Qt.QDateTime.currentDateTime())}ms')
            if not isinstance(_image, np.ndarray):
                return

            self.CameraView.CameraUiSignal.emit('', ImageUtils.cv2_to_QImage(_image, 800, 800))
            AppTimeLoop.processGlobalEvents(200)
            model.Level = ScanStatusLevel.LowScanning_Status
            save_filename: str = f"D:/DeepLearning_data/Camera/{AppConvert.QDateTimeToPath(Qt.QDateTime.currentDateTime(), '_')}.png"
            info: Qt.QFileInfo = Qt.QFileInfo(save_filename)
            if not info.dir().exists():
                info.dir().mkpath(info.absolutePath())
            cv2.imwrite(info.absoluteFilePath(), _image)
            print(f'时间为: {begin_times.msecsTo(Qt.QDateTime.currentDateTime())}ms  {info.absoluteFilePath()}')
        except Exception as e:
            AppUtils.print_Exception(e)

    def SlotCameraButton                   (self):
        if not self.hasCameraTimer:
            self.initCameraTimer()
        if not self.hasCamera:
            self.initCamera()
        if not self.hasModel:
            self.initModel()
            self.flushPosition()
        if self.CameraTimer.isActive():
            self.CameraTimer.stop()
            self.camera.StopGrabbing()
            self.camera.Close()
            self.CameraView.CameraUiSignal.emit('', None)
            AppTimeLoop.processGlobalEvents(150)
        else:
            self.motion.changedLightIntensity(self.Model.ObjectiveLevel)
            self.camera.setModel(self.Model.ObjectiveLevel)
            # self.camera.reopen(self.Model.ObjectiveLevel)
            self.camera.StartFocusing(self.Model.ObjectiveLevel)
            self.CameraTimer.start(300)
            if self.Stacked.currentWidget() != self.CameraView:
                self.Stacked.setCurrentWidget(self.CameraView)


        pass
    def SlotCameraTimer(self):
        # self.getPosition()
        model: SlideModel = self.Model.copy()
        image: np.ndarray
        self.camera.GetFocusingNumpy(model)
        if not model.hasImageScore:
            return
        self.CameraView.CameraUiSignal.emit('',  model.toQImage(800, 800))
        self.SlideData.currentDataUpdated.emit(self.Model)
        AppTimeLoop.processGlobalEvents(200)
        # AppSlot.CameraUiSignal.emit('', ImageUtils.cv2_to_QImage(image, -1, -1))


    def flushPosition(self):
        self.initModel()
        if self.hasMotion:
            self.Model.ObjectiveLevel = self.motion.getObjective()
            self.motion.get_position(self.Model)
            self.initCameraParameter()
        self.updateUiModel()

    def getPosition(self):
        self.initModel()
        objective: int
        if self.hasMotion:
            isWrong, objective = self.motion.currentObjective()
            if 1 == isWrong:
                self.Model.ObjectiveLevel = objective
            self.motion.get_position(self.Model)

    def SlotSaveImageButton                (self):
        from AppCore.AppManagers.ProcessManager import ImageSaveProcess
        self.flushPosition()
        model: SlideModel = self.Model.copy()
        self.camera.GetRequest(model)
        if not model.hasImageScore:
            return

        image: np.ndarray = model.toImage()
        AppSlot.CameraUiSignal.emit('', image)
        model.Level = ScanStatusLevel.LowScanning_Status
        save_filename: str = f"D:/DeepLearning_data/Camera/{AppConvert.QDateTimeMsecToPath(Qt.QDateTime.currentDateTime(), '_')}.png"

        info: Qt.QFileInfo = Qt.QFileInfo(save_filename)
        print(info.absoluteFilePath())
        ImageSaveProcess(info.absoluteFilePath(), image)



    def SlotPositionPositionButton         (self):
        self.flushPosition()
        self.flushFrame()


    def updateUiModel(self):
        self.Operation.Position.setPosition(self.Model.ObjectiveLevel, self.Model.Position_X, self.Model.Position_Y, self.Model.Position_Z)
        self.Operation.Location.setLocation(self.Model.ObjectiveLevel, self.Model.TrayNumber, self.Model.RowNumber, self.Model.ColNumber)
        self.Operation.ObjectiveChangedButton.EditStep.setCurrentText(f'{self.Model.ObjectiveLevel}')
        self.MotionControl.currentDataUpdated.emit(self.Model.copy())
        self.SlideData.currentDataUpdated.emit(self.Model)
        AppTimeLoop.processGlobalEvents(500)

    def flushFrame(self):
        self.initModel          ()
        self.updateUiModel      ()



    @property
    def IsAvailable(self) -> bool:
        self.initBusiness()
        if not self.hasMotion:
            self.business.initHardWare()
        if not self.hasMotion:
            return False
        Objective: ObjectiveModel = ObjectiveModel.getObjectiveConfig(ObjectiveLevel.ObjectiveNone)
        if not self.business.status.isMicroscopeAvailable():
            self.business.devices.waitForMicroscope()
            # self.business.devices.waitForMicroscope()
        self.motion.set_objective_limit(Objective.Level)
        self.motion.waitmove_z(Objective.Safe_Limit)
        self.motion.changedObjective(ObjectiveLevel.ObjectiveNone)
        self.motion.waitmove_z(Objective.Lower_Limit)
        if not self.business.status.isManipulatorAvailable():
            self.business.devices.waitForManipulatorHome()
        if not self.business.status.isManipulatorAvailable():
            return False
        return True
    def isAvailable(self):
        self.initBusiness()
        if not self.hasMotion:
            self.business.initHardWare()
        if not self.hasMotion:
            return False
        return self.business.status.isMicroscopeAvailable() and self.business.status.isManipulatorAvailable()
    @property
    def hasAvailable(self) -> bool:
        self.initBusiness()
        if not self.hasMotion:
            self.business.initHardWare()
        if not self.hasMotion:
            return False
        return self.business.status.isMicroscopeAvailable() and self.business.status.isManipulatorAvailable()

    def SlotControlValueChanged(self, model: SlideModelInterface):
        if not self.hasAvailable:
            self.isAvailable()
        if not self.hasAvailable:
            return
        self.model_move(model)

    def SlotMotionInitStatus(self):
        from AppSettings.AppGlobalStatus import AppGlobalStatus, AppStatus
        AppStatus.setManipulator(True)
        AppStatus.setMicroscope (True)
        AppStatus.setCamera(True)
        self.flushPosition()
        pass

    def SlotCameraConversion(self):
        if self.Stacked.currentWidget() == self.CameraView:
            if self.hasCurrentWidget:
                self.Stacked.setCurrentWidget(self.CurrentWidget)
        else:
            self.CurrentWidget = self.Stacked.currentWidget()
            self.Stacked.setCurrentWidget(self.CameraView)


    def SlotObjectiveChangedButtonUpButton (self):
        if not self.hasAvailable:
            self.isAvailable()
        if not self.hasAvailable:
            return
        objective: int = AppConvert.ObjectConvert(self.Operation.ObjectiveChangedButton.EditStep.currentText(), int)
        if not isinstance(objective, int) or objective not in ObjectiveLevel.all():
            return
        self.getPosition()
        if self.Model.has_ObjectiveLevel and self.Model.ObjectiveLevel == objective:
            return
        self.Model.ObjectiveLevel = objective
        self.motion.changedObjective(self.Model.ObjectiveLevel)
        self.flushPosition()

        pass
    def SlotXChangedButtonUpButton         (self):
        if not self.hasAvailable:
            self.isAvailable()
        if not self.hasAvailable:
            return
        position: float = AppConvert.ObjectConvert(self.Operation.XChangedButton.EditStep.currentText().replace('mm', ''), float)
        if not isinstance(position, (int, float)):
            return
        self.getPosition()
        if not self.Model.has_Position_X:
            return
        model = self.Model.copy()
        model.Position_X = float(Decimal(f'{model.Position_X}') - Decimal(f'{position}'))
        self.motion.waitmove_x(model.Position_X)
        self.Model.Position_X = model.Position_X
        self.updateUiModel()

        pass
    def SlotYChangedButtonUpButton         (self):
        if not self.hasAvailable:
            self.isAvailable()
        if not self.hasAvailable:
            return
        position: float = AppConvert.ObjectConvert(self.Operation.YChangedButton.EditStep.currentText().replace('mm', ''), float)
        if not isinstance(position, (int, float)):
            return
        self.getPosition()
        if not self.Model.has_Position_Y:
            return
        model = self.Model.copy()
        model.Position_Y = float(Decimal(f'{model.Position_Y}') + Decimal(f'{position}'))
        self.motion.waitmove_y(model.Position_Y)
        self.Model.Position_Y = model.Position_Y
        self.updateUiModel()

    def SlotZChangedButtonUpButton         (self):
        if not self.hasAvailable:
            self.isAvailable()
        if not self.hasAvailable:
            return
        position: float = AppConvert.ObjectConvert(self.Operation.ZChangedButton.EditStep.currentText(), float)
        if not isinstance(position, (int, float)):
            return
        self.getPosition()
        if not self.Model.has_Position_Z or not self.Model.has_ObjectiveLevel:
            return
        model = self.Model.copy()
        model.Position_Z += position
        Objective = ObjectiveModel.getObjectiveConfig(model.ObjectiveLevel)
        Lower_Limit: int = Objective.Lower_Limit
        Upper_Limit: int = Objective.Upper_Limit
        self.motion.set_z_move_mode(1)
        self.motion.set_z_speed(Objective.Default_Speed)
        self.motion.set_z_range(Lower_Limit, Upper_Limit)
        model.Position_Z = min(Upper_Limit, max(Lower_Limit, int(model.Position_Z)))
        self.motion.waitmove_z(model.Position_Z)
        self.Model.Position_Z = model.Position_Z
        self.updateUiModel()

    def SlotObjectiveChangedButtonDownButton   (self):
        if not self.hasAvailable:
            self.isAvailable()
        if not self.hasAvailable:
            return
        objective: int = AppConvert.ObjectConvert(self.Operation.ObjectiveChangedButton.EditStep.currentText(), int)
        if not isinstance(objective, int) or objective not in ObjectiveLevel.all():
            return
        self.getPosition()
        if self.Model.ObjectiveLevel != objective:
            self.Model.ObjectiveLevel = objective
            self.initCameraParameter()
            self.motion.changedObjective(self.Model.ObjectiveLevel)


        self.flushPosition()
        pass
    def SlotXChangedButtonDownButton           (self):
        if not self.hasAvailable:
            self.isAvailable()
        if not self.hasAvailable:
            return
        position: float = AppConvert.ObjectConvert(self.Operation.XChangedButton.EditStep.currentText().replace('mm', ''), float)
        if not isinstance(position, (int, float)):
            return
        self.getPosition()
        if not self.Model.has_Position_X:
            return
        model = self.Model.copy()
        model.Position_X = float(Decimal(f'{model.Position_X}') + Decimal(f'{position}'))
        # self.Model.Position_X += position
        self.motion.waitmove_x(model.Position_X)
        self.Model.Position_X = model.Position_X
        self.updateUiModel()
    def SlotYChangedButtonDownButton           (self):
        if not self.hasAvailable:
            self.isAvailable()
        if not self.hasAvailable:
            return
        position: float = AppConvert.ObjectConvert(self.Operation.YChangedButton.EditStep.currentText().replace('mm', ''), float)
        if not isinstance(position, (int, float)):
            return
        self.getPosition()
        if not self.Model.has_Position_Y:
            return
        model = self.Model.copy()
        model.Position_Y = float(Decimal(f'{model.Position_Y}') - Decimal(f'{position}'))
        # self.Model.Position_Y += position
        self.motion.waitmove_y(model.Position_Y)
        self.Model.Position_Y = model.Position_Y
        self.updateUiModel()
    def SlotZChangedButtonDownButton           (self):
        if not self.hasAvailable:
            self.isAvailable()
        if not self.hasAvailable:
            return
        position: float = AppConvert.ObjectConvert(self.Operation.ZChangedButton.EditStep.currentText(), float)
        if not isinstance(position, (int, float)):
            return
        self.getPosition()
        if not self.Model.has_Position_Z or not self.Model.has_ObjectiveLevel:
            return
        model = self.Model.copy()
        model.Position_Z -= position
        Objective = ObjectiveModel.getObjectiveConfig(model.ObjectiveLevel)
        Lower_Limit: int = Objective.Lower_Limit
        Upper_Limit: int = Objective.Upper_Limit
        model.Position_Z = min(Upper_Limit, max(Lower_Limit, int(model.Position_Z)))
        self.motion.set_z_move_mode(1)
        self.motion.set_z_speed(Objective.Default_Speed)
        self.motion.set_z_range(Lower_Limit, Upper_Limit)
        self.motion.waitmove_z(model.Position_Z)
        self.Model.Position_Z = model.Position_Z
        self.updateUiModel()

    def SlotLocationLocationButton         (self):
        self.initModel()
        if not self.hasAvailable:
            self.isAvailable()
        if not self.hasAvailable:
            return
        ChamberNumber  : int
        ChamberRowNumber: int
        _ObjectiveLevel: int
        _TrayNumber    : int
        _RowNumber     : int
        _ColNumber     : int
        ChamberNumber       ,RowNumber      = self.Operation.SelectChamber.getChamberNumber()
        _ObjectiveLevel     ,_TrayNumber    ,_RowNumber     ,_ColNumber      = self.Operation.Location.getLocation()
        model                       : SlideFocusingModel = SlideFocusingModel.instance()
        tray: TrayModel = TrayModel.getTrayConfig(_TrayNumber)
        if model is None or tray is None:
            return
        self.Model.ChamberRowNumber         = RowNumber
        self.Model.ChamberGroupNumber       = ChamberNumber
        self.Model.TrayNumber               = _TrayNumber
        self.Model.RowNumber                = _RowNumber
        self.Model.ColNumber                = _ColNumber
        model.ChamberRowNumber              = RowNumber
        model.ChamberGroupNumber            = ChamberNumber
        model.TrayNumber                    = _TrayNumber
        model.RowNumber                     = _RowNumber
        model.ColNumber                     = _ColNumber
        model.ObjectiveLevel                = self.Model.ObjectiveLevel
        model.Position_Z                    = self.Model.Position_Z
        SlideFocusingModel.setModelPosition(tray, model)
        self.model_move(model)

        pass

    def SlotActionMovesSignal(self, model: SlideModelInterface):
        self.initModel()
        if not self.hasAvailable:
            self.isAvailable()
        if not self.hasAvailable:
            return
        self.model_move(model)
        pass

    def SlotCellModelActionMovesSignal(self, model: SlideModelInterface):
        self.initModel()
        if not self.hasAvailable:
            self.isAvailable()
        if not self.hasAvailable:
            return
        tray_model: TrayModel = TrayModel.getTrayConfig(model.TrayNumber)
        CellModel.setCellPoint(tray_model, model)
        self.model_move(model)

    def model_move(self, model: SlideModelInterface):
        self.initModel()
        if not self.hasModel:
            return
        if not self.hasAvailable:
            self.isAvailable()
        if not self.hasAvailable:
            return
        if not model:
            return
        Objective: ObjectiveModel = ObjectiveModel.getObjectiveConfig(model.ObjectiveLevel)
        if not isinstance(Objective, ObjectiveModel):
            return
        if int(model.Position_Z) > int(Objective.Upper_Limit):
            self.motion.waitmove_z(Objective.Safe_Limit)
        self.motion.waitmove_xy(model.Position_X, model.Position_Y)

        objective: int = self.motion.getObjective()
        if objective != model.ObjectiveLevel:
            self.motion.changedObjective(Objective.Level)

        self.motion.waitmove_z(model.Position_Z)
        self.Model.as_field(model.to_field())
        self.updateUiModel()

    def SlotLowScanButton(self):
        self.initModel()
        if not self.hasModel:
            return
        if not self.hasAvailable:
            self.isAvailable()
        if not self.hasAvailable:
            return
        TrayNumber      : int
        ChamberNumber   : int
        RowNumber       : int
        ChamberNumber, RowNumber        = self.Operation.SelectChamber.getChamberNumber()
        TrayNumber                      = self.Operation.SelectChamber.getTrayNumber()
        self.Model.TrayNumber           = TrayNumber
        self.Model.ChamberRowNumber     = RowNumber
        self.Model.ChamberGroupNumber   = ChamberNumber
        self.business.status.setRunning(True)
        try:

            self.business.status.setTraySlideItem(TrayNumber, self.Model.copy())

            self.Business.LowScanningTraySlide(chamber_number=ChamberNumber, row_number=RowNumber, tray_number=TrayNumber, isSafe=False)
            self.business.status.setTraySlideItem(TrayNumber, None)

        except Exception as e:
            AppUtils.print_Exception(e)
        self.business.status.setRunning(False)

    def SlowScanning(self):
        self.initModel()
        if not self.hasModel:
            return
        if not self.hasAvailable:
            self.isAvailable()
        if not self.hasAvailable:
            return
        TrayNumber: int
        ChamberNumber: int
        RowNumber: int
        ChamberNumber, RowNumber = self.Operation.SelectChamber.getChamberNumber()
        TrayNumber = self.Operation.SelectChamber.getTrayNumber()
        self.Model.TrayNumber = TrayNumber
        self.Model.ChamberRowNumber = RowNumber
        self.Model.ChamberGroupNumber = ChamberNumber
        self.business.status.setRunning(True)
        try:

            self.business.status.setTraySlideItem(TrayNumber, self.Model.copy())
            self.Business.LowScanningTraySlide(chamber_number=ChamberNumber, row_number=RowNumber, tray_number=TrayNumber, isSafe=False)
            self.business.status.setTraySlideItem(TrayNumber, None)

        except Exception as e:
            AppUtils.print_Exception(e)
        self.business.status.setRunning(False)
        pass
        pass
    def SLotFocusingAndScanning(self):
        self.initModel()
        if not self.hasModel:
            return
        if not self.hasAvailable:
            self.isAvailable()
        if not self.hasAvailable:
            return
        TrayNumber: int
        ChamberNumber: int
        RowNumber: int
        ChamberNumber, RowNumber = self.Operation.SelectChamber.getChamberNumber()
        TrayNumber = self.Operation.SelectChamber.getTrayNumber()
        self.Model.TrayNumber = TrayNumber
        self.Model.ChamberRowNumber = RowNumber
        self.Model.ChamberGroupNumber = ChamberNumber
        self.business.status.setRunning(True)
        try:
            self.business.status.setTraySlideItem(TrayNumber, self.Model.copy())
            self.business.status.waitForRunning()
            self.Business.LowScanningTraySlide(chamber_number=ChamberNumber, row_number=RowNumber, tray_number=TrayNumber, isSafe=False)
            self.business.status.setTraySlideItem(TrayNumber, None)
            self.business.status.waitForRunning()
        except Exception as e:
            AppUtils.print_Exception(e)
        self.business.status.setRunning(False)
    def SlotHigScanButton(self):
        self.initModel()
        if not self.hasModel:
            return
        if not self.hasAvailable:
            self.isAvailable()
        if not self.hasAvailable:
            return
        TrayNumber: int
        ChamberNumber: int
        RowNumber: int
        ChamberNumber, RowNumber = self.Operation.SelectChamber.getChamberNumber()
        TrayNumber = self.Operation.SelectChamber.getTrayNumber()
        self.Model.TrayNumber = TrayNumber
        self.Model.ChamberRowNumber = RowNumber
        self.Model.ChamberGroupNumber = ChamberNumber
        self.business.status.setRunning(True)
        try:
            self.business.status.setTraySlideItem(TrayNumber, self.Model.copy())
            self.business.status.waitForRunning()
            self.Business.HigScanningTraySlide(chamber_number=ChamberNumber, row_number=RowNumber, tray_number=TrayNumber, isSafe=False)
            self.business.status.setTraySlideItem(TrayNumber, None)
            self.business.status.waitForRunning()
        except Exception as e:
            AppUtils.print_Exception(e)
        self.business.status.setRunning(False)


    def SlotObjectiveModelButton                 (self):
        self.Stacked.setCurrentWidget(self.ObjectiveModelView)
        self.ObjectiveModelView.flushFrame()
    def SlotCameraModelModelButton               (self):
        self.Stacked.setCurrentWidget(self.CameraModelModelView)
        self.CameraModelModelView.flushFrame()
    def SlotTrayModelButton                      (self):
        self.Stacked.setCurrentWidget(self.TrayModelView)
        self.TrayModelView.flushFrame()
    def SlotAnointingModelButton                 (self):
        self.Stacked.setCurrentWidget(self.AnointingModelView)
        self.AnointingModelView.flushFrame()
    def SlotFocusingModelButton                   (self):
        self.Stacked.setCurrentWidget(self.FocusingModelView)
        self.FocusingModelView.flushFrame()
    def SlotSlideCaseModelButton                 (self):
        self.Stacked.setCurrentWidget(self.SlideCaseModelView)
        self.SlideCaseModelView.flushFrame()
    def SlotCellModelButton                      (self):
        self.Stacked.setCurrentWidget(self.CellModelView)
        self.CellModelView.flushFrame()

    def SlotChamberStatusModelButton             (self):
        self.Stacked.setCurrentWidget(self.ChamberStatusModelView)
        self.ChamberStatusModelView.flushFrame()
    def SlotImageModelButton                     (self):
        self.Stacked.setCurrentWidget(self.ImageModelView)
        self.ImageModelView.flushFrame()

    def SlotDebugModeButton                      (self):
        from AppSettings.SystemSetting import SystemConfig
        isDebug: int = SystemConfig.isDebugMode()
        SystemConfig.setDebugMode(1 - isDebug)

        pass
    def initValue(self):
        super(SlideViews, self).initValue()
        self.initWindows        ()
        self.initBusiness       ()
        self.initModel          ()
        self.initHitBot         ()
        self.initCamera         ()
        self.initMotion         ()
        self.initCameraTimer    ()
        self.initCameraParameter()

    def initLayouts(self):
        if self.hasWindowLayouts:
            return
        layout: Qt.QHBoxLayout = Qt.QHBoxLayout()
        layout.setSpacing(1)
        layout.setContentsMargins(5, 0, 5, 0)

        t_layout: Qt.QHBoxLayout = Qt.QHBoxLayout()
        l_layout: Qt.QVBoxLayout = Qt.QVBoxLayout()
        t_layout.setSpacing(1)
        t_layout.setContentsMargins(0, 0, 0, 0)
        l_layout.setSpacing(1)
        l_layout.setContentsMargins(0, 0, 0, 0)

        t_layout.addWidget(self.MotionControl   )
        t_layout.addWidget(self.SlideData       )
        l_layout.addLayout(t_layout         )
        l_layout.addWidget(self.Operation   )

        layout.addLayout(l_layout       )
        layout.addLayout(self.Stacked   )
        self.setLayout(layout)
        self.Stacked.addWidget(self.CameraView                  )
        self.Stacked.addWidget(self.ObjectiveModelView          )
        self.Stacked.addWidget(self.CameraModelModelView        )
        self.Stacked.addWidget(self.TrayModelView               )
        self.Stacked.addWidget(self.AnointingModelView          )
        self.Stacked.addWidget(self.FocusingModelView           )
        self.Stacked.addWidget(self.SlideCaseModelView          )
        self.Stacked.addWidget(self.CellModelView               )
        self.Stacked.addWidget(self.ChamberStatusModelView      )
        self.Stacked.addWidget(self.ImageModelView              )
        self.Stacked.setCurrentWidget(self.CameraView)

        # self.CameraView                  .setVisible(False)
        self.ObjectiveModelView          .setVisible(False)
        self.CameraModelModelView        .setVisible(False)
        self.TrayModelView               .setVisible(False)
        self.AnointingModelView          .setVisible(False)
        self.FocusingModelView           .setVisible(False)
        self.SlideCaseModelView          .setVisible(False)
        self.CellModelView               .setVisible(False)
        self.ChamberStatusModelView      .setVisible(False)
        self.ImageModelView              .setVisible(False)

    def initWindows(self):
        self.initCameraParameter             ()
        self.initMotionControl               ()
        self.initSlideData                   ()
        self.initOperation                   ()
        self.initStacked                     ()
        self.initCameraView                  ()
        self.initObjectiveModelView          ()
        self.initCameraModelModelView        ()
        self.initTrayModelView               ()
        self.initAnointingModelView          ()
        self.initFocusingModelView           ()
        self.initSlideCaseModelView          ()
        self.initCellModelView               ()
        self.initChamberStatusModelView      ()
        self.initImageModelView              ()
        self.initModel                       ()
        self.initCameraTimer                 ()




    def initBusiness                    (self):
        if not self.hasBusiness                    :
            self.Business                     = AppScanningFlow       .GetInstance()

    def initMotionControl               (self):
        if not self.hasMotionControl                 :
            self.MotionControl            = MotionControlView     (self)

    def initSlideData                   (self):
        if not self.hasSlideData                   :
            self.SlideData                    = DrawSlidesDataView    (self)

    def initOperation                   (self):
        if not self.hasOperation                   :
            self.Operation                    = SlideOperationView    (self)

    def initStacked                     (self):
        if not self.hasStacked                     :
            self.Stacked                      = Qt.QStackedLayout     ()

    def initCameraView                  (self):
        if not self.hasCameraView                  :
            self.CameraView                   = CameraConfigView    (self)

    def initHitBot(self):
        self.initBusiness()
        if not self.hasHitBot:
            self.Business.initHitBot()


    def initCamera(self):
        self.initBusiness()
        if not self.hasCamera:
            self.Business.initHardWare()



    def initMotion(self):
        self.initBusiness()
        if not self.hasMotion:
            self.Business.initHardWare()

    def initModel(self):
        if not self.hasModel:
            ChamberNumber   : int
            RowNumber       : int
            if self.hasOperation:

                ChamberNumber, RowNumber = self.Operation.SelectChamber.getChamberNumber()
            else:
                ChamberNumber, RowNumber = 1, 1
            self.Model = SlideModel.copyInstance(ChamberStatusModel.getStatusModel(ChamberNumber, RowNumber))


    def initCameraTimer(self):
        if not self.hasCameraTimer:
            TYPE: Qt.Qt.ConnectionType = Qt.Qt.ConnectionType(Qt.Qt.AutoConnection | Qt.Qt.UniqueConnection)
            self.CameraTimer = Qt.QTimer(self)
            self.CameraTimer.timeout.connect(slot=self.SlotCameraTimer, type=TYPE)



    def initCameraParameter(self):
        self.initModel()
        if not self.hasCameraParameter or self.CameraParameter.Level != self.Model.ObjectiveLevel:
            self.CameraParameter = MonosCameraModel.getObjectiveConfig(self.Model.ObjectiveLevel)

    def initObjectiveModelView          (self):
        if not self.hasObjectiveModelView          :
            self.ObjectiveModelView           = DBModelView    (data_model=ObjectiveModel       (),parent=self)

    def initCameraModelModelView        (self):
        if not self.hasCameraModelModelView        :
            self.CameraModelModelView         = DBModelView    (data_model=CameraModel          (),parent=self)

    def initTrayModelView               (self):
        if not self.hasTrayModelView               :
            self.TrayModelView                = DBModelView    (data_model=TrayModel            (),parent=self)

    def initAnointingModelView          (self):
        if not self.hasAnointingModelView          :
            self.AnointingModelView           = DBModelView    (data_model=AnointingModel       (),parent=self)

    def initFocusingModelView           (self):
        if not self.hasFocusingModelView           :
            self.FocusingModelView            = DBModelView    (data_model=FocusingConfigModel  (),parent=self)

    def initSlideCaseModelView          (self):
        if not self.hasSlideCaseModelView          :
            self.SlideCaseModelView           = SlideModelView (data_model=SlideCaseModel       (),parent=self)

    def initCellModelView               (self):
        if not self.hasCellModelView               :
            self.CellModelView                = SlideModelView (data_model=CellModel            (),parent=self)

    def initChamberStatusModelView      (self):
        if not self.hasChamberStatusModelView      :
            self.ChamberStatusModelView       = SlideModelView (data_model=ChamberStatusModel   (),parent=self)

    def initImageModelView              (self):
        if not self.hasImageModelView              :
            self.ImageModelView               = DBModelView    (data_model=ImageConfigModel     (),parent=self)




    @property
    def business(self) -> AppScanningFlow:
        return None if not self.hasBusiness else self.Business

    @property
    def hasHitBot(self) -> bool:
        return self.hasBusiness and self.Business.hasHitBot

    @property
    def hasMotion(self) -> bool:
        return self.hasBusiness and self.Business.hasMotion

    @property
    def hasCamera(self) -> bool:
        return self.hasBusiness and self.Business.hasCamera

    @property
    def hitbot(self):
        return None if not self.hasHitBot else self.Business.hitbot

    @property
    def motion(self):
        return None if not self.hasMotion else self.Business.motion

    @property
    def camera(self):
        return None if not self.hasCamera else self.Business.camera


    @property
    def hasBusiness                    (self) -> bool:
        return hasattr(self, 'Business'               ) and isinstance(self.Business                    , AppScanningFlow       )

    @property
    def hasMotionControl                     (self) -> bool:
        return hasattr(self, 'MotionControl'                ) and isinstance(self.MotionControl                     , MotionControlView     )

    @property
    def hasSlideData                   (self) -> bool:
        return hasattr(self, 'SlideData'              ) and isinstance(self.SlideData                   , DrawSlidesDataView    )

    @property
    def hasOperation                   (self) -> bool:
        return hasattr(self, 'Operation'              ) and isinstance(self.Operation                   , SlideOperationView    )

    @property
    def hasStacked                     (self) -> bool:
        return hasattr(self, 'Stacked'                ) and isinstance(self.Stacked                     , Qt.QStackedLayout     )

    @property
    def hasCameraView                  (self) -> bool:
        return hasattr(self, 'CameraView'                 ) and isinstance(self.CameraView                      , CameraConfigView    )

    @property
    def hasChamberStatusModel          (self) -> bool:
        return hasattr(self, 'ChamberStatusModel'     ) and isinstance(self.ChamberStatusModel          , SlideModelView        )

    @property
    def hasSlideFocusingModel          (self) -> bool:
        return hasattr(self, 'SlideFocusingModel'     ) and isinstance(self.SlideFocusingModel          , SlideModelView        )

    @property
    def hasSlideScanningModel          (self) -> bool:
        return hasattr(self, 'SlideScanningModel'     ) and isinstance(self.SlideScanningModel          , SlideModelView        )

    @property
    def hasCellModel                   (self) -> bool:
        return hasattr(self, 'CellModel'              ) and isinstance(self.CellModel                   , SlideModelView        )

    @property
    def hasSlideOilDropModel           (self) -> bool:
        return hasattr(self, 'SlideOilDropModel'      ) and isinstance(self.SlideOilDropModel           , SlideModelView        )

    @property
    def hasSlideHigFocusingModel       (self) -> bool:
        return hasattr(self, 'SlideHigFocusingModel'  ) and isinstance(self.SlideHigFocusingModel       , SlideModelView        )

    @property
    def hasSlideCaseModel              (self) -> bool:
        return hasattr(self, 'SlideCaseModel'         ) and isinstance(self.SlideCaseModel              , SlideModelView        )

    @property
    def hasObjectiveModel              (self) -> bool:
        return hasattr(self, 'ObjectiveModel'         ) and isinstance(self.ObjectiveModel              , DBModelView           )

    @property
    def hasCameraModelModel            (self) -> bool:
        return hasattr(self, 'CameraModelModel'       ) and isinstance(self.CameraModelModel            , DBModelView           )

    @property
    def hasImageConfigModel            (self) -> bool:
        return hasattr(self, 'ImageConfigModel'       ) and isinstance(self.ImageConfigModel            , DBModelView           )

    @property
    def hasTrayModel                   (self) -> bool:
        return hasattr(self, 'TrayModel'              ) and isinstance(self.TrayModel                   , DBModelView           )

    @property
    def hasAnointingModel              (self) -> bool:
        return hasattr(self, 'AnointingModel'         ) and isinstance(self.AnointingModel              , DBModelView           )

    @property
    def hasModel(self) -> bool:
        return hasattr(self, 'Model') and isinstance(self.Model, SlideModelInterface)

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




    @property
    def hasCameraParameter(self) -> bool:
        return hasattr(self, 'CameraParameter') and isinstance(self.CameraParameter, CameraInterface)



    @property
    def hasCurrentWidget(self) -> bool:
        return hasattr(self, 'CurrentWidget') and isinstance(self.CurrentWidget, Qt.QWidget)











    @property
    def hasObjectiveModelView          (self) -> bool:
        return hasattr(self, 'ObjectiveModelView'    ) and isinstance(self.ObjectiveModelView          , DBModelView    )

    @property
    def hasCameraModelModelView        (self) -> bool:
        return hasattr(self, 'CameraModelModelView'  ) and isinstance(self.CameraModelModelView        , DBModelView    )

    @property
    def hasTrayModelView               (self) -> bool:
        return hasattr(self, 'TrayModelView'         ) and isinstance(self.TrayModelView               , DBModelView    )

    @property
    def hasAnointingModelView          (self) -> bool:
        return hasattr(self, 'AnointingModelView'    ) and isinstance(self.AnointingModelView          , DBModelView    )

    @property
    def hasFocusingModelView           (self) -> bool:
        return hasattr(self, 'FocusingModelView'     ) and isinstance(self.FocusingModelView           , DBModelView    )

    @property
    def hasSlideCaseModelView          (self) -> bool:
        return hasattr(self, 'SlideCaseModelView'    ) and isinstance(self.SlideCaseModelView          , SlideModelView )

    @property
    def hasCellModelView               (self) -> bool:
        return hasattr(self, 'CellModelView'         ) and isinstance(self.CellModelView               , SlideModelView )

    @property
    def hasChamberStatusModelView      (self) -> bool:
        return hasattr(self, 'ChamberStatusModelView') and isinstance(self.ChamberStatusModelView      , SlideModelView )

    @property
    def hasImageModelView              (self) -> bool:
        return hasattr(self, 'ImageModelView'        ) and isinstance(self.ImageModelView              , DBModelView    )
