// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT

struct Piece  {
    // col/row position of the tile in the puzzle
    pos-x: int,
    pos-y: int,
    // offset in pixel from the base position for the kicking animation
    offset-x: length,
    offset-y: length,
}

struct Theme  {
    name: string,
    window-background-color: brush,
    game-background-color: brush,
    game-use-background-image: bool,
    game-border: length,
    game-radius: length,
    game-text-color: color,
    game-highlight-color: color,
    piece-border: length,
    piece-background-1: brush,
    piece-background-2: brush,
    piece-border-color-1: brush,
    piece-border-color-2: brush,
    piece-text-color-1: color,
    piece-text-color-2: color,
    piece-text-weight-incorrect-pos: int,
    piece-text-weight-correct-pos: int,
    piece-text-font-family: string,
    piece-radius: length,
    /// Ratio of the piece size
    piece-spacing: float,
}

component Checkbox inherits Rectangle {
    in property <color> checked-color;
    in property <color> unchecked-color;
    in-out property <bool> checked;

    callback toggled(bool);

    states [
         checked when root.checked : {
             clip.width: root.width;
             checkbox-rect.border-color: root.checked-color;
             checkbox-rect.border-width: root.width;
             in {
                 animate clip.width { duration: 200ms; easing: ease-in; }
                 animate checkbox-rect.border-width { duration: 100ms; easing: ease-out; }
             }
             out {
                 animate clip.width { duration: 100ms; easing: ease; }
                 animate checkbox-rect.border-width { duration: 200ms; easing: ease-in-out; }
                 animate checkbox-rect.border-color { duration: 200ms; easing: cubic-bezier(1,1,1,0); }
             }
         }
     ]

    hover-rect := Rectangle {
        background: #f5f5f5;
        x: - parent.width / 4;
        y: - parent.height / 4;
        width: ta.has-hover ? root.width * 1.5 : 0px;
        height: self.width;
        border-radius: self.width;
    }

    checkbox-rect := Rectangle {
        border-width: self.height * 10%;
        border-color: root.unchecked-color;
        border-radius: 2px;

        clip := Rectangle {
            x:0;
            width: 0px;
            clip: true;

            Text {
                x:0;y:0;
                width: root.width;
                height: root.height;
                text: "✓";
                font-size: self.height * 80%;
                color: white;
                vertical-alignment: center;
                horizontal-alignment: center;

                animate color { duration: 200ms; }
            }
        }

        ta := TouchArea {
            clicked => {
                root.checked = !root.checked;
                root.toggled(root.checked);
            }
        }

    }
}

