/*
    Speed Climbing Stopwatch - Simple Stopwatch for Climbers
    Copyright (C) 2018  Itsblue Development - Dorian Zeder

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, version 3 of the License.

    This program 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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

import QtQuick 2.9
import QtMultimedia 5.8
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
//import QtQuick.Layouts 1.11

import com.itsblue.speedclimbingstopwatch 1.0

Window {
    visible: true
    width: 540
    height: 960
    title: qsTr("Speedclimbing stw")
    property date currentTime: new Date()
    property int millis: 0


    Page {

        id:root
        anchors.fill: parent

        property double startTime: 0
        property double stoppedTime: 0
        property double currTime

        property double buzzer_offset
        property double last_button_pressed

        property var last_run : {
            'stopp_type': "", 'time': 0
          };

        //set default state to IDLE
        state: "IDLE"

        Timer {
            //timer that updates the currTime variable
            running: true
            repeat: true
            interval: 1
            onTriggered: {
                root.currTime = new Date().getTime()

            }
        }

        BuzzerConn {
            onPushed: {
                // the buzzer was pushed
                root.stop("buzzer")
            }
        }

        Timer {
            id: next_actionTimer

            property string action
            property double started_at

            running: false
            repeat: false
            onRunningChanged: {
                if(!running){
                    started_at = 0
                    if(action == "NONE"){
                        time.text = "0.000 sec"
                    }
                    return
                }

                if(action === "at_marks"){
                    started_at = new Date().getTime()
                    time.text = "at your\nmarks"
                }
                else if(action === "ready"){
                    started_at = new Date().getTime()
                    time.text = "ready"
                }
            }

            onTriggered: {
                if(action === "at_marks"){
                    at_marksSound.play()
                }
                else if(action === "ready"){
                    action = "NONE"
                    readySound.play()
                }

            }
        }

        SoundEffect {
            id: at_marksSound
            source: "qrc:/sounds/at_marks_1.wav"

            onPlayingChanged: {
                if(!playing && root.state==="STARTING"){
                    if(_cppAppSettings.loadSetting("ready_en") === "true"){
                        next_actionTimer.action = "ready"
                        next_actionTimer.interval = _cppAppSettings.loadSetting("ready_delay")>0 ? _cppAppSettings.loadSetting("ready_delay"):1
                        next_actionTimer.start()
                    }
                    else{
                        startSound.play()
                    }
                }
            }
        }

        SoundEffect {
            id: readySound
            source: "qrc:/sounds/ready_1.wav"
            onPlayingChanged: {
                if(!playing && root.state==="STARTING"){
                    startSound.play()
                }
            }
        }

        SoundEffect {
            //start sound
            id: startSound
            source: "qrc:/sounds/OFFICAL_IFSC_STARTIGNAL.wav"

            onPlayingChanged: {
                if(!playing && root.state==="STARTING"){
                    root.startTime = _cppBuzzerConn.get("currtime")

                    root.currTime = _cppBuzzerConn.get("currtime")
                    time.text = ( ( root.currTime - root.startTime ) / 1000 ).toFixed(3) + " sec"
                    root.state = "RUNNING"
                }
            }
        }

        /*------------------------
          Timer text an upper line
        ------------------------*/
        Item {
            id: time_container
            anchors {
                top: parent.top
                left: parent.left
                right: root.landscape() ? startButt.left:parent.right
                bottom: root.landscape() ? parent.bottom:startButt.top
                bottomMargin: root.landscape() ? undefined:parent.height * 0.1
                rightMargin: root.landscape() ? parent.width * 0.05:0
            }
            //height: root.landscape() ? undefined:parent.height * 0.15
            Label {
                id: time
                text: qsTr("Click start to start")

                anchors.centerIn: parent
                //font.pixelSize: root.landscape() ? parent.width * 0.1:parent.height * 0.3
                elide: "ElideRight"

                Behavior on text {
                    enabled: root.state !== "RUNNING"
                    FadeAnimation {
                        target: time
                    }
                }
            }
        }

        Image {
            id: buzzerLogo
            source: "qrc:/graphics/icons/buzzer_black.png"
            mipmap: true
            anchors {
                top: parent.top
                topMargin: 10
                left: parent.left
                leftMargin: 10
            }
            visible: _cppBuzzerConn.get("connected")===1
           height: root.landscape()? root.height*0.1:root.width*0.1
           width: height
           Component.onCompleted: {
               visible= _cppBuzzerConn.get("connected")===1
           }

           Timer {
               interval: 100
               running: true
               repeat: true
               onTriggered: {
                   buzzerLogo.visible= _cppBuzzerConn.get("connected")===1
               }
           }
        }

        Rectangle {
            id: upper_line
            width: root.landscape() ? 1:parent.width
            height: root.landscape() ? parent.height:1
            color: "grey"
            anchors.left: root.landscape() ? time_container.right:parent.left
            anchors.top: root.landscape() ? parent.top:time_container.bottom
            anchors.bottom: root.landscape() ? parent.bottom:undefined
        }

        /*----------------------
          Start / Stop / Reset button
        ----------------------*/
        Button {
            id : startButt

            text: qsTr("start")
            property int size: root.landscape() ? parent.width * 0.5:parent.height * 0.5
            anchors {
                bottom: parent.bottom
                bottomMargin: root.height * 0.5 - height * 0.5
                right: parent.right
                rightMargin: root.width * 0.5 - width * 0.5
            }
            contentItem: Text {
                //make text disappear
            }
            height: root.landscape() ? size > parent.height * 0.9 ? parent.height * 0.9:size : size
            width: root.landscape() ? size : size > parent.width * 0.9 ? parent.width * 0.9:size

            onPressedChanged: {
                if(pressed){
                    background.color = "lightgrey"
                }
                else {
                    background.color = "white"
                }
            }

            background: Rectangle {
                color: "white"
                border.color: "grey"
                border.width: 1
                radius: width / 2
                Label {
                    id: startButt_text
                    text: startButt.text
                    anchors.centerIn: parent
                    font.pixelSize: parent.height * 0.16
                    font.family: "Helvetica"
                }
            }

            Behavior on text {
                //animate a text change
                enabled: true
                FadeAnimation {
                    target: startButt_text
                }
            }

            onClicked: {
                switch(root.state) {
                case "IDLE":
                    root.start()
                    break
                case "RUNNING":
                    root.stop("manual")
                    break
                case "STOPPED":
                    root.reset()
                    break
                }
            }
        }

        ProgressCircle {
            id: prog
            anchors.fill: startButt
            opacity: next_actionTimer.started_at > 0 ? 1:0
            lineWidth: 5

            arcBegin: 0
            arcEnd: 360 * (( next_actionTimer.interval - ( new Date().getTime() - next_actionTimer.started_at ) ) / next_actionTimer.interval)

            colorCircle: "grey"

            animationDuration: 0

            Timer {
                id: prog_refresh
                running: parent.opacity === 1
                interval: 1
                repeat: true
                onTriggered: {
                    prog.arcEnd = 360 * (( next_actionTimer.interval - ( new Date().getTime() - next_actionTimer.started_at ) ) / next_actionTimer.interval)
                }
            }
        }

        /*----------------------
          Cancel button
        ----------------------*/
        RoundButton {
            id: cancelButt

            text: qsTr("cancel")
            anchors {
                right: startButt.right
                bottom: startButt.bottom
            }
            contentItem: Text {
                //make text disappear
            }
            height: startButt.height * 0.3
            scale: 0
            width: height

            enabled: root.state === "STARTING"
            onPressedChanged: {
                if(pressed){
                    background.color = "lightgrey"
                }
                else {
                    background.color = "white"
                }
            }

            onClicked: {
                root.stop("false")
            }

            Behavior on scale {
                PropertyAnimation {
                    duration: 200
                }
            }
            background: Rectangle {
                color: "white"
                border.color: "grey"
                border.width: 1
                radius: width / 2
                Label {
                    id: cancelButt_text
                    text: cancelButt.text
                    anchors.centerIn: parent
                    font.pixelSize: parent.height * 0.16
                    font.family: "Helvetica"
                }
            }
        }

        /*------
          Popups
        ------*/
        SettingsDialog{
            id: settingsDialog
        }

