R6 Robot Teach Pendant

// Copyright (C) 2026 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
pragma ComponentBehavior: Bound

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

Rectangle {
    id: root

    property var waypoints: []
    property string executionStatus: "idle" // idle, executing, completed, error
    property int currentWaypointIndex: -1
    property real progress: 0
    property bool loopEnabled: false

    signal playSequence
    signal stopSequence

    color: "transparent"

    ColumnLayout {
        anchors.fill: parent
        spacing: 0

        // Execution Controls
        Rectangle {
            Layout.fillWidth: true
            Layout.preferredHeight: 140
            color: Theme.card

            Rectangle {
                anchors.bottom: parent.bottom
                width: parent.width
                height: 1
                color: Theme.border
            }

            ColumnLayout {
                anchors.fill: parent
                anchors.margins: Theme.spacingMedium
                spacing: 12

                RowLayout {
                    Layout.fillWidth: true
                    spacing: 12

                    Button {
                        id: playButton
                        Layout.fillWidth: true
                        Layout.preferredHeight: 56
                        enabled: root.waypoints.length >= 2
                                 && root.executionStatus !== "executing"

                        background: Rectangle {
                            color: parent.enabled ? (playButton.pressed ? "#2DA35C" : Theme.success) : Theme.muted
                            radius: Theme.radius
                        }

                        contentItem: RowLayout {
                            spacing: 8

                            Label {
                                text: "▶"
                                color: "white"
                                font.pixelSize: 20
                            }

                            Label {
                                text: "Play"
                                color: "white"
                                font.pixelSize: 16
                                font.bold: true
                                Layout.fillWidth: true
                            }
                        }

                        onClicked: root.playSequence()
                    }

                    Button {
                        id: stopButton
                        Layout.fillWidth: true
                        Layout.preferredHeight: 56
                        enabled: root.executionStatus === "executing"

                        background: Rectangle {
                            color: parent.enabled ? (stopButton.pressed ? "#C74545" : Theme.destructive) : Theme.muted
                            radius: Theme.radius
                        }

                        contentItem: RowLayout {
                            spacing: 8

                            Label {
                                text: "■"
                                color: "white"
                                font.pixelSize: 18
                            }

                            Label {
                                text: "Stop"
                                color: "white"
                                font.pixelSize: 16
                                font.bold: true
                                Layout.fillWidth: true
                            }
                        }

                        onClicked: root.stopSequence()
                    }
                }

                CheckBox {
                    id: loopCheckbox
                    text: "Loop Sequence"
                    checked: root.loopEnabled
                    onToggled: root.loopEnabled = checked

                    contentItem: Label {
                        text: loopCheckbox.text
                        color: Theme.foreground
                        font.pixelSize: 13
                        leftPadding: loopCheckbox.indicator.width + 8
                        verticalAlignment: Text.AlignVCenter
                    }

                    indicator: Rectangle {
                        implicitWidth: 20
                        implicitHeight: 20
                        x: loopCheckbox.leftPadding
                        y: parent.height / 2 - height / 2
                        radius: 4
                        border.width: 2
                        border.color: loopCheckbox.checked ? Theme.primary : Theme.border
                        color: loopCheckbox.checked ? Theme.primary : "transparent"

                        Label {
                            visible: loopCheckbox.checked
                            anchors.centerIn: parent
                            text: "✓"
                            color: Theme.primaryForeground
                            font.pixelSize: 14
                        }
                    }
                }
            }
        }

        // Status Area
        Rectangle {
            Layout.fillWidth: true
            Layout.preferredHeight: 100
            color: Theme.card

            Rectangle {
                anchors.bottom: parent.bottom
                width: parent.width
                height: 1
                color: Theme.border
            }

            ColumnLayout {
                anchors.fill: parent
                anchors.margins: Theme.spacingMedium
                spacing: 8

                RowLayout {
                    Layout.fillWidth: true

                    Label {
                        text: "STATUS"
                        color: Theme.mutedForeground
                        font.pixelSize: 11
                        font.bold: true
                        font.letterSpacing: 1
                    }

                    Item {
                        Layout.fillWidth: true
                    }

                    Rectangle {
                        Layout.preferredWidth: 10
                        Layout.preferredHeight: 10
                        radius: 5
                        color: {
                            if (root.executionStatus === "executing")
                            return Theme.primary
                            if (root.executionStatus === "completed")
                            return Theme.success
                            if (root.executionStatus === "error")
                            return Theme.destructive
                            return Theme.mutedForeground
                        }
                    }

                    Label {
                        text: root.executionStatus.charAt(0).toUpperCase(
                                  ) + root.executionStatus.slice(1)
                        color: Theme.foreground
                        font.pixelSize: 14
                        font.bold: true
                    }
                }

                ProgressBar {
                    Layout.fillWidth: true
                    value: root.progress
                    from: 0
                    to: 100

                    background: Rectangle {
                        implicitHeight: 8
                        color: Theme.muted
                        radius: 4
                    }

                    contentItem: Item {
                        implicitHeight: 8

                        Rectangle {
                            width: parent.width * (root.progress / 100)
                            height: parent.height
                            radius: 4
                            color: Theme.primary

                            Behavior on width {
                                NumberAnimation {
                                    duration: 200
                                }
                            }
                        }
                    }
                }

                Label {
                    text: {
                        if (root.executionStatus === "executing") {
                            return "Executing waypoint " + (root.currentWaypointIndex + 1)
                            + " of " + root.waypoints.length
                        }
                        if (root.executionStatus === "completed") {
                            return "Sequence completed (" + root.waypoints.length + " waypoints)"
                        }
                        if (root.executionStatus === "error") {
                            return "Error: Trajectory aborted"
                        }
                        if (root.waypoints.length >= 2) {
                            return root.waypoints.length + " waypoints ready"
                        }
                        return "Need at least 2 waypoints to execute"
                    }
                    color: Theme.mutedForeground
                    font.pixelSize: 12
                }
            }
        }

        // Timeline Visualization
        Rectangle {
            Layout.fillWidth: true
            Layout.preferredHeight: 120
            color: Theme.card

            Rectangle {
                anchors.bottom: parent.bottom
                width: parent.width
                height: 1
                color: Theme.border
            }

            ColumnLayout {
                anchors.fill: parent
                anchors.margins: Theme.spacingMedium
                spacing: 12

                Label {
                    text: "TIMELINE"
                    color: Theme.mutedForeground
                    font.pixelSize: 11
                    font.bold: true
                    font.letterSpacing: 1
                }

                ScrollView {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    clip: true

                    ScrollBar.vertical.policy: ScrollBar.AlwaysOff
                    ScrollBar.horizontal.policy: ScrollBar.AsNeeded

                    Row {
                        spacing: 0

                        Repeater {
                            model: root.waypoints

                            Row {
                                id: timeLineDot
                                spacing: 0
                                required property int index
                                required property var modelData

                                Item {
                                    width: 40
                                    height: 40

                                    Rectangle {
                                        width: 32
                                        height: 32
                                        radius: 16

                                        anchors.centerIn: parent
                                        color: {
                                            if (timeLineDot.index === root.currentWaypointIndex
                                                && root.executionStatus === "executing") {
                                                return Theme.primary
                                            }
                                            if (timeLineDot.index < root.currentWaypointIndex
                                                && root.executionStatus === "executing") {
                                                return Theme.success
                                            }
                                            return Theme.mutedForeground
                                        }

                                        Label {
                                            anchors.centerIn: parent
                                            text: (timeLineDot.index + 1).toString()
                                            color: "white"
                                            font.pixelSize: 12
                                            font.bold: true
                                        }

                                        // Glow effect for active waypoint
                                        Rectangle {
                                            id: glowEffect
                                            visible: timeLineDot.index === root.currentWaypointIndex
                                                     && root.executionStatus === "executing"
                                            anchors.centerIn: parent
                                            width: parent.width + 8
                                            height: parent.height + 8
                                            radius: (parent.width + 8) / 2
                                            color: "transparent"
                                            border.width: 2
                                            border.color: Theme.primary
                                            opacity: 0.5

                                            SequentialAnimation on opacity {
                                                running: glowEffect.visible
                                                loops: Animation.Infinite
                                                NumberAnimation {
                                                    from: 0.5
                                                    to: 0
                                                    duration: 1000
                                                }
                                                NumberAnimation {
                                                    from: 0
                                                    to: 0.5
                                                    duration: 1000
                                                }
                                            }
                                        }
                                    }
                                }

                                // Connection line (not for last waypoint)
                                Rectangle {
                                    anchors.verticalCenter: parent.verticalCenter
                                    visible: index < root.waypoints.length - 1
                                    width: 40
                                    height: 2

                                    color: {
                                        if (index < root.currentWaypointIndex
                                            && root.executionStatus === "executing") {
                                            return Theme.success
                                        }
                                        return Theme.muted
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        // Validation message
        Rectangle {
            visible: root.waypoints.length < 2
            Layout.fillWidth: true
            Layout.fillHeight: true
            color: "transparent"

            ColumnLayout {
                anchors.centerIn: parent
                spacing: 16

                Label {
                    text: "▶"
                    font.pixelSize: 48
                    color: Theme.mutedForeground
                    opacity: 0.3
                    Layout.alignment: Qt.AlignHCenter
                }

                Label {
                    text: "Not enough waypoints"
                    color: Theme.mutedForeground
                    font.pixelSize: 16
                    font.bold: true
                    Layout.alignment: Qt.AlignHCenter
                }

                Label {
                    text: "Add at least 2 waypoints to execute a sequence"
                    color: Theme.mutedForeground
                    font.pixelSize: 13
                    Layout.alignment: Qt.AlignHCenter
                }
            }
        }

        Item {
            visible: root.waypoints.length >= 2
            Layout.fillHeight: true
        }
    }
}