#!D:/IDE/anaconda3/envs/Microscope_Scan python
# -*- coding: UTF-8 -*-
"""
@FileName：SlideController.py
@Description：
@Author：XSH
@Time：2025/12/23 16:34
@Department：研发部
@Copyright：©2025 乐辰生物
"""
import sys
import os
from PyQt5                                                      import Qt                                               #
from AppSettings.Settings                                       import *                                                #
from AppInterfaces.utils                                        import *                                                #
from AppCore.Levels                                             import *                                                #
from AppCore.DBModels                                           import *                                                #
from AppUtils.utils                                             import *                                                #
from AppInterfaces.UiInterface                                  import UiInterface                                      #
from AppBackEnd.AppBusinessInterface                            import AppBusinessInterface                             #
from AppHeadEnd.Commons.OperationViews.SlideOperation           import SlideOperation, SlideFrame                       #
from AppHeadEnd.Commons.OperationViews.SlideButtonOperation     import SlideButtonOperation                             #
from AppHeadEnd.ControllerFrames.ControlFrameInterface          import ControlFrameInterface                            #
from AppUtils.HardWareUnit                                      import HardWareUnit                                     #
class SlideController(Qt.QWidget, ControlFrameInterface):
    Operation   : SlideOperation        #
    Buttons     : SlideButtonOperation  #
    Objective   : ObjectiveModel        #
    Level       : int                   #
    SlideNumber : int                   #

    def __init__(self, business:AppBusinessInterface, parent: Qt.QWidget = None):
        super(SlideController, self).__init__(parent)
        self.Business = business
        self.Initialization('玻片校准界面', self, parent)
        self.initWindowIcon()

    def initConnect(self):
        super(SlideController, self).initConnect()
        TYPE: Qt.Qt.ConnectionType = Qt.Qt.ConnectionType(Qt.Qt.AutoConnection | Qt.Qt.UniqueConnection)
        self.Buttons.LastButton      .clicked.connect(self.SlotLastButton      , TYPE)
        self.Buttons.BeginButton     .clicked.connect(self.SlotBeginButton     , TYPE)
        self.Buttons.EndButton       .clicked.connect(self.SlotEndButton       , TYPE)
        self.Buttons.NextButton      .clicked.connect(self.SlotNextButton      , TYPE)
        self.Buttons.DoneButton      .clicked.connect(self.SlotDoneButton      , TYPE)
        self.Operation.clicked.connect(self.SlotOperationClicked, TYPE)

    def SlotOperationClicked(self, number: int):
        if not self.isAvailable():
            return
        if not isinstance(number, int) or number not in TrayLevel.all():
            return
        self.SlideNumber = self.Operation.number
        Tray: TrayModel = TrayModel.getConfig(self.SlideNumber)
        HardWareUnit.axis_waitmove_xy(self.axis_x, self.axis_y, Tray.Position_X, Tray.Position_Y)

    def SlotLastButton      (self):
        SlideNumber: int = self.Operation.number
        SlideNumber = SlideNumber - 1
        if SlideNumber < TrayLevel.TraySlide1:
            SlideNumber = TrayLevel.TraySlide5
        if SlideNumber > TrayLevel.TraySlide5:
            SlideNumber = TrayLevel.TraySlide1
        self.SlideNumber = SlideNumber
        Tray: TrayModel = TrayModel.getConfig(self.SlideNumber)
        HardWareUnit.axis_waitmove_xy(self.axis_x, self.axis_y, Tray.Position_X, Tray.Position_Y)

    def SlotBeginButton     (self):
        if not self.hasSlideNumber or not self.isAvailable():
            return
        isWrong, x, y = HardWareUnit.get_axis_position_xy(self.axis_x, self.axis_y)
        if RECODE_SUCCEED != isWrong or not isinstance(x, (int, float)) or not isinstance(y, (int, float)):
            return
        Tray: TrayModel = TrayModel.getConfig(self.SlideNumber)
        if not isinstance(Tray, TrayModel):
            return
        Tray.Position_X = round(x, 2)
        Tray.Position_Y = round(y, 2)
        TrayModel.changed({TrayModel.Position_X: x,
                           TrayModel.Position_Y: y},
                          TrayModel.Level == self.SlideNumber)
        TraySlideModel.changed({TraySlideModel.Position_X: x, TraySlideModel.Position_Y: y}, TraySlideModel.ID ==  self.SlideNumber)
        if Tray.Level == TrayLevel.TraySlide1:
            for tray_number in TrayLevel.all():
                TraySlideModel.changed({TraySlideModel.Position_X: 0, TraySlideModel.Position_Y: 0}, TraySlideModel.ID == tray_number)

            TrayConfigModel.changed({TrayConfigModel.Position_X: x, TrayConfigModel.Position_Y: y})
        Slide: TraySlideModel = TraySlideModel.getConfig(ID=1)
        if not isinstance(Slide, TraySlideModel):
            return
        SlideSpacing: float = round(abs(Slide.Position_X - x), 2)
        TraySlideModel.changed({TraySlideModel.ImageCellWidth: SlideSpacing}, TraySlideModel.ID == self.SlideNumber)
    def SlotEndButton       (self):
        isWrong, x, y = HardWareUnit.get_axis_position_xy(self.axis_x, self.axis_y)
        if RECODE_SUCCEED != isWrong or not isinstance(x, (int, float)) or not isinstance(y, (int, float)):
            return
        Tray: TrayModel = TrayModel.getConfig(self.SlideNumber)
        if not isinstance(Tray, TrayModel):
            return
        SlideWidth  : int = round(abs(Tray.Position_X - x), 2)
        SlideHeight : int = round(abs(Tray.Position_Y - y), 2)
        MaxRowNumber           = int(round(SlideWidth             / Tray.Step_X      , 4))
        MaxColNumber           = int(round(SlideHeight            / Tray.Step_Y      , 4))
        MaxRowNumber20X        = int(round(SlideWidth             / Tray.Step_X_20X  , 4))
        MaxColNumber20X        = int(round(SlideHeight            / Tray.Step_Y_20X  , 4))
        TrayModel.changed({TrayModel.SlideWidth             : SlideWidth                ,
                           TrayModel.SlideHeight            : SlideHeight               ,
                           TrayModel.MaxRowNumber           : MaxRowNumber              ,
                           TrayModel.MaxColNumber           : MaxColNumber              ,
                           TrayModel.MaxRowNumber20X        : MaxRowNumber20X           ,
                           TrayModel.MaxColNumber20X        : MaxColNumber20X           ,
                           TrayModel.IsCalibrate            : 1                         ,
                           },
                          TrayModel.Level == self.SlideNumber)
        if Tray.Level == TrayLevel.TraySlide1:
            TrayConfigModel.changed({TrayConfigModel.SlideWidth             : SlideWidth                ,TrayConfigModel.SlideHeight            : SlideHeight               ,})
        else:
            TraySlideModel.changed({TraySlideModel.Position_X: x, TraySlideModel.Position_Y: y}, TraySlideModel.ID == self.SlideNumber)


    def SlotNextButton      (self):
        SlideNumber: int = self.Operation.number
        SlideNumber = SlideNumber + 1
        if SlideNumber < TrayLevel.TraySlide1:
            SlideNumber = TrayLevel.TraySlide5
        if SlideNumber > TrayLevel.TraySlide5:
            SlideNumber = TrayLevel.TraySlide1
        self.SlideNumber = SlideNumber
        Tray: TrayModel = TrayModel.getConfig(self.SlideNumber)
        HardWareUnit.axis_waitmove_xy(self.axis_x, self.axis_y, Tray.Position_X, Tray.Position_Y)

    def SlotDoneButton      (self):
        pass


    def initValue(self):
        super(SlideController, self).initValue()
        self.initOperation  ()
        self.initButtons    ()
        self.initSlideNumber()
        self.initLevel      ()
        self.initObjective  ()



    def initProperty(self):
        super(SlideController, self).initProperty()
        self.setFixedSize(250 * 3, 750 * 0.7)

    def initLayouts(self):
        if self.hasWindowLayouts:
            return
        main_layout: Qt.QVBoxLayout = Qt.QVBoxLayout()
        main_layout.setSpacing(5)
        main_layout.setContentsMargins(10, 10, 10, 10)


        main_layout.addWidget(self.Operation)
        main_layout.addWidget(self.Buttons)
        self.setLayout(main_layout)



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


    def initButtons     (self):
        if not self.hasButtons     :
            self.Buttons      = SlideButtonOperation()


    def initObjective   (self):
        if not self.hasObjective   :
            self.Objective    = ObjectiveModel.getConfig(ObjectiveLevel.Objective10)


    def initLevel       (self):
        if not self.hasLevel       :
            self.Level        = ObjectiveLevel.Objective10


    def initSlideNumber (self):
        if not self.hasSlideNumber :
            self.SlideNumber  = TrayLevel.TraySlide1


    @property
    def hasOperation   (self) -> bool:
        return self.has_field('Operation'    , SlideOperation      )

    @property
    def hasButtons     (self) -> bool:
        return self.has_field('Buttons'      , SlideButtonOperation)

    @property
    def hasObjective   (self) -> bool:
        return self.has_field('Objective'    , ObjectiveModel      )

    @property
    def hasLevel       (self) -> bool:
        return self.has_field('Level'        , int                 )

    @property
    def hasSlideNumber (self) -> bool:
        return self.has_field('SlideNumber'  , int                 )