//        ProfilesDialog {
//            id: profilesDialog
//        }

        /*-------------------
          lower line and menu
        -------------------*/
        Rectangle {
            width: root.landscape() ? 1:parent.width
            height: root.landscape() ? parent.height:1
            color: "grey"
            anchors.right: root.landscape() ? menu_container.left:parent.right
            anchors.bottom: root.landscape() ? parent.bottom:menu_container.top
            anchors.top: root.landscape() ? parent.top:undefined
        }

        Item {
            id: menu_container
            anchors {
                bottom: parent.bottom
                right: parent.right
                left: root.landscape() ? startButt.right:parent.left
                top: root.landscape() ? parent.top:startButt.bottom
                topMargin: root.landscape() ? undefined:parent.height * 0.1
                leftMargin: root.landscape() ? parent.width * 0.05:0
            }

            RoundButton {
                id: settingsButt

                anchors {
                    //center
                    verticalCenter: root.landscape() ? undefined:parent.verticalCenter
                    horizontalCenter: root.landscape() ? parent.horizontalCenter:undefined
                    //set anchors
                    left: root.landscape() ? undefined:parent.left
                    top: root.landscape() ? parent.top:undefined
                    //align in landscape mode
                    //for two buttons: topMargin: root.landscape() ? (parent.height - (height * 2)) / 3:undefined
                    topMargin: root.landscape() ? (parent.height * 0.5 - (height * 0.5)):undefined
                    //align in portrait mode
                    //for two buttons: leftMargin: root.landscape() ? undefined:(parent.width - width * 2) / 3
                    leftMargin: root.landscape() ? undefined:(parent.width * 0.5 - width * 0.5)
                }

                height: root.landscape() ? parent.width * 0.7:parent.height * 0.7
                width: height

                onPressedChanged: {
                    if(pressed){
                        background.color = "lightgrey"
                    }
                    else {
                        background.color = "white"
                    }
                }

                onClicked: {
                   settingsDialog.open()
                }

                background: Rectangle {
                    color: "white"
                    border.color: "grey"
                    border.width: 1
                    radius: width / 2


                    Image {
                        id: settungsButt_Image
                        source: "qrc:/graphics/icons/settings.png"
                        anchors.centerIn: parent
                        height: parent.height * 0.7
                        width: parent.width * 0.7
                        mipmap: true
                    }
                }
            }

            /*
            RoundButton {
                id: profilesButt

                anchors {
                    verticalCenter: root.landscape() ? undefined:parent.verticalCenter
                    horizontalCenter: root.landscape() ? parent.horizontalCenter:undefined
                    left: root.landscape() ? undefined:settingsButt.right
                    top: root.landscape() ? settingsButt.bottom:undefined
                    topMargin: root.landscape() ? (parent.height - (height * 2)) / 3:undefined
                    leftMargin: root.landscape() ? undefined:(parent.width - width * 2) / 3
                }

                height: root.landscape() ? parent.width * 0.7:parent.height * 0.7
                width: height

                onPressedChanged: {
                    if(pressed){
                        background.color = "lightgrey"
                    }
                    else {
                        background.color = "white"
                    }
                }

                onClicked: {
                    profilesDialog.open()
                }

                background: Rectangle {
                    color: "white"
                    border.color: "grey"
                    border.width: 1
                    radius: width / 2

                    Image {
                        id: profilesButt_Image
                        source: "qrc:/graphics/icons/user.png"
                        anchors.centerIn: parent
                        height: parent.height * 0.5
                        width: parent.width * 0.5
                        mipmap: true
                    }
                }
            }
            */

        }

        /*----------------------
          Timer states
        ----------------------*/
        states: [
            State {
                name: "IDLE"
                //state for the start page
                PropertyChanges { target: time; text: qsTr("Click start to start"); font.pixelSize: root.landscape() ? parent.width * 0.1:parent.height * 0.3; scale: 1 }
                PropertyChanges {
                    target: time_container;
                    anchors.bottomMargin: root.landscape() ? undefined:parent.height * 0.1;
                    anchors.rightMargin: root.landscape() ? parent.height * 0.05:0
                }

                PropertyChanges {
                    target: startButt;
                    enabled: true; text: qsTr("start");
                    size: root.landscape() ? parent.width * 0.5:parent.height * 0.5
                    anchors.bottomMargin: parent.height * 0.5 - startButt.height * 0.5
                    anchors.rightMargin: parent.width * 0.5 - startButt.width * 0.5
                }

            },
            State {
                name: "STARTING"
                //state for the start sequence
                PropertyChanges { target: startButt; enabled: false; text: qsTr("starting...");
                    anchors.rightMargin: root.landscape() ? parent.width * 0.05:parent.width * 0.5 - startButt.width * 0.5 //put the button more to the right to hide the menu (only in landscape mode)
                    anchors.bottomMargin: root.landscape() ? parent.height * 0.5 - startButt.height * 0.5:parent.height * 0.1 //put the button lower to hide the menu (only in portrait mode)
                }
                PropertyChanges { target: time; text: "0.000 sec"; font.pixelSize: root.landscape() ? parent.width * 0.2:parent.height * 0.3; scale: 1 }
                PropertyChanges { target: cancelButt; scale: 1}
                PropertyChanges { target: menu_container; }
            },
            State {
                name: "RUNNING"
                //state when the timer is running
                PropertyChanges { target: time; text: ( ( root.currTime - root.startTime ) / 1000 ).toFixed(3) + " sec"; font.pixelSize: root.landscape() ? parent.width * 0.2:parent.height * 0.3; scale: 1 }
                PropertyChanges { target: startButt; enabled: true;
                    text: "stop"
                    anchors.rightMargin: root.landscape() ? parent.width * 0.05:parent.width * 0.5 - startButt.width * 0.5 //put the button more to the right to hide the menu (only in landscape mode)
                    anchors.bottomMargin: root.landscape() ? parent.height * 0.5 - startButt.height * 0.5:parent.height * 0.1 //put the button lower to hide the menu (only in portrait mode)
                }

            },

            State {
                name: "STOPPED"
                //state when the meassuring is over
                PropertyChanges {
                    target: time;
                    text: root.stoppedTime > 0 ? ( root.stoppedTime / 1000 ).toFixed(3) + " sec":qsTr("false start");
                    font.pixelSize: root.landscape() ? parent.width * 0.15:parent.height * 0.1;
                    scale: 1
                }
                PropertyChanges {
                    target: startButt;
                    enabled: true; text: qsTr("reset");
                    size: root.landscape() ? parent.height * 0.35:parent.height * 0.2;
                    anchors.bottomMargin: root.landscape() ? parent.height * 0.5 - startButt.height * 0.5:parent.height * 0.2 - startButt.height * 0.5
                    anchors.rightMargin: root.landscape() ? parent.height * 0.2 - startButt.height * 0.5:parent.width * 0.5 - startButt.width * 0.5
                }
                PropertyChanges {
                    target: time_container;
                    anchors.rightMargin: root.landscape() ? 0-startButt.width/2:undefined
                    anchors.bottomMargin: root.landscape() ? undefined:0-startButt.height/2
                }
            }
        ]

        /*----------------------
          Timer animations
        ----------------------*/
        transitions: [
            Transition {
                NumberAnimation { properties: "size,rightMargin,height,width,bottomMargin,font.pixelSize"; easing.type: Easing.InOutQuad; duration: 700 }
            },
            Transition {
                to: "STOPPED"
                NumberAnimation { properties: "size,rightMargin,height,width,bottomMargin,font.pixelSize"; easing.type: Easing.InOutQuad; duration: 700 }
            },
            Transition {
                to: "IDLE"
                NumberAnimation { properties: "size,rightMargin,height,width,bottomMargin,font.pixelSize"; easing.type: Easing.InOutQuad; duration: 700 }
            },

            Transition {
                to: "RUNNING"
                //disable transitions for the RUNNING state
            }
        ]

        /*----------------------
          Timer functions
        ----------------------*/
        function landscape(){
            return(root.height < root.width)
        }

        /*----Functions to control the stopwatch----*/
        function start(){
            root.state = "STARTING"
            if(_cppAppSettings.loadSetting("at_marks_en") === "true"){
                next_actionTimer.action = "at_marks"
                next_actionTimer.interval = _cppAppSettings.loadSetting("at_marks_delay")>0 ? _cppAppSettings.loadSetting("at_marks_delay"):1
                next_actionTimer.start()
                return
            }
            if(_cppAppSettings.loadSetting("ready_en") === "true"){
                next_actionTimer.action = "ready"
                next_actionTimer.interval =  _cppAppSettings.loadSetting("ready_delay")>0 ? _cppAppSettings.loadSetting("ready_delay"):1
                next_actionTimer.start()
                return
            }

            startSound.play()
        }

        function stop(type){
            switch(type){
            case "buzzer":
                //the buzzer was pushed
                root.buzzer_offset = _cppBuzzerConn.get("offset")
                root.last_button_pressed = _cppBuzzerConn.get("lastpressed")
                root.stoppedTime = (root.last_button_pressed + root.buzzer_offset) - root.startTime
                root.state = "STOPPED"
                //time.text = ( root.stoppedTime / 1000 ).toFixed(3) + " sec"
                console.log("STOPPED: "+root.stoppedTime)
                break
            case "manual":
                //te stop button was pressed
                root.stoppedTime = new Date().getTime() - root.startTime
                time.text = ( root.stoppedTime / 1000 ).toFixed(3) + " sec"
                root.state = "STOPPED"
                break
            case "false":
                //the cancel button was pressed
                root.stoppedTime = 0
                time.text = "false start"
                root.state = "STOPPED"
                next_actionTimer.stop()
                at_marksSound.stop()
                readySound.stop()
                startSound.stop()
                break
            }
        }

        function reset(){
            root.state = "IDLE"
        }
    }
}
