// A miniature of the real desktop that redraws as you change Appearance.
//
// The point is that "outer gaps 24" and "radius 9" mean nothing as numbers. This
// shows two tiled windows at the settings currently in effect: the focused one
// wearing the prism border and its glow, the unfocused one carrying the
// inactive-opacity setting, both inside real gaps at a real corner radius.
//
// Geometry is scaled by the ratio between this preview's width and the actual
// monitor's, so proportions are honest rather than decorative -- a 10px gap on
// a 4500px display genuinely is almost invisible, and the preview says so.
//
// Everything here is driven by bindings on DesktopPreferences, so the preview
// shows what is actually stored and applied. It has no state of its own and
// nothing animates while idle.

import QtQuick
import QtQuick.Effects
import qs.config
import qs.services

Rectangle {
    id: root

    implicitHeight: 232
    radius: Theme.cardRadius
    clip: true
    border.width: 1
    border.color: Theme.alpha(Theme.fg, 0.09)

    // Falls back to a sane width if the monitor has not been read yet, so the
    // preview is never wrong by a factor of ten on first paint.
    readonly property real monitorWidth: SystemSettings.monitorWidth > 0 ? SystemSettings.monitorWidth : 3000
    readonly property real scale: width > 0 ? width / root.monitorWidth : 0.25

    readonly property int gapsIn: DesktopPreferences.get("gapsIn")
    readonly property int gapsOut: DesktopPreferences.get("gapsOut")
    readonly property int borderSize: DesktopPreferences.get("borderSize")
    readonly property int rounding: DesktopPreferences.get("windowRounding")
    readonly property real inactiveOpacity: DesktopPreferences.get("inactiveOpacity")
    readonly property bool shadowOn: DesktopPreferences.get("shadowEnabled")
    readonly property int shadowRange: DesktopPreferences.get("shadowRange")
    readonly property bool glowOn: DesktopPreferences.get("glowEnabled")
    readonly property int glowRange: DesktopPreferences.get("glowRange")

    // Scaled geometry, floored so a small-but-nonzero setting stays visible
    // rather than rounding away to nothing.
    function px(value: real): real {
        return value <= 0 ? 0 : Math.max(1, value * root.scale);
    }

    // Stands in for the wallpaper. Static: an animated gradient here would
    // repaint forever behind a settings page.
    // Follows the colour scheme. A preview that stays dark while the shell
    // around it is light does not read as "your desktop" -- it reads as a
    // screenshot of someone else's.
    gradient: Gradient {
        orientation: Gradient.Vertical
        GradientStop { position: 0.0; color: Theme.dark ? "#2b3050" : "#b9c0dd" }
        GradientStop { position: 1.0; color: Theme.dark ? "#241f33" : "#cbbcd4" }
    }

    // The bar, so the preview reads as this desktop and not a generic one.
    Rectangle {
        id: miniBar
        anchors.top: parent.top
        anchors.left: parent.left
        anchors.right: parent.right
        height: 20
        color: Theme.alpha(Theme.bgDark, 0.4)
        border.width: 0

        Row {
            anchors.left: parent.left
            anchors.leftMargin: 9
            anchors.verticalCenter: parent.verticalCenter
            spacing: 4

            Repeater {
                model: 3
                Rectangle {
                    required property int index
                    width: index === 0 ? 12 : 5
                    height: 5
                    radius: 2.5
                    border.width: 0
                    color: index === 0 ? Theme.accent : Theme.alpha(Theme.fg, 0.3)
                    anchors.verticalCenter: parent.verticalCenter
                }
            }
        }

        Text {
            anchors.centerIn: parent
            text: "Panama"
            color: Theme.alpha(Theme.fg, 0.45)
            font.family: Theme.fontFamily
            font.pixelSize: 9
        }
    }

    Row {
        id: tiles
        anchors.top: miniBar.bottom
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        anchors.margins: root.px(root.gapsOut)
        spacing: root.px(root.gapsIn) * 2

        MiniWindow {
            width: (tiles.width - tiles.spacing) / 2
            height: tiles.height
            focused: true
        }

        MiniWindow {
            width: (tiles.width - tiles.spacing) / 2
            height: tiles.height
            focused: false
        }
    }

    component MiniWindow: Item {
        id: win

        required property bool focused

        // The gradient border is drawn as a filled rounded rect with the window
        // body inset on top of it: QML's Rectangle border takes a colour, not a
        // gradient, and the prism border is the whole signature here.
        Rectangle {
            id: frame
            anchors.fill: parent
            radius: root.px(root.rounding)
            border.width: 0
            visible: win.focused && root.borderSize > 0

            gradient: Gradient {
                orientation: Gradient.Horizontal
                GradientStop { position: 0.0; color: Theme.accent }
                GradientStop { position: 1.0; color: Theme.accentSecondary }
            }
        }

        Rectangle {
            id: body
            anchors.fill: parent
            anchors.margins: win.focused ? root.px(root.borderSize) : 0
            radius: Math.max(0, root.px(root.rounding) - (win.focused ? root.px(root.borderSize) : 0))
            color: Theme.alpha(Theme.bgDark, 0.92)
            opacity: win.focused ? 1.0 : root.inactiveOpacity
            border.width: win.focused ? 0 : 1
            border.color: Theme.alpha(Theme.gutter, 0.6)
            clip: true

            Rectangle {
                anchors.top: parent.top
                anchors.left: parent.left
                anchors.right: parent.right
                height: 13
                color: Theme.alpha(Theme.fg, 0.05)
                border.width: 0
            }

            Column {
                anchors.left: parent.left
                anchors.right: parent.right
                anchors.top: parent.top
                anchors.topMargin: 22
                anchors.margins: 10
                spacing: 5

                Repeater {
                    model: [1.0, 0.74, 0.52]
                    Rectangle {
                        required property real modelData
                        width: parent.width * modelData
                        height: 4
                        radius: 2
                        border.width: 0
                        color: Theme.alpha(Theme.fg, win.focused ? 0.2 : 0.13)
                    }
                }
            }

            Text {
                anchors.left: parent.left
                anchors.bottom: parent.bottom
                anchors.margins: 8
                text: win.focused ? "focused" : "unfocused"
                color: Theme.fgMuted
                font.family: Theme.fontFamily
                font.pixelSize: 9
            }
        }

        // Shadow and glow both come from MultiEffect. Only the focused window
        // gets the glow, matching looks.lua where glow.color_inactive is fully
        // transparent.
        MultiEffect {
            anchors.fill: body
            source: body
            visible: root.shadowOn || (win.focused && root.glowOn)
            z: -1

            shadowEnabled: true
            shadowColor: win.focused && root.glowOn
                ? Theme.alpha(Theme.accent, 0.5)
                : Theme.alpha(Theme.dark ? "#15161e" : "#6172b0", Theme.dark ? 0.85 : 0.45)
            shadowBlur: win.focused && root.glowOn
                ? Math.min(1.0, root.px(root.glowRange) / 12)
                : Math.min(1.0, root.px(root.shadowRange) / 24)
            shadowVerticalOffset: win.focused && root.glowOn ? 0 : root.px(4)
            shadowHorizontalOffset: 0
        }
    }
}
