/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

import QtQuick 2.5
import Nymea 1.0
import QtQuick.Controls 2.2
import QtQuick.Controls.Material 2.2
import QtQuick.Layouts 1.3

Item {
    id: root

    property Thing thing: null

    readonly property bool isExtended: thing && thing.thingClass.interfaces.indexOf("extendednavigationpad") >= 0

    readonly property ActionType navigateActionType: thing ? thing.thingClass.actionTypes.findByName("navigate") : null

    Pane {
        id: pane
        Material.elevation: 2
        width: Math.min(root.width, root.height)
        height: Math.min(root.width, root.height)
        anchors.centerIn: parent

        padding: 0

        contentItem: Item {

            Pane {
                anchors.centerIn: parent
                Material.elevation: 2
                rotation: 45
                width: Math.sqrt(Math.pow(parent.width / 2, 2) + Math.pow(parent.height / 2, 2))
                height: width
            }

            KeypadButton {
                id: backButton
                anchors { left: parent.left; top: parent.top; margins: parent.width * .1 }
                height: Style.iconSize
                width: Style.iconSize
                imageSource: "../images/back.svg"
                Item { id: backButtonArea; anchors.centerIn: parent; width: pane.width / 4; height: width; rotation: 45; }
            }
            KeypadButton {
                id: menuButton
                anchors { right: parent.right; top: parent.top; margins: parent.width * .1 }
                height: Style.iconSize
                width: Style.iconSize
                visible: root.thing.thingClass.interfaces.indexOf("extendednavigationpad") >= 0
                imageSource: "../images/navigation-menu.svg"
                Item { id: menuButtonArea; anchors.centerIn: parent; width: pane.width / 4; height: width; rotation: 45 }
            }
            KeypadButton {
                id: homeButton
                anchors { left: parent.left; bottom: parent.bottom; margins: parent.width * .1 }
                height: Style.iconSize
                width: Style.iconSize
                imageSource: "../images/home.svg"
                visible: root.thing.thingClass.interfaces.indexOf("extendednavigationpad") >= 0
                Item { id: homeButtonArea; anchors.centerIn: parent; width: pane.width / 4; height: width; rotation: 45 }
            }
            KeypadButton {
                id: infoButton
                anchors { right: parent.right; bottom: parent.bottom; margins: parent.width * .1 }
                height: Style.iconSize
                width: Style.iconSize
                imageSource: "../images/info.svg"
                visible: root.thing.thingClass.interfaces.indexOf("extendednavigationpad") >= 0
                Item { id: infoButtonArea; anchors.centerIn: parent; width: pane.width / 4; height: width; rotation: 45 }
            }
            Rectangle {
                id: enterButton
                anchors.centerIn: parent
                height: Style.iconSize
                width: Style.iconSize
                radius: width / 2
                border.color: t.running ? Style.accentColor : "#808080"
                Behavior on border.color { ColorAnimation { duration: 200 } }
                Timer { id: t; interval: 400 }
                border.width: 3
                color: "transparent"
                function activate() { t.start() }
            }

            Item { id: enterButtonArea; anchors.centerIn: parent; width: pane.width / 4; height: width; rotation: 0 }
            Item { id: leftButtonArea; anchors { left: parent.left; verticalCenter: parent.verticalCenter; } width: pane.width / 4; height: width; rotation: 0 }
            Item { id: rightButtonArea; anchors { right: parent.right; verticalCenter: parent.verticalCenter; } width: pane.width / 4; height: width;  rotation: 0 }
            Item { id: upButtonArea; anchors { top: parent.top; horizontalCenter: parent.horizontalCenter; } width: pane.width / 4; height: width; rotation: 0 }
            Item { id: downButtonArea; anchors { bottom: parent.bottom; horizontalCenter: parent.horizontalCenter; } width: pane.width / 4; height: width; rotation: 0 }

            Repeater {
                id: directionsRepeater
                model: 4

                Column {
                    height: parent.height * .8
                    width: Style.iconSize
                    anchors.centerIn: parent
                    rotation: index * 90

                    function activate() {
                        if (!delayTimer.running) {
                            delayTimer.idx = 2;
                            delayTimer.start();
                        } else {
                            delayTimer.onceMore = true;
                        }
                    }
                    Timer {
                        id: delayTimer;
                        triggeredOnStart: true
                        interval: 150
                        repeat: true
                        property int idx: 2
                        property bool onceMore: false
                        onTriggered: {
                            print("activating", idx)
                            childRepeater.itemAt(idx--).activate()
                            if (idx < 0) {
                                if (onceMore) {
                                    idx = 2;
                                    onceMore = false;
                                } else {
                                    delayTimer.stop();
                                }
                            }
                        }
                    }


                    Repeater {
                        id: childRepeater
                        model: 3
                        KeypadButton {
                            height: Style.iconSize
                            width: height
                            imageSource: "../images/up.svg"
                        }
                    }
                }
            }
        }

        MouseArea {
            id: mouseArea
            anchors.fill: parent
            preventStealing: true

            property int startX
            property int startY

            property string lockedDirection: "none"
            readonly property int steps: 20
            readonly property int stepSize: height / steps

            property int horizontalSteps: 0
            property int verticalSteps: 0

            onPressed: {
                startX = mouseX
                startY = mouseY
            }

            onPositionChanged: {
                var horizontalDiff = mouseX - startX
                var verticalDiff = mouseY - startY

                if (lockedDirection == "none") {
                    if (Math.abs(horizontalDiff) > stepSize) {
                        lockedDirection = "horizontal"
                        trigger(horizontalDiff > 0 ? "right" : "left")
                        directionsRepeater.itemAt(horizontalDiff > 0 ? 1 : 2).activate()
                    } else if (Math.abs(verticalDiff) > stepSize) {
                        lockedDirection = "vertical"
                        trigger(verticalDiff > 0 ? "down" : "up")
                        directionsRepeater.itemAt(verticalDiff > 0 ? 2 : 0).activate()
                    }
                }

                horizontalSteps = horizontalDiff / stepSize
                verticalSteps = verticalDiff / stepSize
            }

            onReleased: {
                if (lockedDirection === "none") {
                    if (checkButton(backButtonArea)) {
                        trigger("back");
                        backButton.activate();
                    } else if (checkButton(leftButtonArea)) {
                        trigger("left");
                        directionsRepeater.itemAt(3).activate()
                    } else if (checkButton(rightButtonArea)) {
                        trigger("right");
                        directionsRepeater.itemAt(1).activate()
                    } else if (checkButton(upButtonArea)) {
                        trigger("up");
                        directionsRepeater.itemAt(0).activate()
                    } else if (checkButton(downButtonArea)) {
                        trigger("down");
                        directionsRepeater.itemAt(2).activate()
                    } else if (checkButton(enterButtonArea)) {
                        trigger("enter");
                        enterButton.activate();
                    } else if (checkButton(menuButtonArea)) {
                        trigger("menu");
                        menuButton.activate();
                    } else if (checkButton(homeButtonArea)) {
                        trigger("home");
                        homeButton.activate();
                    } else if (checkButton(infoButtonArea)) {
                        trigger("info");
                        infoButton.activate();
                    }
                }

                lockedDirection = "none"
            }

            function checkButton(button) {
                var coords = mouseArea.mapToItem(button, mouseX, mouseY)
                if (coords.x > 0 && coords.x < button.width && coords.y > 0 && coords.y < button.height) {
                    return true;
                }
                return false;
            }

            function trigger(direction) {
                var params = []
                var param = {}
                param["paramTypeId"] = root.navigateActionType.paramTypes.findByName("to").id;
                param["value"] = direction;
                params.push(param);
                engine.thingManager.executeAction(root.thing.id, root.navigateActionType.id, params)
                PlatformHelper.vibrate(PlatformHelper.HapticsFeedbackSelection)
            }

            Timer {
                id: repeatTimer
                running: mouseArea.lockedDirection !== "none"
                interval: 1000
                repeat: true
                onRunningChanged: interval = 1000
                onTriggered: {
                    if (mouseArea.lockedDirection === "horizontal") {
                        mouseArea.trigger(mouseArea.horizontalSteps > 0 ? "right" : "left")
                        directionsRepeater.itemAt(mouseArea.horizontalSteps > 0 ? 1 : 3).activate()
                    } else if (mouseArea.lockedDirection === "vertical") {
                        mouseArea.trigger(mouseArea.verticalSteps > 0 ? "down" : "up")
                        directionsRepeater.itemAt(mouseArea.verticalSteps > 0 ? 2 : 0).activate()
                    }
                    interval = Math.max(50, 1000 - Math.abs(mouseArea.lockedDirection === "horizontal" ? mouseArea.horizontalSteps : mouseArea.verticalSteps) * 100)
                }
            }
        }
    }
}
