import QtQuick 2.0
import QtQuick.Controls 2.9
import QtQuick.Layouts 1.0
import de.itsblue.LedDisplayController 1.0
import de.itsblue.bluetoothleuart 1.0
import QtQuick.Controls.Material 2.0
import QtGraphicalEffects 1.0

Page {
    id: root

    property bool actionButtonVisible: false
    property bool backButtonVisible: false
    property string statusText
    property bool working

    title: qsTr("Available displays")

    signal opened()

    onOpened: {
    }

    ColumnLayout {
        id: mainLayout
        anchors {
            fill: parent
            margins: Math.min(parent.height, parent.width) * 0.05
        }

        Chip {
            id: topChip

            Layout.fillWidth: true
            Layout.preferredHeight: 35
            Layout.alignment: Layout.Center

            verticalPadding: height * 0.25
            horizontalPadding: width * 0.05

            color: "#ffffff"
            text: root.statusText

            onClicked: {
                if(parseInt(root.state) === LedDisplayBackend.LocationPermissionDenied && !backend.bleClient.isLocationPermissionGranted())
                    backend.bleClient.requestLocationPermission()
                else
                    backend.bleClient.startScanningForDevices()
            }

            BusyIndicator {
                    id: busyIndicator

                    anchors {
                        right: parent.right
                    }

                    height: parent.height
                    width: height

                    scale: 0.8

                    opacity: root.working ? 1:0
            }

            Item {
                anchors.fill: parent

                ProgressBar {
                    id: loadingProgressBar
                    anchors {
                        left: parent.left
                        right: parent.right
                        bottom: parent.bottom
                    }

                    value: backend.loadingProgress
                    opacity: 0

                    Behavior on value {
                        NumberAnimation {}
                    }

                    Behavior on opacity {
                        NumberAnimation {}
                    }
                }

                layer.enabled: true
                layer.effect: OpacityMask {
                    maskSource: Item {
                        width: topChip.width
                        height: topChip.height
                        Rectangle {
                            anchors.fill: parent
                            radius: topChip.radius
                        }
                    }
                }
            }
        }

        Item {
            Layout.fillWidth: true
            Layout.preferredHeight: mainLayout.height * 0.025
        }

        ListView {
            id: availableDisplaysListView

            Layout.preferredWidth: parent.width
            Layout.fillHeight: true
            Layout.alignment: Layout.Center

            clip: true
            boundsBehavior: Flickable.OvershootBounds

            model: backend.bleClient.availableDevicesModel

            add: Transition {
                NumberAnimation { property: "opacity"; from: 0; to: 1; duration: 200 }
                NumberAnimation { property: "scale"; from: 0.9; to: 1; duration: 200 }
            }

            remove: Transition {
                NumberAnimation { property: "opacity"; from: 1; to: 0; duration: 200 }
                NumberAnimation { property: "scale"; from: 1; to: 0.9; duration: 200 }
            }

            spacing: 5

            delegate: ItemDelegate {
                width: parent.width

                text: name

                onClicked: backend.bleClient.connectToDevice(device)

                Rectangle {
                    anchors {
                        top: parent.top
                        left: parent.left
                        right: parent.right
                        topMargin: - availableDisplaysListView.spacing * 0.5
                    }

                    color: "lightgrey"
                    height: 1
                    visible: index !== 0
                }
            }

            Item {
                id: noDisplaysItem
                anchors.centerIn: parent

                width: Math.min(parent.height, parent.width)
                height: Math.min(parent.height, parent.width)

                opacity: availableDisplaysListView.model.rowCount === 0 ? 1:0

                Behavior on opacity {
                    NumberAnimation {}
                }

                Rectangle {
                    id: noDisplaysRect

                    anchors {
                        top: parent.top
                        topMargin: parent.height * 0.2
                        horizontalCenter: parent.horizontalCenter
                    }

                    width: parent.width * 0.7
                    height: width * 0.3

                    color: "transparent"

                    border.width: height * 0.15
                    border.color: "lightgrey"

                    Text {
                        anchors.centerIn: parent
                        anchors.verticalCenterOffset: text === "..." ? -height * 0.25:0
                        color: "lightgrey"
                        font.pixelSize: parent.height * 0.6
                        font.bold: true
                        text: parseInt(root.state) === LedDisplayBackend.Scanning ? "...":"?"
                    }
                }

                Text {
                    id: noDisplaysText
                    anchors {
                        top: noDisplaysRect.bottom
                        topMargin: noDisplaysRect.height * 0.15
                        horizontalCenter: parent.horizontalCenter
                    }

                    font.bold: true
                    font.pixelSize: noDisplaysRect.height * 0.3

                    color: Qt.darker("lightgrey", 1.1)
                    text: parseInt(root.state) === LedDisplayBackend.Scanning ? qsTr("Still scanning"):qsTr("No displays found")
                }
            }


            Item {
                id: bluetoothOffItem
                anchors.centerIn: parent

                width: Math.min(parent.height, parent.width)
                height: Math.min(parent.height, parent.width)

                opacity: 0

                Behavior on opacity {
                    NumberAnimation {}
                }


                    Text {
                        id: bluetoothOffIcon
                        anchors {
                            top: parent.top
                            topMargin: parent.height * 0.1
                            horizontalCenter: parent.horizontalCenter
                        }
                        anchors.verticalCenterOffset: text === "..." ? -height * 0.25:0
                        color: "lightgrey"
                        font.pixelSize: parent.height * 0.4
                        font.family: fontAwesomeBrands.name
                        text: "\uf294"
                    }


                Text {
                    id: bluetoothOffText
                    anchors {
                        top: bluetoothOffIcon.bottom
                        topMargin: bluetoothOffIcon.height * 0.15
                        horizontalCenter: parent.horizontalCenter
                    }

                    font.bold: true
                    font.pixelSize: bluetoothOffIcon.height * 0.15

                    color: Qt.darker("lightgrey", 1.1)
                    text: qsTr("Bluetooth is turned off")
                }
            }

            Item {
                id: noPermissionItem
                anchors.centerIn: parent

                width: Math.min(parent.height, parent.width)
                height: Math.min(parent.height, parent.width)

                opacity: 0

                Behavior on opacity {
                    NumberAnimation {}
                }


                    Text {
                        id: noPermissionIcon
                        anchors {
                            top: parent.top
                            topMargin: parent.height * 0
                            horizontalCenter: parent.horizontalCenter
                        }
                        anchors.verticalCenterOffset: text === "..." ? -height * 0.25:0
                        color: "lightgrey"
                        font.pixelSize: parent.height * 0.4
                        font.family: fontAwesome.name
                        text: "\uf3ed"
                    }
                    Text {
                        id: noPermissionText
                        anchors {
                            top: noPermissionIcon.bottom
                            topMargin: noPermissionIcon.height * 0.15
                            horizontalCenter: parent.horizontalCenter
                        }

                        width: parent.width * 0.9

                        font.bold: true
                        font.pixelSize: noPermissionIcon.height * 0.15

                        horizontalAlignment: Text.AlignHCenter

                        wrapMode: Text.Wrap

                        color: Qt.darker("lightgrey", 1.1)
                        text: qsTr("Error:\nLocation permission denied!")
                    }

                Text {
                    id: noPermissionDetailText
                    anchors {
                        top: noPermissionText.bottom
                        topMargin: noPermissionText.height * 0.15
                        horizontalCenter: parent.horizontalCenter
                    }

                    width: parent.width * 0.9

                    font.bold: true
                    font.pixelSize: noPermissionText.font.pixelSize * 0.7

                    horizontalAlignment: Text.AlignHCenter

                    wrapMode: Text.Wrap

                    color: Qt.darker("lightgrey", 1.1)
                    text: qsTr("This app requires location permission in order for Bluetooth to work, it will not actually access your location.")
                }
            }

        }
    }

    Dialog {
        id: authenticationDialog

        property bool shouldBeOpened: false

        parent: Overlay.overlay
        x: (parent.width - width) / 2
        y: (parent.height - height) / 2

        width: parent.width * 0.9

        modal: true
        closePolicy: Popup.NoAutoClose
        standardButtons: Dialog.Ok | Dialog.Cancel

        title: qsTr("Input code")

        onShouldBeOpenedChanged:  {
            if(shouldBeOpened)
                open()
            else
                close()
        }

        onAccepted: {
            backend.authenticate(secretTextInput.text)
        }

        onRejected: {
            backend.bleClient.disconnectFromDevice()
        }

        contentItem: TextField {
            id: secretTextInput
            placeholderText: qsTr("code")
            Keys.onReturnPressed: authenticationDialog.accept()
        }
    }

    states: [
        State {
            name: LedDisplayBackend.Idle

            PropertyChanges {
                target: root
                statusText: qsTr("Tap here to scan")
                working: false
            }

            PropertyChanges {
                target: noPermissionItem
                opacity: 0
            }
        },
        State {
            name: LedDisplayBackend.BluetoothOff
            PropertyChanges {
                target: bluetoothOffItem
                opacity: 1
            }
            PropertyChanges {
                target: root
                statusText: qsTr("Bluetooth is turned off")
                working: false
            }
            PropertyChanges {
                target: noDisplaysItem
                opacity: 0
            }
        },
        State {
            name: LedDisplayBackend.LocationPermissionDenied

            PropertyChanges {
                target: noPermissionItem
                opacity: 1
            }
            PropertyChanges {
                target: root
                statusText: qsTr("Tap here to continue")
                working: false
            }
            PropertyChanges {
                target: noDisplaysItem
                opacity: 0
            }
        },
        State {
            name: LedDisplayBackend.Scanning

            PropertyChanges {
                target: root
                statusText: qsTr("Scanning...")
                working: true
            }
            PropertyChanges {
                target: bluetoothOffItem
                opacity: 0
            }
            PropertyChanges {
                target: noPermissionItem
                opacity: 0
            }
        },
        State {
            name: LedDisplayBackend.ReadyToConnect

            PropertyChanges {
                target: root
                statusText: availableDisplaysListView.model.rowCount > 0 ? qsTr("Please select a device or tap to scan again"):qsTr("No displays found. Tap to scan again")
                working: false
            }
        },

        State {
            name: LedDisplayBackend.AuthenticationRequired

            PropertyChanges {
                target: authenticationDialog
                shouldBeOpened: true
            }

            PropertyChanges {
                target: availableDisplaysListView
                enabled: false
            }

            PropertyChanges {
                target: root
                statusText: qsTr("trying to authenticate...")
                working: true
            }
        },
        State {
            name: LedDisplayBackend.Authenticating

            PropertyChanges {
                target: availableDisplaysListView
                enabled: false
            }

            PropertyChanges {
                target: root
                statusText: qsTr("trying to authenticate...")
                working: true
            }
        },

        State {
            name: LedDisplayBackend.Connecting

            PropertyChanges {
                target: availableDisplaysListView
                enabled: false
            }

            PropertyChanges {
                target: root
                statusText: qsTr("trying to connect...")
                working: true
            }
        },
        State {
            name: LedDisplayBackend.Initing

            PropertyChanges {
                target: availableDisplaysListView
                enabled: false
            }

            PropertyChanges {
                target: root
                statusText: qsTr("loading data...")
                working: true
            }

            PropertyChanges {
                target: loadingProgressBar
                opacity: 1
            }
        }
    ]
}
