from PyQt5.QtCore import QPropertyAnimation, QParallelAnimationGroup, QAbstractAnimation, QSize, Qt
from PyQt5.QtGui import QPainter, QColor
from PyQt5.QtWidgets import QWidget, QStyleOption, QStyle, QVBoxLayout, QApplication, QLabel, QGraphicsDropShadowEffect

from config import config
from kit.component.kit_button import KitButton
from kit.component.kit_overlay import KitOverlay


class KitDrawer(QWidget):
    """
    侧边栏抽屉
    """
    Left = 0
    Top = 1
    Right = 2
    Bottom = 3

    CloseOnClicked = 0
    CloseOnEscape = 1

    def __init__(self, orientation=Left):
        super(KitDrawer, self).__init__()

        # 内部使用的变量
        self._parent = None
        self._width = 300
        self._height = 300
        self._orientation = orientation
        self.close_policy = KitDrawer.CloseOnClicked
        self.overlay = KitOverlay()

        self.__init_widget()
        self.__init_slot()
        self.__init_qss()

    def setWidth(self, width):
        if self._orientation == self.Left or self._orientation == self.Right:
            self._width = width

    def setHeight(self, height):
        if self._orientation == self.Top or self._orientation == self.Bottom:
            self._height = height

    def setClosePolicy(self, policy: int):
        self.close_policy = policy
        self.overlay.setClosePolicy(policy)

    def __init_widget(self):
        self.hide()
        self.overlay.setClosePolicy(KitOverlay.CloseOnClicked)

    def __init_slot(self):
        self.overlay.clicked.connect(lambda: self.close() if self.close_policy == KitDrawer.CloseOnClicked else None)
        self.overlay.resized.connect(lambda: self.__init_size())
        self.overlay.resized.connect(lambda: self.__fresh_position())

    def __init_qss(self):
        self.setAttribute(Qt.WA_StyledBackground, True)

        shadow = QGraphicsDropShadowEffect(self)
        shadow.setOffset(0, 0)
        shadow.setBlurRadius(10)
        shadow.setColor(QColor(0, 0, 0, 80))
        self.setGraphicsEffect(shadow)

    def __init_size(self):
        """
        初始化大小
        """
        if self._orientation == self.Left or self._orientation == self.Right:
            self.setFixedSize(self._width, self._parent.height())
        elif self._orientation == self.Top or self._orientation == self.Bottom:
            self.setFixedSize(self._parent.width(), self._height)

    def __init_parent(self):
        """
        初始化父类
        """
        window = QApplication.activeWindow()
        if window is not None:
            self._parent = window
            self.setParent(self._parent)
        else:
            self._parent = None

    def __init_position(self):
        """
        初始化位置
        """
        if self._orientation == self.Left:
            self.move(0 - self._width, 0)
        elif self._orientation == self.Top:
            self.move(0, 0 - self._height)
        elif self._orientation == self.Right:
            self.move(self._parent.width(), 0)
        elif self._orientation == self.Bottom:
            self.move(0, self._parent.height())

    def __fresh_position(self):
        if self.isHidden():
            return
        if self._orientation == self.Left:
            self.move(0, 0)
        elif self._orientation == self.Top:
            self.move(0, 0)
        elif self._orientation == self.Right:
            self.move(self._parent.width() - self._width, 0)
        elif self._orientation == self.Bottom:
            self.move(0, self._parent.height() - self._height)

    def __init_animation(self):
        """
        初始化动画
        """
        # 滑出动画
        self.__sizeAnimation = None
        if self._orientation == KitDrawer.Left:
            self.__sizeAnimation = QPropertyAnimation(self, b"x")
            self.__sizeAnimation.setStartValue(0)
            self.__sizeAnimation.setEndValue(self._width)
            self.__sizeAnimation.valueChanged.connect(lambda value: self.move(value - self._width, 0))
        elif self._orientation == KitDrawer.Top:
            self.__sizeAnimation = QPropertyAnimation(self, b"y")
            self.__sizeAnimation.setStartValue(0)
            self.__sizeAnimation.setEndValue(self._height)
            self.__sizeAnimation.valueChanged.connect(lambda value: self.move(0, value - self._height))
        elif self._orientation == KitDrawer.Right:
            self.__sizeAnimation = QPropertyAnimation(self, b"x")
            self.__sizeAnimation.setStartValue(0)
            self.__sizeAnimation.setEndValue(self._width)
            self.__sizeAnimation.valueChanged.connect(lambda value: self.move(self._parent.width() - value, 0))
        elif self._orientation == KitDrawer.Bottom:
            self.__sizeAnimation = QPropertyAnimation(self, b"y")
            self.__sizeAnimation.setStartValue(0)
            self.__sizeAnimation.setEndValue(self._height)
            self.__sizeAnimation.valueChanged.connect(lambda value: self.move(0, self._parent.height() - value))

        # 动画合集
        self.__animation_group = QParallelAnimationGroup()
        self.__animation_group.addAnimation(self.__sizeAnimation)

    def open(self):
        """
        打开抽屉
        """
        self.__init_parent()
        self.__init_animation()
        self.__animation_group.setDirection(QAbstractAnimation.Forward)
        self.overlay.show()
        self.setHidden(False)
        self.raise_()
        self.__animation_group.start()

    def close(self):
        """
        关闭抽屉
        """
        self.overlay.close()
        self.__animation_group.setDirection(QAbstractAnimation.Backward)
        self.__animation_group.start()
        self.__animation_group.finished.connect(self.hide)


