/*
 * Copyright (C) 2023, KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

import QtQuick 2.12
// import QtGraphicalEffects 1.12
import Qt5Compat.GraphicalEffects
import org.ukui.notification.ui 1.0
import org.ukui.sidebar.core 1.0
import org.ukui.quick.platform 1.0 as Platform

Item {
    id: root
    property int duration: 300
    LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
    LayoutMirroring.childrenInherit: true

    Component.onCompleted: {
        sidebarWindow.requestShowContent.connect(showContent);
        sidebarWindow.requestHideContent.connect(hideContent);
        sidebarWindow.radius = Qt.binding(function() { return Platform.GlobalTheme.kRadiusWindow; });

        handGestureHelper.controlCenterCalled.connect(trackMouse)
        handGestureHelper.right2LeftReleased.connect(mouseReleased)
    }

    Keys.onEscapePressed: {
        if (sidebarWindow.visible) {
            sidebarWindow.activeWindow(false);
        }
    }

    function updateProperty(active) {
        if (active) {
            notificationArea.x = notificationAreaBase.width + sidebarWindow.windowPadding;
            windowBlurHelper.radius = 0;

        } else {
            notificationArea.x = 0;
        }

        windowBlurHelper.enable = sidebarWindow.isTabletMode;
    }

    function isRunning(active) {
        return notificationAnimation.running;
    }

    function showContent() {
        notificationAreaBase.startAnimation(
                    LayoutMirroring.enabled
                    ? -(notificationAreaBase.width + sidebarWindow.windowPadding)
                    : notificationAreaBase.width + sidebarWindow.windowPadding, 0, root.duration, true);
    }

    function hideContent() {
        notificationAreaBase.startAnimation(
                    0,
                    LayoutMirroring.enabled
                    ? -(notificationAreaBase.width + sidebarWindow.windowPadding)
                    : notificationAreaBase.width + sidebarWindow.windowPadding, root.duration, false);
    }

    function trackMouse(posX) {
        if (sidebarWindow.isTabletMode) {
            return;
        }

        if (sidebarWindow.contentVisible) {
            return;
        }

        if (notificationAnimation.running === true) {
            notificationAnimation.running = false;
        }

        if (!sidebarWindow.visible) {
            updateProperty(true);
            sidebarWindow.show();
        }

        // 鼠标位置与当前主屏幕左边界/右边界的距离
        let distanceX = LayoutMirroring.enabled
            ? posX
            : sidebarWindow.primaryScreenRight - posX;

        if (distanceX < 0) {
            if (sidebarWindow.visible) {
                sidebarWindow.hide();
            }
            return;
        }
        // 加上padding忽略窗口的边距
        let notificationWidth = 384 + sidebarWindow.windowPadding;
        if (distanceX > notificationWidth) {
            distanceX = notificationWidth;
        }

        notificationArea.x = LayoutMirroring.enabled
                ? distanceX - notificationWidth
                : notificationWidth - distanceX;
    }

    // 唤起侧边栏手势释放事件
    function mouseReleased(posX) {
        if (!sidebarWindow.visible || sidebarWindow.contentVisible) {
            return;
        }

        // 鼠标位置与当前主屏幕左边界/右边界的距离
        let distanceX = LayoutMirroring.enabled
            ? posX
            : sidebarWindow.primaryScreenRight - posX;
        let notificationWidth = 384 + sidebarWindow.windowPadding;
        let duration = 50;

        // 如果为负值，快速隐藏
        if (distanceX < 0) {
            notificationAreaBase.startAnimation(notificationArea.x,
                                                LayoutMirroring.enabled
                                                ? -notificationWidth
                                                : notificationWidth, duration, false);
            return;
        }

        // 屏幕宽度的5%
        if (distanceX <= sidebarWindow.minimumThreshold) {
            duration = Math.floor(root.duration * (distanceX / notificationWidth));
            notificationAreaBase.startAnimation(notificationArea.x,
                                                LayoutMirroring.enabled
                                                ? -notificationWidth
                                                : notificationWidth, duration, false);
            return;
        }

        duration = Math.floor(root.duration * ((notificationWidth - distanceX) / notificationWidth));
        notificationAreaBase.startAnimation(notificationArea.x, 0, duration, true);
        EventTrack.sendSlideEvent("open_sidebar", "sidebar", {"type": "slide"});
    }

    NumberAnimation {
        id: showGroundGlass
        target: windowBlurHelper
        property: "radius"
        duration: root.duration
        from: 0
        to: 4000

        function startAnimation() {
            if (isLiteMode) {
                windowBlurHelper.radius = 4000;
                return;
            }

            start();
        }
    }

    // 阴影区域
    ShadowComponent {
        id: shadowArea;
        z: 10;
        visible: !sidebarWindow.isTabletMode && isOpenGLEnv;
        radius: Platform.GlobalTheme.kRadiusWindow;
        x: notificationAreaBase.x - sidebarWindow.windowPadding;
        y: notificationAreaBase.y - sidebarWindow.windowPadding;
        width: notificationAreaBase.width + sidebarWindow.windowPadding*2;
        height: notificationAreaBase.height + sidebarWindow.windowPadding*2;
    }

    Item {
        id: notificationAreaBase
        property bool isNotifyEmpty: sidebarWindow.isNotificationEmpty
        anchors.margins: sidebarWindow.windowPadding
        z: 100

        anchors.left: root.left
        height: sidebarWindow.minWindowSize
        anchors.right: root.right
        anchors.bottom: root.bottom


        function startAnimation(from, to, duration, isShow) {
            // console.log("=== start animation ===", from, to, duration, isShow)
            if (isLiteMode) {
                notificationArea.x = to;
                notificationAnimation.animationStopped(isShow);
                return;
            }

            if (notificationAnimation.running) {
                return;
            }
            notificationAnimation.from = from;
            notificationAnimation.to = to;
            notificationAnimation.duration = duration < 50 ? 50 : duration;
            notificationAnimation.isShow = isShow;

            notificationAnimation.start();
        }

        NumberAnimation {
            id: notificationAnimation
            property bool isShow: false

            target: notificationArea
            property: "x"
            easing.type: Easing.InOutQuad

            onStopped: { animationStopped(isShow); }

            function animationStopped(isShow) {
                if (isShow) {
                    sidebarWindow.contentVisible = true;
                    if (!sidebarWindow.isTabletMode) {
                        windowBlurHelper.enable = true;
                        showGroundGlass.startAnimation();
                    }
                } else {
                    sidebarWindow.contentVisible = false;
                    sidebarWindow.hide();
                }
            }
        }

        NotificationArea {
            id: notificationArea;
            visible: true
            width: 384;
            height: parent.height;
            clip: true;
            layer.enabled: isOpenGLEnv;
            layer.effect: OpacityMask {
                maskSource: Rectangle {
                    width: notificationArea.width;
                    height: notificationArea.height;
                    radius: sidebarWindow.radius;
                }
            }

            onXChanged: {
                shadowArea.x = notificationAreaBase.x - shadowArea.shadowWidth + notificationArea.x;

                if (sidebarWindow.isTabletMode) {
                    let shortAreaWidth = width + sidebarWindow.windowPadding;
                    let rightWidth = Math.abs(Math.floor(shortAreaWidth - x));
                    windowBlurHelper.radius = Math.floor(4000 * (rightWidth / shortAreaWidth));
                    windowBlurHelper.enable = (rightWidth !== 0);
                }
            }
        }

        NumberAnimation {
            id: foldChangeAnimation
            target: notificationAreaBase
            property: "height"
            duration: 300
            easing.type: Easing.InOutQuad
            onFinished: {
                if (sidebarWindow.isNotificationEmpty) {
                    //折叠
                    sidebarWindow.isWindowFold = true;
                }
            }
        }

        onIsNotifyEmptyChanged: {
            if (foldChangeAnimation.running) {
                foldChangeAnimation.running = false;
            }
            if (sidebarWindow.isNotificationEmpty) {
                foldChangeAnimation.to = sidebarWindow.minWindowSize;
                foldChangeAnimation.start();
            } else {
                //展开
                sidebarWindow.isWindowFold = false;
                foldChangeAnimation.to = root.height - sidebarWindow.windowPadding*2;
                foldChangeAnimation.start();
            }
        }

        function setWindowHeight() {
            if (!sidebarWindow.isWindowFold) {
                height = root.height - sidebarWindow.windowPadding*2;
            }
        }

        onHeightChanged: {
            sidebarWindow.setBlurHeight(height);
        }
    }

    onHeightChanged: {
        notificationAreaBase.setWindowHeight();
    }
}
