/*
    blueROCK - for digital rock
    Copyright (C) 2019  Dorian Zedler

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

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

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

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.3
import QtQuick.Controls.Material 2.12
import QtPurchasing 1.12

import de.itsblue.blueROCK 1.0

import "./Pages"
import "./Components"

import "./Widgets"

Window {
    visible: true
    width: 540
    height: 960
    title: "blueROCK"

    Page {
        id: app

        property int errorCode: -1

        property var colorShade: Material.theme === Material.Light ? Material.Shade300 : Material.Shade700
        property color nationalAdultsColor: Material.color(Material.Green, colorShade)
        property color nationalYouthColor: Material.color(Material.LightGreen, colorShade)
        property color federalColor: Material.color(Material.Grey, colorShade)

        // comp cats source:
        // - https://github.com/ralfbecker/ranking/blob/master/sitemgr/digitalrock/dav_calendar.php
        // - https://github.com/ralfbecker/ranking/blob/master/sitemgr/digitalrock/sac_calendar.php

        property var compCats: {
            // --- ICC ---

            /*'int' : {
                'label'  : 'International',
                'nation' : 'ICC',
                'wettk_reg' : '^[0-9]{2,2}[_^E]{1}[^YJ]{1,1}.*',
                'serie_reg' : '^[0-9]{2,2}_(WC|TR){1,1}.*',
                'rang_title': 'CUWR continuously updated WORLDRANKING',
                'bgcolor'   : '#B8C8FF',
                'nat_team_ranking' : '',
                'cat_id' : [68,86]//[68,69,70,86,259]
            },*/
            'worldcup': {
                'label' : 'World Cups',
                'nation' : 'ICC',
                'bgcolor'   : '#B8C8FF',
                'sort_rank': 1,
                'cat_id' : [69]
            },
            'youth' : {
                'label'  : 'Youth Events',
                'nation' : 'ICC',
                'wettk_reg' : '^[0-9]{2,2}(EYC|_J|_Y){1,1}.*',
                'serie_reg' : '^[0-9]{2,2}_EYC',
                'rang_title': '',
                'bgcolor'   : '#D8E8FF',
                'sort_rank': 2,
                'cat_id' : [71,258]
            },
            'cont': {
                'label' : 'Continental Events',
                'nation' : 'ICC',
                'bgcolor'   : '#B8C8FF',
                'sort_rank': 3,
                'cat_id' : [262]
            },
            'masters' : {
                'label'  : 'Masters and Promo Events',
                'nation' : 'ICC',
                'wettk_reg' : '^[0-9]{2,2}_[^PWERASL]{1}.*',
        //		'serie_reg' : '^[0-9]{2,2}_(WC|TR){1,1}.*',
        //		'rang_title': 'CUWR continuously updated WORLDRANKING',
                'bgcolor'   : '#F0F0F0',
                'sort_rank': 4,
                'cat_id' : [70]
            },
            'para' : {
                'label'  : 'Paraclimbing Events',
                'nation' : 'ICC',
                'wettk_reg' : '^[0-9]{2,2}_PE.*',
                'bgcolor'   : '#F0F0F0',
                'sort_rank': 5,
                'cat_id' : [256,259]
            },
            'games': {
                'label': 'Games',
                'nation': 'ICC',
                'bgcolor'   : '#B8C8FF',
                'sort_rank': 6,
                'cat_id': [68,86]
            },

            // --- GER ---

            'ger_meisterschaft' : {
                'label' : 'Deutsche Meisterschaft',
                'nation' : 'GER',
                'bgcolor'   : app.nationalAdultsColor,//'#A8F0A8',
                'sort_rank': 1,
                'cat_id' : [57, 59, 60]
            },

            'ger_jugend' : {
                'label'  : 'Deutscher Jugendcup',
                'nation' : 'GER',
                'wettk_reg' : '^[0-9]{2,2}[_J]{1,1}[^WL]+.*',
                'serie_reg' : '^[0-9]{2,2}_JC',
                //		'rang_title': 'Deutsche Jugend RANGLISTE',
                'bgcolor'   : app.nationalYouthColor,//'#D8FFD8',
                'sort_rank': 2,
                'cat_id' : [58]
            },
            'ger_state' : {
                'label'  : 'Landesmeisterschaft',
                'nation' : 'GER',
                'wettk_reg' : '^[0-9]{2,2}[_J]{1,1}LM.*',
                'serie_reg' : '^[0-9]{2,2}[_J]{1,1}LM.*',
                'rang_title': '',
                'bgcolor'   : app.federalColor, //'#F0F0F0',
                'sort_rank': 3,
                'cat_id' : [61,56]
            },

            // --- SUI ---

            'sui' : {
                'label'  : 'Erwachsene',
                'nation' : 'SUI',
                'wettk_reg' : '^[0-9]{2,2}_[^R].*',
                'serie_reg' : '.*',
                'rang_title': 'SWISS RANKING',
                'bgcolor'   : app.nationalAdultsColor, //'#A8F0A8',
                'sort_rank': 1,
                'cat_id'    : [62,63]
            },
            'sui_jugend' : {
                'label'  : 'Jugend',
                'nation' : 'SUI',
                'wettk_reg' : '^[0-9]{2,2}_[^R].*',
                'serie_reg' : '.*',
                'rang_title': 'SWISS RANKING',
                'bgcolor'   : app.nationalYouthColor, //'#D8FFD8',
                'sort_rank': 2,
                'cat_id'    : [65]
            },
            'sui_local' : {
                'label'  : 'RegioCups',
                'nation' : 'SUI',
                'wettk_reg' : '^[0-9]{2,2}_RG_.*',
                'rang_title': '',
                'bgcolor'   : app.federalColor, //'#F0F0F0',
                'sort_rank': 3,
                'cat_id'    : [64]
            },
            'sui_ice' : {
                'label'  : 'Iceclimbing',
                'nation' : 'SUI',
                'wparams["valid"]ettk_reg' : '^[0-9]{2,2}_RC_.*',
                'rang_title': '',
                'bgcolor'   : app.federalColor, //'#F0F0F0',
                'sort_rank': 4,
                'cat_id'    : [84]
            }
        }

        anchors.fill: parent

        Material.theme: appSettings.read("darkTheme") === "true" ? Material.Dark:Material.Light

        FontLoader {
            id: fa5solid
            source: "qrc:/fonts/fa5solid.otf"
        }

        FontLoader {
            id: fa5regular
            source: "qrc:/fonts/fa5regular.otf"
        }

        Shortcut {
            sequences: ["Esc", "Back"]
            enabled: mainStack.depth > 1
            onActivated: app.goBack()
        }

        BlueRockBackend {
            id: serverConn

            onOpenedViaUrl: {
                app.openWidgetFromUrl(url)
            }
        }

        AppSettings {
            id: appSettings
        }

        StackView {
            id: mainStack

            anchors {
                top: toolBar.bottom
                left: parent.left
                right: parent.right
                bottom: parent.bottom
            }

            initialItem: startPgComp

            Component {
                id: startPgComp
                StartPage {}
            }

            popEnter: Transition {
                XAnimator {
                    from: (mainStack.mirrored ? -1 : 1) * -mainStack.width
                    to: 0
                    duration: 500
                    easing.type: Easing.OutCubic
                }
            }

            popExit: Transition {
                XAnimator {
                    from: 0
                    to: (mainStack.mirrored ? -1 : 1) * mainStack.width
                    duration: 500
                    easing.type: Easing.OutCubic
                }
            }

            pushEnter: Transition {
                XAnimator {
                    from: (mainStack.mirrored ? -1 : 1) * mainStack.width
                    to: 0
                    duration: 500
                    easing.type: Easing.OutCubic
                }
            }

            pushExit: Transition {
                XAnimator {
                    from: 0
                    to: (mainStack.mirrored ? -1 : 1) * -mainStack.width
                    duration: 500
                    easing.type: Easing.OutCubic
                }
            }
        }

        AppToolBar {
            id: toolBar

            anchors {
                top: parent.top
                left: parent.left
                right: parent.right
                topMargin: -height
            }

            height: 50

            showErrorBar: true

            RowLayout {

                anchors.fill: parent

                spacing: width * 0.02

                ToolButton {
                    id:toolButton

                    height: parent.height

                    onClicked: app.goBack()

                    text: "\uf053"
                    font.family: fa5solid.name
                }

                Column {

                    Layout.fillWidth: true

                    height: childrenRect.height
                    width: parent.width - extraComponentLoader.width - toolButton.width - 3 * parent.spacing

                    MovingLabel {
                        id: toolBarTitleLa

                        syncWithLabel: toolBarSubTitleLa
                        width: parent.width
                        scale: 1

                        font.bold: true
                        verticalAlignment: Text.AlignVCenter

                        text: getText()

                        function getText(){
                            var titleString = "";

                            if(!mainStack.currentItem.titleIsPageTitle){
                                for(var i=1; i<mainStack.depth; i++){
                                    if(i > 1){
                                        titleString += " > "
                                    }

                                    titleString += mainStack.get(i).title
                                }
                            }
                            else {
                                titleString = mainStack.currentItem.title
                            }

                            return(titleString)
                        }

                        Behavior on text {
                            FadeAnimation {
                                target: toolBarTitleLa
                            }
                        }
                    }

                    MovingLabel {
                        id: toolBarSubTitleLa

                        visible: text !== ""

                        syncWithLabel: toolBarTitleLa
                        width: parent.width

                        font.bold: false

                        text: getText()

                        function getText(){
                            var titleString = "";

                            if(mainStack.currentItem.subTitle !== undefined){
                                titleString = mainStack.currentItem.subTitle
                            }

                            return titleString
                        }

                        Behavior on text {
                            FadeAnimation {
                                target: toolBarSubTitleLa
                            }
                        }
                    }

                }

                Loader {
                    id: extraComponentLoader

                    property int maximumWidth: parent.width * 0.4 - toolButton.width - 3

                    height: parent.height

                    onItemChanged: {
                        if(item === null) {
                            extraComponentLoader.Layout.preferredWidth = 0
                            return
                        }

                        extraComponentLoader.item.width = extraComponentLoader.item.implicitWidth
                        extraComponentLoader.Layout.preferredWidth = extraComponentLoader.item.width
                        widthChangedCon.target = extraComponentLoader.item
                    }

                    Connections {
                        target: mainStack
                        function onCurrentItemChanged() {
                            secondCon.target = mainStack.currentItem
                            disappearNa.start()
                        }
                    }

                    Connections {
                        id: secondCon
                        target: null
                        function onHeaderComponentChanged() {
                            disappearNa.start()
                        }
                    }

                    Connections {
                        id: widthChangedCon
                        function onImplicitWidthChanged() {
                            extraComponentLoader.item.width = extraComponentLoader.item.implicitWidth
                            extraComponentLoader.Layout.preferredWidth = extraComponentLoader.item.implicitWidth
                        }
                    }

                    ParallelAnimation {
                        id: appearNa

                        NumberAnimation {

                            target: extraComponentLoader
                            property: "opacity"

                            from: 0
                            to: 1

                            duration: 150
                        }

                        NumberAnimation {

                            target: extraComponentLoader
                            property: "scale"

                            from: 0.9
                            to: 1

                            duration: 150
                        }
                    }

                    ParallelAnimation {
                        id: disappearNa

                        NumberAnimation {

                            target: extraComponentLoader
                            property: "opacity"

                            from: 1
                            to: 0

                            duration: 150
                        }

                        NumberAnimation {

                            target: extraComponentLoader
                            property: "scale"

                            from: 1
                            to: 0.9

                            duration: 150
                        }

                        onRunningChanged: {
                            if(!running){
                                extraComponentLoader.sourceComponent = mainStack.currentItem.headerComponent
                                appearNa.start()
                            }
                        }

                    }
                }

            }

            Behavior on anchors.topMargin {
                NumberAnimation {
                    duration: 500
                    easing.type: Easing.OutCubic
                }
            }

            states: [
                State {
                    name: "closed"
                    when: mainStack.depth === 1
                    PropertyChanges {
                        target: toolBar
                        anchors.topMargin: -height
                    }
                },
                State {
                    name: "open"
                    when: mainStack.depth > 1
                    PropertyChanges {
                        target: toolBar
                        anchors.topMargin: 0
                    }
                }
            ]
        }

        Popup {
            id: loadingDl

            x: ( app.width - width ) / 2
            y: ( app.height - height ) / 2

            modal: true
            closePolicy: Dialog.NoAutoClose

            contentItem: Column {

                spacing: 50

                FancyBusyIndicator {
                    running: true
                }

                Label {

                    anchors.horizontalCenter: parent.horizontalCenter

                    font.bold: true
                    color: "white"

                    //% "Loading"
                    text: qsTrId("#loading") + "..."
                }
            }

            background: Rectangle {
                color: "transparent"
            }


        }

        Store {
            id: inAppProductStore

            Product {
                id: speedFlowChartProduct
                identifier: "speed_flowchart"
                //identifier: "android.test.purchased"
                //identifier: "android.test.canceled"
                //identifier: "android.test.refunded"

                type: Product.Unlockable

                onPurchaseRestored: {
                    appSettings.write("speedBackendPurchase", 1)
                }

                onPurchaseSucceeded: {
                    appSettings.write("speedBackendPurchase", 1)
                }

                onPurchaseFailed: {
                    appSettings.write("speedBackendPurchase", 0)
                }
            }
        }

        function landscape() {
            return app.height < app.width
        }

        function toggleDarkMode() {
            var dark = app.Material.theme === Material.Light

            app.Material.theme = dark ? Material.Dark : Material.Light
            appSettings.write("darkTheme", dark)
        }

        function largeScreen() {
            return Math.min(app.width, app.height) > 750
        }

        function openWidget(params) {
            loadingDl.open()

            console.log("Opening widget: ", JSON.stringify(params))

            var result = false

            if(Object.keys(params).length) {
                var calComp = Qt.createComponent("qrc:/Pages/WidgetPage.qml").createObject(null, {"params": params})
                app.errorCode = calComp.status

                if(calComp.ready) {
                    mainStack.push(calComp)
                    result = true
                }
                else {
                    delete(calComp)
                }
            }

            loadingDl.close()
            return result
        }

        function openWidgetFromUrl(url) {
            var result = serverConn.getParamsFromUrl(url)

            if(result["valid"]) {
                openWidget(result["params"])
                return app.errorCode !== 906
            }

            return result["valid"]
        }

        function defaultString(string, defaultString) {
            if(string === undefined || string === null) {
                return defaultString
            }
            else {
                return string
            }
        }

        function goBack() {
            if(!mainStack.currentItem.hasOwnProperty('onBackRequested') || mainStack.currentItem.onBackRequested())
                mainStack.pop()
        }

        function getErrorInfo(errorCode) {

            var infoLevel
            // 0 - ok
            // 1 - info
            // 2 - error

            var errorString

            switch(errorCode) {
            case 0:
                infoLevel = 2
                //% "No connection to server"
                errorString = qsTrId("#noConnectionError")
                break
            case 404:
                infoLevel = 2
                //% "Not found"
                errorString = qsTrId("#notFoundError")
                break
            case 901:
                infoLevel = 1
                //% "No Data"
                errorString = qsTrId("#noDataError")
                break
            case 906:
                infoLevel = 2
                //% "Invalid Request"
                errorString = qsTrId("#invalidRequestError")
                errorDescription = "Invalid Request"
                break
            default:
                infoLevel = 2
                //% "Unexpected error"
                errorString = qsTrId("#unexpectedError") + " ("+errorCode+")"
            }

            return([infoLevel, errorString])
        }

    }
}