if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    qss = config.init_qss()
    app.setStyleSheet(qss)
    top_main = QWidget()
    top_main.setObjectName('top_main')
    top_main.resize(800, 800)
    top_main_layout = QVBoxLayout()
    top_main.setLayout(top_main_layout)

    main = QWidget()
    main.setObjectName('main')
    main.resize(400, 400)
    main_layout = QVBoxLayout()
    main.setLayout(main_layout)

    top_main_layout.addWidget(main)

    drawer_left = KitDrawer(orientation=KitDrawer.Left)
    drawer_left.setWidth(600)
    drawer_left.setClosePolicy(KitDrawer.CloseOnEscape)
    btn = KitButton('left')
    btn.clicked.connect(lambda: drawer_left.open())
    drawer_left.setLayout(QVBoxLayout())
    close_left = KitButton('close')
    close_left.clicked.connect(lambda: drawer_left.close())
    drawer_left.layout().addWidget(close_left)

    drawer_right = KitDrawer(orientation=KitDrawer.Right)
    btn2 = KitButton('right')
    btn2.clicked.connect(lambda: drawer_right.open())
    drawer_right.setLayout(QVBoxLayout())
    close_right = KitButton('close')
    close_right.clicked.connect(lambda: drawer_right.close())
    drawer_right.layout().addWidget(close_right)

    drawer_top = KitDrawer(orientation=KitDrawer.Top)
    btn3 = KitButton('top')
    btn3.clicked.connect(lambda: drawer_top.open())
    drawer_top.setLayout(QVBoxLayout())
    close_top = KitButton('close')
    close_top.clicked.connect(lambda: drawer_top.close())
    drawer_top.layout().addWidget(close_top)

    drawer_bottom = KitDrawer(orientation=KitDrawer.Bottom)
    btn4 = KitButton('bottom')
    btn4.clicked.connect(lambda: drawer_bottom.open())
    drawer_bottom.setLayout(QVBoxLayout())
    close_bottom = KitButton('close')
    close_bottom.clicked.connect(lambda: drawer_bottom.close())
    drawer_bottom.layout().addWidget(close_bottom)

    main_layout.addWidget(btn)
    main_layout.addWidget(btn2)
    main_layout.addWidget(btn3)
    main_layout.addWidget(btn4)

    top_main.show()
    sys.exit(app.exec_())
