/*
 *  SPDX-FileCopyrightText: 2025 Micah Stanley <stanleymicah@proton.me>
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 */

import QtQuick
import QtQuick.Controls as Controls
import QtQuick.Layouts
import QtQuick.Effects

import org.kde.kirigami as Kirigami
import org.kde.plasma.private.mobileshell.state as MobileShellState
import org.kde.plasma.private.mobileshell as MobileShell

import org.kde.layershell 1.0 as LayerShell


Window {
    id: root

    readonly property int size: Kirigami.Units.gridUnit * 2
    readonly property int margins: Math.round(Kirigami.Units.largeSpace * 0.5)

    property int screenCorner: ActionButton.ScreenCorner.BottomRight
    property int angle: 0
    property string iconSource
    property bool active: false
    readonly property int buttonAnimationDuration: MobileShell.Motion.duration(MobileShell.Motion.Standard)
    readonly property real hiddenScale: MobileShell.Motion.hiddenScale
    readonly property real pressedScale: MobileShell.Motion.pressScaleOut

    signal triggered()

    enum ScreenCorner {
        BottomRight,
        BottomLeft,
        TopLeft,
        TopRight
    }

    // When the button is animating its disappearance, make sure it is transparent to inputs.
    onActiveChanged: {
        ShellUtil.setInputTransparent(root, !active)
        if (active) {
            root.visible = true;
            root.raise();
            hideButton.stop();
            return;
        }
        hideButton.restart();
    }

    LayerShell.Window.scope: "overlay"
    LayerShell.Window.margins.top: margins
    LayerShell.Window.margins.bottom: margins
    LayerShell.Window.margins.left: margins
    LayerShell.Window.margins.right: margins
    LayerShell.Window.layer: LayerShell.Window.LayerOverlay
    LayerShell.Window.exclusionZone: -1
    LayerShell.Window.keyboardInteractivity: LayerShell.Window.KeyboardInteractivityNone
    LayerShell.Window.anchors: {
        if (screenCorner === ActionButton.ScreenCorner.TopLeft) {
            return LayerShell.Window.AnchorTop | LayerShell.Window.AnchorLeft
        } else if (screenCorner === ActionButton.ScreenCorner.BottomRight) {
            return LayerShell.Window.AnchorBottom | LayerShell.Window.AnchorRight
        } else if (screenCorner === ActionButton.ScreenCorner.BottomLeft) {
            return LayerShell.Window.AnchorBottom | LayerShell.Window.AnchorLeft
        } else {
            return LayerShell.Window.AnchorTop | LayerShell.Window.AnchorRight
        }
    }

    Kirigami.Theme.colorSet: Kirigami.Theme.View
    Kirigami.Theme.inherit: false

    // Double the set button size to leave room for button scale animation.
    width: size * 2
    height: size * 2

    visible: active

    color: "transparent"

    // Hide the root window after the button disappearing animation finishes.
    Timer {
        id: hideButton
        interval: root.buttonAnimationDuration
        repeat: false
        onTriggered: if (!active) root.visible = false;
    }

    Component.onCompleted: {
        // Because the window surface area had to be made larger to accommodate the button scale animation,
        // set the input region to the size of the actual button.
        ShellUtil.setInputRegion(root, Qt.rect((root.width - size) / 2, (root.height - size) / 2, size, size));
        ShellUtil.setInputTransparent(root, !active);
    }

    Controls.Control {
        id: content
        anchors.centerIn: parent
        width: root.size
        height: root.size
        opacity: root.active ? 1 : 0

        property double scale: !root.active ? root.hiddenScale : (button.pressed ? root.pressedScale : 1)

        Behavior on scale {
            MobileShell.MotionNumberAnimation { type: MobileShell.Motion.StandardDecel }
        }

        Behavior on opacity {
            MobileShell.MotionNumberAnimation { type: MobileShell.Motion.StandardDecel }
        }

        transform: Scale {
            origin.x: root.size / 2
            origin.y: root.size / 2
            xScale: content.scale
            yScale: content.scale
        }

        MobileShell.PanelBackground {
            anchors.fill: parent
            panelType: MobileShell.PanelBackground.PanelType.Popup
            radius: root.size
        }

        Controls.AbstractButton {
            id: button
            anchors.fill: parent
            hoverEnabled: true

            MobileShell.HapticsEffect {
                id: haptics
            }

            contentItem: Item {
                MobileShell.MotionStateLayer {
                    anchors.fill: parent
                    radius: root.size
                    hovered: button.hovered
                    pressed: button.pressed
                }

                Kirigami.Icon {
                    anchors.centerIn: parent
                    width: Kirigami.Units.iconSizes.small
                    height: Kirigami.Units.iconSizes.small
                    transformOrigin: Item.Center
                    rotation: root.angle
                    source: root.iconSource
                    isMask: true
                    color: Kirigami.Theme.textColor
                }
            }

            onPressed: {
                haptics.buttonVibrate();
            }

            onReleased: {
                if (active) root.triggered();
            }
        }
    }
}