export component MainWindow inherits Window {
    in property <[Piece]> pieces: [
        { pos-x: 0, pos-y: 0 },
        { pos-x: 0, pos-y: 1 },
        { pos-x: 0, pos-y: 2 },
        { pos-x: 0, pos-y: 3 },
        { pos-x: 1, pos-y: 0 },
        { pos-x: 1, pos-y: 1 },
        { pos-x: 1, pos-y: 2 },
        { pos-x: 1, pos-y: 3 },
        { pos-x: 2, pos-y: 0 },
        { pos-x: 2, pos-y: 1 },
        { pos-x: 2, pos-y: 2 },
        { pos-x: 2, pos-y: 3 },
        { pos-x: 3, pos-y: 0 },
        { pos-x: 3, pos-y: 1 },
        { pos-x: 3, pos-y: 2 },
    ];
    out property <int> current-theme-index;
    in-out property <bool> auto-play;
    in-out property <int> moves;
    in-out property <int> tiles-left;

    callback piece-clicked(int);
    callback reset();
    callback enable-auto-mode(bool);

    private property <[Theme]> themes: [
        {
            name: "SIMPLE",
            window-background-color: #ffffff,
            game-background-color: #ffffff,
            game-use-background-image: false,
            game-border: 1px,
            game-radius: 2px,
            game-text-color: #858585,
            game-highlight-color: #1d6aaa,
            piece-border: 1px,
            piece-background-1: #0d579b,
            piece-background-2: #0d579b,
            piece-border-color-1: #0a457b,
            piece-border-color-2: #0a457b,
            piece-text-color-1: #ffffff,
            piece-text-color-2: #ffffff,
            piece-text-weight-incorrect-pos: 400,
            piece-text-weight-correct-pos: 700,
            piece-radius: 5px,
            /// Ratio of the piece size
            piece-spacing: 10%,
        },
    ];
    private property <Theme> current-theme: root.themes[root.current-theme-index];
    private property <length> pieces-size: min(root.width, root.height) / 6;
    private property <length> pieces-spacing: root.current-theme.game-use-background-image && root.tiles-left == 0 ?
        2px : (root.pieces-size * root.current-theme.piece-spacing);

    title: "Slide Puzzle - Slint Demo";

    animate pieces-spacing { duration: 500ms; easing: ease-out; }

    Rectangle {
        background: root.current-theme.window-background-color;
        animate background { duration: 500ms; easing: ease-out; }
    }

    Rectangle {
        background: root.current-theme.game-background-color;
        border-color: root.current-theme.game-text-color;
        border-width: root.current-theme.game-border;
        border-radius: root.current-theme.game-radius;
        width: root.pieces-size * 4.6;
        height: root.pieces-size * 5.4;
        x: (parent.width - self.width)/2;
        y: (parent.height - self.height)/2;
        animate background, border-color, border-width, border-radius { duration: 500ms; easing: ease-out; }

        Rectangle {
            y:0;
            width: parent.width * 90%;
            height: root.pieces-size/2;
            x: (parent.width - self.width) / 2;

            
        }

        for p[i] in root.pieces : Rectangle {
            property <float> px: p.pos-x;
            property <float> py: p.pos-y;
            property <bool> is-correct: i == p.pos-x * 4 + p.pos-y;

            x: self.py * (root.pieces-size + root.pieces-spacing) + p.offset-x
                + (parent.width - (4*root.pieces-size + 3*root.pieces-spacing))/2;
            y: self.px * (root.pieces-size + root.pieces-spacing) + p.offset-y
                + (parent.height - (4*root.pieces-size + 3*root.pieces-spacing))/2;
            width: root.pieces-size;
            height: root.pieces-size;
            drop-shadow-offset-x: 1px;
            drop-shadow-offset-y: 1px;
            drop-shadow-blur: 3px;
            drop-shadow-color: #00000040;
            border-radius: root.current-theme.piece-radius;
            clip: true;

            states [
                pressed when touch.pressed : {
                    shadow.color: #0002;
                    circle.width: shadow.width * 2 * 1.4142;
                in  {
                    animate shadow.color { duration: 50ms; }
                    animate circle.width { duration: 2s; easing: ease-out; }
                }
                out  {
                    animate shadow.color { duration: 50ms; }
                }
                }
                hover when touch.has-hover: {
                    shadow.color: #0000000d;
                }
            ]

            if (!root.current-theme.game-use-background-image) : Rectangle {
                background: i >= 8 ? root.current-theme.piece-background-2 : root.current-theme.piece-background-1;
                border-color: i >= 8 ? root.current-theme.piece-border-color-2 : root.current-theme.piece-border-color-1;
                border-width: root.current-theme.piece-border;
                border-radius: root.current-theme.piece-radius;

                animate border-width, border-radius { duration: 500ms; easing: ease-out; }
            }

            if (!root.current-theme.game-use-background-image || root.tiles-left > 0) : Text {
                text: i+1;
                color: ((!root.current-theme.game-use-background-image && i >= 8) || (root.current-theme.game-use-background-image && is-correct)) ? root.current-theme.piece-text-color-2 : root.current-theme.piece-text-color-1;
                font-size: root.pieces-size / 3;
                font-weight: is-correct ? root.current-theme.piece-text-weight-correct-pos : root.current-theme.piece-text-weight-incorrect-pos;
                font-family: root.current-theme.piece-text-font-family;
                vertical-alignment: center;
                horizontal-alignment: center;
                width: 100%;
                height: 100%;
            }

            touch := TouchArea {
                clicked => { root.piece-clicked(i); }
            }

            shadow := Rectangle {
                circle := Rectangle {
                    height: self.width;
                    border-radius: self.width/2;
                    background: #0002;
                    x: touch.pressed-x - self.width/2;
                    y: touch.pressed-y - self.width/2;
                }
            }
        }

        Rectangle {
            width: parent.width;
            height: 1px;
            background: root.current-theme.game-text-color;
            y: parent.height - root.pieces-size / 2;
        }

        HorizontalLayout {
            height: root.pieces-size / 2;
            y: parent.height - root.pieces-size / 2;
            width: parent.width;
            padding: self.height * 25%;

            Text {
                text: " ↻ ";
                font-size: parent.height * 40%;
                color: root.current-theme.game-highlight-color;
                vertical-alignment: center;
                TouchArea {
                    clicked => { root.reset(); }
                }
            }

            Checkbox {
                toggled(checked) => { root.enable-auto-mode(self.checked) }

                width: parent.height - 2 * parent.padding;
                checked <=> root.auto-play;
                checked-color: root.current-theme.game-highlight-color;
                unchecked-color: root.current-theme.game-text-color;
            }

            Rectangle {} // stretch

            Text {
                text: root.moves;
                color: root.current-theme.game-highlight-color;
                vertical-alignment: center;
            }

            Text {
                text: "Moves ";
                color: root.current-theme.game-text-color;
                vertical-alignment: center;
            }

            Text {
                text: root.tiles-left;
                color: root.current-theme.game-highlight-color;
                vertical-alignment: center;
            }

            Text {
                text: "Tiles left";
                color: root.current-theme.game-text-color;
                vertical-alignment: center;
            }
        }
    }
}
