#!D:/IDE/anaconda3/envs/Microscope_Scan python
# -*- coding: UTF-8 -*-
"""
@FileName：GimbalDashboardOperation.py
@Description：
@Author：XSH
@Time：2025/12/17 17:15
@Department：研发部
@Copyright：©2025 乐辰生物
"""
from abc                        import abstractmethod                     #
from PyQt5                      import Qt                                 #
from AppInterfaces.UiInterface  import UiInterface                        #
from AppInterfaces.globalSlot   import globalSlot, AppSlot                #
from AppCore.Contexts           import *                                  #
from AppCore.DBModels           import *                                  #
from AppCore.Levels             import *                                  #
from AppUtils.utils             import *                                  #

class GimbalDashboardOperation(Qt.QWidget, UiInterface):
    AxisMoveSignal      : Qt.pyqtSignal = Qt.pyqtSignal(object, object)
    MicroscopeMoveSignal: Qt.pyqtSignal = Qt.pyqtSignal(object)
    GimbalFrame         : Qt.QLabel                 # 云台窗口
    GoalFrame           : Qt.QLabel                 # 目标窗口
    GimbalIcon          : Qt.QPixmap                # 云台图标
    GoalIcon            : Qt.QPixmap                # 目标图标
    PressPoint          : Qt.QPoint                 # 按下位置
    LastPoint           : Qt.QPoint                 # 上次位置
    OffsetX             : int                       # 云台偏移量
    OffsetY             : int                       # 云台偏移量
    OffsetZ             : int                       # 云台偏移量
    GimbalW             : int                       # 云台宽度
    GimbalH             : int                       # 云台高度
    GoalW               : int                       # 目标宽度
    GoalH               : int                       # 目标高度

    def __init__(self, parent: Qt.QWidget = None):
        super(GimbalDashboardOperation, self).__init__(parent)
        self.Initialization("", self, parent)


    def initValue(self):
        super(GimbalDashboardOperation, self).initValue()
        self.initGimbalFrame         ()
        self.initGoalFrame           ()
        self.initGimbalIcon          ()
        self.initGoalIcon            ()
        self.initPressPoint          ()
        self.initReleasePoint        ()
        self.initGimbalW             ()
        self.initGimbalH             ()
        self.initGoalW               ()
        self.initGoalH               ()

    def initProperty(self):
        super(GimbalDashboardOperation, self).initProperty()
        self.GimbalFrame.setPixmap(self.GimbalIcon)
        self.GoalFrame.setPixmap(self.GoalIcon)
        # UiUtils.to_center(self.GimbalFrame  , self.geometry())
        UiUtils.to_center(self.GoalFrame    , self.geometry())
        # self.setMinimumSize(self.GimbalFrame.width() + 100, self.GoalFrame.height() + 100)


    def initLayouts(self):
        if self.hasWindowLayouts:
            return
        main_layout: Qt.QGridLayout = Qt.QGridLayout()
        main_layout.setSpacing(0)
        main_layout.setContentsMargins(0, 0, 0, 0)
        main_layout.addWidget(self.GimbalFrame, 0, 0, -1, -1)
        self.setLayout(main_layout)


    def mousePressEvent(self, ev: Qt.QMouseEvent) -> None:
        self.OffsetZ = None
        self.MicroscopeMoveSignal.emit(self.OffsetZ)
        if ev.button() == Qt.Qt.LeftButton or ev.button() == Qt.Qt.RightButton:

            self.setMovePoint(ev.globalPos(), True)
            self.MicroscopeMoveSignal.emit(self.OffsetZ)
            ev.accept()
        else:
            return super(GimbalDashboardOperation, self).mousePressEvent(ev)

    def mouseReleaseEvent(self, ev: Qt.QMouseEvent) -> None:
        self.OffsetZ = None
        if ev.button() == Qt.Qt.LeftButton or ev.button() == Qt.Qt.RightButton:
            self.initMovePoint()
            self.move_center()
            self.MicroscopeMoveSignal.emit(self.OffsetZ)
            self.AxisMoveSignal.emit(self.OffsetX, self.OffsetY)
            ev.accept()
        else:
            return super(GimbalDashboardOperation, self).mouseReleaseEvent(ev)

    def mouseDoubleClickEvent(self, ev: Qt.QMouseEvent) -> None:
        self.initMovePoint()
        self.move_center()
        self.MicroscopeMoveSignal.emit(self.OffsetZ)
        self.AxisMoveSignal.emit(self.OffsetX, self.OffsetY)
        super(GimbalDashboardOperation, self).mouseDoubleClickEvent(ev)

    def mouseMoveEvent(self, ev: Qt.QMouseEvent) -> None:
        if self.IsPress and self.hasLastPoint:
            delta_x = ev.globalPos().x() - self.LastPoint.x()
            delta_y = ev.globalPos().y() - self.LastPoint.y()
            self.setOffset(delta_x, delta_y)
            self.move_offset_center(delta_x, delta_y)
            self.AxisMoveSignal.emit(self.OffsetX, self.OffsetY)
            ev.accept()
        else:
            return super(GimbalDashboardOperation, self).mouseMoveEvent(ev)

    def wheelEvent(self, ev: Qt.QWheelEvent) -> None:
        if self.hasOffsetZ:
            self.OffsetZ += ev.angleDelta().y()
        else:
            self.OffsetZ = ev.angleDelta().y()
        print(self.OffsetZ)
        self.MicroscopeMoveSignal.emit(self.OffsetZ)
        return super(GimbalDashboardOperation, self).wheelEvent(ev)

    def resizeEvent(self, ev: Qt.QResizeEvent) -> None:
        flag = super(GimbalDashboardOperation, self).resizeEvent(ev)
        self.move_center()
        return flag

    def move_center(self):
        # UiUtils.to_center(self.GimbalFrame  , self.geometry())
        UiUtils.to_center(self.GoalFrame    , self.geometry())

    def move_offset_center(self, offset_x: int = 0, offset_y: int = 0):
        # UiUtils.to_center           (self.GimbalFrame  , self.geometry()                    )
        UiUtils.to_offset_center  (self.GoalFrame    , self.geometry(), offset_x, offset_y)

    def initMovePoint(self):
        self.LastPoint  = None          #
        self.IsPress    = False         #
        self.PressPoint = None          #
        self.OffsetX    = None          #
        self.OffsetY    = None          #
        self.OffsetZ    = None          #

    def setMovePoint(self, pos: (Qt.QPoint, Qt.QPointF), is_press: bool = True):
        self.LastPoint = pos
        self.IsPress = True if isinstance(is_press, (bool, int)) and is_press else False


    def setOffset(self, offset_x: int = None, offset_y: int = None, offset_z: int = None):
        self.OffsetX = offset_x if isinstance(offset_x, (int, float)) else None
        self.OffsetY = offset_y if isinstance(offset_y, (int, float)) else None
        self.OffsetZ = offset_z if isinstance(offset_z, (int, float)) else None


    def initGimbalFrame         (self):
        if not self.hasGimbalFrame         :
            self.GimbalFrame          = Qt.QLabel  (self)
            self.initGimbalW()
            self.initGimbalH()
            self.GimbalFrame.setFixedSize(self.GimbalW, self.GimbalH)
            self.GimbalFrame.setAttribute(Qt.Qt.WA_StyledBackground)
            self.GimbalFrame.setAttribute(Qt.Qt.WA_TranslucentBackground)
            self.GimbalFrame.setScaledContents(True)

    def initGoalFrame(self):
        if not self.hasGoalFrame:
            self.GoalFrame          = Qt.QLabel  (self)
            self.initGoalH()
            self.initGoalW()
            self.GoalFrame.setFixedSize(self.GoalW, self.GoalH)
            self.GoalFrame.setAttribute(Qt.Qt.WA_StyledBackground)
            self.GoalFrame.setAttribute(Qt.Qt.WA_TranslucentBackground)
            self.GoalFrame.setScaledContents(True)

    def initGoalIcon            (self):
        if not self.hasGoalIcon            :
            self.GoalIcon             = Qt.QPixmap (AppUtils.toSourceFile("Icon/Goal3.png"))

    def initGimbalIcon          (self):
        if not self.hasGimbalIcon          :
            self.GimbalIcon = Qt.QPixmap(AppUtils.toSourceFile("Icon/GimbalDashboard.png"))
            # self.GimbalIcon           = Qt.QPixmap (AppUtils.toSourceFile("Icon/GimbalDashboard1.png"))

    def initPressPoint          (self):
        if not self.hasPressPoint          :
            self.PressPoint           = Qt.QPoint  ()

    def initReleasePoint        (self):
        if not self.hasReleasePoint        :
            self.ReleasePoint         = Qt.QPoint  ()

    def initLastPoint(self):
        if not self.hasLastPoint:
            self.LastPoint           = Qt.QPoint  ()

    def initGimbalW             (self):
        if not self.hasGimbalW             :
            self.GimbalW              = int        (150)

    def initGimbalH             (self):
        if not self.hasGimbalH             :
            self.GimbalH              = int        (150)

    def initGoalW               (self):
        if not self.hasGoalW               :
            self.GoalW                = int        (60)

    def initGoalH               (self):
        if not self.hasGoalH               :
            self.GoalH                = int        (60)

    @property
    def offset_x(self) -> int:
        return 0 if self.hasOffsetX else self.OffsetX

    @property
    def offset_y(self) -> int:
        return 0 if self.hasOffsetY else self.OffsetY

    @property
    def offset_z(self) -> int:
        return 0 if self.hasOffsetZ else self.OffsetZ

    @property
    def has_offset_xy(self) -> bool:
        return self.hasOffsetX and self.hasOffsetY






    @property
    def hasGimbalFrame         (self) -> bool:
        return self.has_field('GimbalFrame'  , Qt.QLabel  )

    @property
    def hasGoalFrame(self):
        return self.has_field('GoalFrame'    , Qt.QLabel  )

    @property
    def hasGoalIcon            (self) -> bool:
        return self.has_field('GoalIcon'     , Qt.QPixmap )

    @property
    def hasGimbalIcon          (self) -> bool:
        return self.has_field('GimbalIcon'   , Qt.QPixmap )

    @property
    def hasPressPoint          (self) -> bool:
        return self.has_field('PressPoint'   , Qt.QPoint  )

    @property
    def hasReleasePoint        (self) -> bool:
        return self.has_field('ReleasePoint' , Qt.QPoint  )

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

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

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

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

    @property
    def hasOffsetX(self) -> bool:
        return self.has_field('OffsetX', (int, float))

    @property
    def hasOffsetY(self) -> bool:
        return self.has_field('OffsetY', (int, float))

    @property
    def hasOffsetZ(self) -> bool:
        return self.has_field('OffsetZ', (int, float))

    @property
    def hasLastPoint(self) -> bool:
        return self.has_field('LastPoint', (Qt.QPoint, Qt.QPointF))