/*****************************************************************************
**                                                                          **
** Created by Antonio Mancini                                               **
** Contact: <ziobilly94@gmail.com>                                          **
** This is a version of classic Tetris game for SailfishOS developed        **
** entirely by me, no copyright infringement intended.                      **
**                                                                          **
*****************************************************************************/

import QtQuick 2.0
import Sailfish.Silica 1.0
import QtQuick.LocalStorage 2.0
import QtQuick.Particles 2.0
import "../js/settings.js" as Settings
import "../game"

Page {
    id: page


    HighScoreModel {
        id: highScoreModel
        game: hsdb
    }

    Functions {
        id: functions
    }
    property bool onlineEnabled: Settings.getValue("onlineEnabled",0)
    property string hsdb: onlineEnabled ? "online" : "local"
    property int dots: Settings.getValue("dots",1)
    property int ghostEnabled: Settings.getValue("ghostEnabled",1)
    property int musicEnabled: Settings.getValue("musicEnabled",1)
    property int sfxEnabled: Settings.getValue("sfxEnabled",1)
    property string musicScore: "../data/tetris.ogg" //: Settings.getValue("musicScore","")
    property int scoreValue
    property int speedValue
    property int linesValue
    property int level: 1
    property int linesTotal: 0
    property int activeBlock
    property int futureBlock: -1
    property int combo: 1
    property int gravityBreak: 1
    property bool pauseVal
    property int downSpeed: 2500
    property int comboSpeed: 10000

    // 0 = l_normal; 1 = l_reverse;
    // 2 = s_normal; 3 = s_reverse;
    // 4 = t_normal; 5 = square;
    // 6 = line

    property variant activeColor
    property variant futureColor

    property real centerX
    property real centerY

    Timer {
        id: gameOverTimer
        property int i: 15
        property int j: 10
        property bool clear: true
        property bool done: false
        interval: 10
        repeat: true
        onTriggered : {
            if (clear) {
                if ( j === 0) {
                    i--
                    j = 10
                } else {
                    if ( i === 0) {
                        clear = false
                        done = true
                        j = 10
                        i = 15
                    } else {
                        var index = i*12+j
                        repeater.itemAt(index).color = Theme.secondaryHighlightColor//"black"//"transparent"//Theme.secondaryColor
                        repeater.itemAt(index).opacity = 0.5//0.5
                        j--
                    }
                }
            } else {
                if ( j === 0) {
                    i--
                    j = 10
                } else {
                    if ( i === 0) {
                        running = false
                        clear = true
                        if (highScoreModel.newScore) {
                            highScoreModel.newScore = false
                            getName.visible = true ;
                           } else {
                         pullDownMenu.enabled = true
                         splash.visible = true
                        }
                        i = 15
                        j = 10
                    }
                    else {
                        done = false
                        index = i*12+j
                        repeater.itemAt(index).opacity = 0.1
                        j--
                    }
                }
            }
        }
    }

    function downSpeedCalc(level) {
        if (level>1){
        for ( var i = 1; i < level; i++) {
            var ds = downSpeed/15
            downSpeed -= ds
        }
        return downSpeed
        }
    }

    function comboSpeedCalc(level) {
        for ( var i = 1; i < level; i++) {
            comboSpeed = comboSpeed/30
        }
        return comboSpeed+200
    }

    Timer {
        id: downTimer
        interval:  downSpeed+150//interval-(interval/20)+150 //difficulty*(1338*Math.pow(Math.E,-0.07*level)+150) //difficulty*(1338*Math.pow(Math.E,-0.26*level)+150)
        repeat: true
        running: false
        onTriggered: {
            functions.flow()
            speedValue += 1
        }
    }

    SilicaFlickable {
        id: root
        anchors.fill: page
        contentHeight : height

        PushUpMenu {
            id:pushUpMenu
            enabled: false
            visible: false
            MenuItem {
                id: pauseMenuItem
                text: qsTr("Resume")
                onClicked: functions.pause()
            }
        }

        PullDownMenu {
            id: pullDownMenu
            MenuItem {
                text: qsTr("About")
                onClicked: pageStack.push("About.qml")
            }

            MenuItem {
                text: qsTr("Settings")
                onClicked: {
                    var dialog = pageStack.push("SettingsDialog.qml", {"dots": dots, "ghostEnabled": ghostEnabled, "musicEnabled": musicEnabled, "sfxEnabled": sfxEnabled, "musicScore": musicScore, "onlineEnabled": onlineEnabled})
                    dialog.accepted.connect(function() {

                        dots = dialog.dots
                        ghostEnabled = dialog.ghostEnabled
                        musicEnabled = dialog.musicEnabled
                        sfxEnabled = dialog.sfxEnabled
                        onlineEnabled = dialog.onlineEnabled
                        highScoreModel.place = 0
                        Settings.setValue("dots",dots)
                        Settings.setValue("ghostEnabled",ghostEnabled)
                        Settings.setValue("musicEnabled",musicEnabled)
                        Settings.setValue("sfxEnabled",sfxEnabled)
                        Settings.setValue("onlineEnabled",onlineEnabled)
                     //   highScoreModel.game = "local"
                    })
                }
            }

            MenuItem {
                text: functions.garunning ? functions.gapaused ? qsTr("Resume") : qsTr("Pause") : qsTr("New Game")
                onClicked: {
                    if (functions.garunning) {
                        functions.pause()
                    } else {

                    splash.visible = false
                    highscores.visible = false
                    functions.newGame()
                    }
                }
            }
        }

        Label {
            id: score
            text:  qsTr("LEVEL ") + "\n" + qsTr("SCORE ")  + "\n" + qsTr("LINES ")
            color: Theme.secondaryHighlightColor
            font.family: Theme.fontFamilyHeading
            font.pixelSize: Theme.fontSizeMedium
            anchors {
                left: parent.left
                leftMargin: Theme.paddingMedium
                bottom: futureGrid.bottom
            }
        }
        Label {
            id: scoreValues
            text:  level + "\n" + scoreValue + "\n" + linesTotal
            color: Theme.highlightColor
            font.family: Theme.fontFamilyHeading
            font.bold: true
            font.pixelSize: Theme.fontSizeMedium
            horizontalAlignment: Text.AlignRight
            anchors {
                right: bonusPanel.left
                rightMargin: Theme.paddingLarge
                bottom: futureGrid.bottom
            }
        }

        Rectangle {
            id: bonusPanel
            radius: height / 2
            height: futureGrid.height
            width: height
            color: Theme.highlightDimmerColor

            opacity: bonusLabel.opacity > 0 ? 0.8 : 0//bonusLabel.opacity
             anchors {
                horizontalCenter: parent.horizontalCenter
                top: futureGrid.top
            }
        }

        Label {
            id: bonusLabel
            text: ""///functions.garunning ? "" : "PLAY"
            color: Theme.highlightColor
            font.pixelSize: functions.garunning ? bonusPanel.height - (Theme.paddingMedium * 2) : Theme.fontSizeLarge
            font.bold: true
            anchors.verticalCenter: bonusPanel.verticalCenter
            anchors.horizontalCenter: bonusPanel.horizontalCenter
            opacity: 0//functions.garunning ? 0 : 1//infoTimer.running ? 1 : 0
            Behavior on opacity {
                FadeAnimator {}
            }
        }

        Grid {
            id: futureGrid
            y: (parent.height-rect.height-height)/2
            anchors {
                right: parent.right
                rightMargin: Theme.paddingLarge
            }
            columns: 4
            rows: 3
            Repeater {
                id: futureRepeater
                model: 12
                delegate: Dot {width: Theme.paddingLarge*5/3 ;color: Theme.highlightBackgroundColor; opacity: 0.1}
            }
        }

        Timer {  // EXPERIMENT
            id: hssplachTimer
            running: splash.visible || highscores.visible && Qt.application.active && !contextMenu.visible? true : false//!functions.garunning && !gameOverTimer.running ? true : false
            interval: 8000
            repeat: true
            onTriggered: if (highscores.visible) {highscores.visible=false;splash.visible = true;} else {highscores.visible=true;splash.visible=false}//highscores.visible ? splash.visible = true : high.visible = false
        }

        Rectangle {
            id: rect
            width: grid.width
            height: grid.height
            anchors {
                bottom: parent.bottom
            }
            border.color: "transparent"
            color: "black"
           opacity: 0.8//0.8
            Grid {
                id: grid
                columns: 12
                rows: 17
                Repeater {
                    id: repeater
                    model: 204
                    delegate: Dot {width: page.width/12 ;color: Theme.highlightBackgroundColor; opacity: 0.1}
                    onItemAdded: { // Bordi "muro"... seriamente, si può fare di meglio, 576 caratteri per una linea è più brutto di questo commento, da aggiungere a newGame() magari
                        if (index < 12 || index > 191 || index === 0 || index === 12 ||
                            index === 24 || index === 36 || index === 48 || index === 60 ||
                            index === 72 || index === 84 || index === 96 || index === 108 ||
                            index === 120 || index === 132 || index === 144 || index === 156 ||
                            index === 168 || index === 180 || index === 23 || index === 35 ||
                            index === 47 || index === 59 || index === 71 || index === 83 ||
                            index === 95 || index === 107 || index === 119 || index === 131 ||
                            index === 143 || index === 155 || index === 167 || index === 179 || index === 191)
                        {
                            itemAt(index).active = 3
                            itemAt(index).color = Theme.highlightBackgroundColor
                            itemAt(index).opacity = 0.5
                        }
                     }
                }
            }

     /*       ParticleSystem {
                id: sys
            }

            Emitter {
                anchors.fill: parent
                system: sys
                ImageParticle {
                    anchors.fill: parent
                    system: sys
                    source: "../data/dot.png"
                    clip: true
                    id:  redblip
                }
                velocity: PointDirection {yVariation: 16; xVariation: 5}
                acceleration: PointDirection {y: -16}
                lifeSpan: Emitter.InfiniteLife
                maximumEmitted: 1000
            } */

            MultiPointTouchArea {
                id: mouseArea
                property int offsetX: grid.width/14
                property int offsetY: (grid.height/19)
                property int blahX: (parent.width - (grid.width-point1.x))/offsetX
                property int blahY: (parent.height - (grid.height-point1.y))/offsetY
                property int prevX
                property int prevY
                property int initX
                property int initY
                property int inter: 85
                property int plus: 0
                x: 0
                y: 0

                anchors.fill: grid
                anchors.margins: offsetX
                mouseEnabled: true

                touchPoints: [
                    TouchPoint { id: point1 },
                    TouchPoint { id: point2 },
                    TouchPoint { id: point3 }
                ]


                onTouchUpdated: {
                    if (functions.maenabled){
                        if (point1.pressed && point2.pressed && point3.pressed){
                            if (blahY > prevY+2){
                                prevY=blahY
                                functions.instantDown()
                            }
                        } else if (point1.pressed && point2.pressed && !point3.pressed){
                            if (blahY > prevY){
                                prevY=blahY
                                functions.down()
                            }
                            if (blahY < prevY-2){
                                prevY=blahY
                                functions.pause()
                            }
                         } else if (point1.pressed && !point2.pressed && !point3.pressed){
                            //if (blahY==prevY) var plus = 0; else plus = 1;
                            if (blahY > prevY){
                                plus = 1;
                                functions.down()
                                prevY=blahY
                            } else {
                                if (blahX < prevX-plus) {
                                    functions.left()
                                    prevX=blahX
                                    plus = 0
                                }
                                if (blahX > prevX+plus){
                                    functions.right()
                                    prevX=blahX
                                    plus = 0
                                }
                            }
                        /*    if (blahY > prevY){
                                prevY=blahY
                                functions.down()
                            } */
                        }
                     //   console.log(blahX + " - " + prevX)
                    }
                }

                onReleased: {
                    if (blahY == initY && blahX == initX && !point1.pressed && !point2.pressed || point1.pressed && !point2.pressed){
                        functions.rotate()
                    }

                    functions.maenabled = true
                }

                onPressed: {
                    prevX = blahX
                    initX = blahX
                    prevY = blahY
                    initY = blahY
                }
            }
            Label {
                id: gameOverLabel
                anchors {
                    horizontalCenter: rect.horizontalCenter
                    verticalCenter: rect.verticalCenter
                }
                style: Text.Outline; styleColor: Theme.secondaryHighlightColor
                text: "GAME OVER"
                color: Theme.highlightColor
                font.pixelSize: Theme.fontSizeHuge
                font.bold: true
                visible: !functions.garunning && opacity > 0 ? true : false
                opacity: gameOverTimer.running ? 1 : 0

                Behavior on opacity {
                    FadeAnimator {}
                }

            }
            Label {
                id: pauseLabel
                anchors {
                    horizontalCenter: rect.horizontalCenter
                    verticalCenter: rect.verticalCenter
                }
                style: Text.Outline; styleColor: Theme.secondaryHighlightColor
                text: "PAUSED"
                color: Theme.highlightColor
                font.pixelSize: Theme.fontSizeHuge
                font.bold: true
                visible: false
                states: [
                    State { when: stateVisible;
                        PropertyChanges {   target: myRect; opacity: 1.0    }
                    },
                    State { when: !stateVisible;
                        PropertyChanges {   target: myRect; opacity: 0.0    }
                    }
                ]
                transitions: Transition {
                    NumberAnimation { property: "opacity"; duration: 300}
                }
            }
            Label {
                id: infoLabel
                anchors {
                    verticalCenter: rect.verticalCenter
                    horizontalCenter: rect.horizontalCenter
                }
                width: parent.width
                wrapMode: Text.WordWrap
                horizontalAlignment: Text.AlignHCenter
                style: Text.Outline; styleColor: Theme.secondaryHighlightColor;
                color: Theme.highlightColor
                font.pixelSize: Theme.fontSizeLarge*2
                font.bold: true
                opacity: infoTimer.running ? 1 : 0

                Behavior on opacity {
                    FadeAnimator {}
                }
            }
            Timer {
                id: infoTimer
                running: false
                repeat: false
                interval: 1100
                onTriggered: {
                    infoLabel.opacity = 0
                }
            }
        }



        Rectangle {
            id: highscores
            anchors.verticalCenter: rect.verticalCenter
            anchors.horizontalCenter: rect.horizontalCenter
            width: rect.width - (rect.width/6)
            height: rect.height - (rect.height/8)+Theme.paddingSmall
            visible: splash.visible || functions.garunning || getName.visible && opacity === 0 ? false : true //!splash.visible && !getName.visible && !functions.garunning
            color: "transparent"//Theme.highlightBackgroundColor
            opacity: !visible ? 0 : 0.8

            Behavior on opacity {
                FadeAnimator {onStopped: console.log("highscores fade animation klar")}
            }

            Label {
                id: hs1
                anchors.horizontalCenter: parent.horizontalCenter
                anchors.top: parent.top
                anchors.topMargin: Theme.paddingLarge
                text: "HIGHSCORES ["+highScoreModel.game+"]"
                color: Theme.secondaryHighlightColor
                font.pixelSize: Theme.fontSizeLarge
                font.bold: true
                MouseArea {
                    anchors.fill: hs1
                    onClicked: {
                        !onlineEnabled ? onlineEnabled=true : onlineEnabled=false
                        console.log("ONLINE: "+highScoreModel.game)
                    }
                }
            }

                ListView {
                  width: parent.width; height: parent.height - hs1.height
                  enabled: true
                  anchors.top: hs1.bottom
                  anchors.left: parent.left
                  anchors.right: parent.right
                  anchors.bottom: parent.bottom
                  anchors.margins: Theme.paddingLarge
                  model: highScoreModel
                  delegate: ListItem {
                      id: showDelegate
                   //   menu: contextMenu
                      highlighted: index == highScoreModel.place-1 ? true : false
                      width: ListView.view.width
                      height: menuOpen ? contextMenu.height + pn.height + Theme.paddingSmall : pn.height + Theme.paddingSmall//contextMenu.height + contentItem.height + Theme.paddingMedium : contentItem.height + Theme.paddingMedium
                      contentHeight: pn.height + Theme.paddingSmall
                      Text {
                          id: pn
                          font.pixelSize: Theme.fontSizeLarge
                          anchors.left: parent.left
                          anchors.leftMargin: Theme.paddingMedium
                          color: Theme.highlightColor
                          text: index+(1)+"."
                      }
                      Text {
                          id: pnm
                          font.pixelSize: Theme.fontSizeLarge
                          anchors.left: pn.right
                          anchors.leftMargin: Theme.paddingMedium
                          anchors.top: pn.top
                          color: Theme.highlightColor
                          text: player
                      }
                      Text {
                          font.pixelSize: Theme.fontSizeLarge
                          anchors.right: parent.right
                          anchors.rightMargin: Theme.paddingMedium
                          anchors.top: pn.top
                          color: Theme.highlightColor
                          text: score
                      }

                  }
                }
        }

        ContextMenu {
            id: contextMenu
            width: rect.width - (rect.width/6)
            anchors.horizontalCenter: highscores.horizontalCenter
            MenuItem {
                id:onlineMenu

                visible: true
                text: qsTr("Share score online")
                onClicked: {
                    var uuid = generateUUID()
                    console.log("UUID: "+uuid)
                 /*   internal ? ps(source) : model.id == 0 ? ps(source) : cps(model.id)
                    radioStation = title
                    if (icon == "0") picon = "../allradio-data/images/allradio.png"
                    else if (icon.search(".png")>0) picon = icon.toLowerCase(); // The old save in database
                    else  picon = "../allradio-data/images/"+icon+".png";
                    website = (Qt.resolvedUrl(site)) */
                }
            }
        }

        Rectangle {
            id: splash
            anchors.verticalCenter: rect.verticalCenter
            anchors.horizontalCenter: rect.horizontalCenter
            width: rect.width - (rect.width/6)
            height: rect.height - (rect.height/8) + Theme.paddingSmall

            visible: functions.garunning || getName.visible || highscores.visible  && opacity === 0 ? false : true//true && !functions.garunning//!functions.garunning && !getName.visible && !highscores.visible//&& !gameOverTimer.done ? true : false //&& gameOverTimer.running ? done :
            color: "transparent"//Theme.highlightBackgroundColor
            opacity: !visible ? 0 : 0.8

            Behavior on opacity {
                FadeAnimator {}
            }
            Column {
                spacing: Theme.paddingLarge
                anchors {
                    horizontalCenter: splash.horizontalCenter
                    verticalCenter: splash.verticalCenter
                }
                Label {
                    id: name
                    anchors.horizontalCenter: parent.horizontalCenter
                    text: "TetraFish"
                    color: Theme.highlightColor
                    font.pixelSize: Theme.fontSizeHuge
                    font.bold: true
                }
            Image {
                anchors.horizontalCenter: parent.horizontalCenter
                id: tetraFish
                width: name.width
                height: width
                source: "../data/tetrafish.png"
            }

            Label {
                id: info1

                anchors.horizontalCenter: parent.horizontalCenter
                text: "A TETRIS clone"
                color: Theme.secondaryHighlightColor
                font.pixelSize: Theme.fontSizeLarge
                font.bold: true
            }
            Label {
                id: info2
                anchors.horizontalCenter: parent.horizontalCenter
                text: "Presented by NESNOMIS"
                color: Theme.secondaryHighlightColor
                font.pixelSize: Theme.fontSizeSmall
                font.bold: true
            }
            }
        }
        Rectangle {
            id: getName
            anchors.fill: rect
            anchors.left: rect.left
            anchors.top: rect.top
            width: rect.width
            height: rect.height

            visible: false//!functions.garunning && !gameOverTimer.done ? true : false //&& gameOverTimer.running ? done :
            color: "black"//Theme.highlightBackgroundColor
            opacity: !visible ? 0 : 0.8

            Behavior on opacity {
                FadeAnimator {}
            }

            Label {
                id: congrat
                anchors.horizontalCenter: parent.horizontalCenter
                text: "CONGRATULATIONS"//+highScoreModel.place
                color: Theme.highlightColor
                anchors.bottom: namn.top
                font.pixelSize: Theme.fontSizeExtraLarge
                font.bold: true
            }
                Label {
                    id: namn
                    anchors.horizontalCenter: parent.horizontalCenter
                    text: "You placed No. "+highScoreModel.place
                    color: Theme.primaryColor
                    anchors.bottom: textField.top
                    anchors.bottomMargin: Theme.paddingLarge * 3
                    font.pixelSize: Theme.fontSizeMedium
                    font.bold: true
                }

                TextField {
                    id: textField
                    enabled: parent.visible
                    anchors.horizontalCenter: parent.horizontalCenter
                    anchors.bottom: parent.bottom
                    width: parent.width
                    maximumLength: 8
                    focus: true
                    placeholderText: "ENTER YOUR NAME"
                    inputMethodHints: Qt.ImhUppercaseOnly | Qt.ImhPreferUppercase | Qt.ImhNoPredictiveText
                    horizontalAlignment: TextInput.AlignHCenter
                    font.bold: true
                    font.pixelSize: Theme.fontSizeHuge
                    font.capitalization: Font.AllUppercase
                    EnterKey.iconSource: "image://theme/icon-m-enter" //"image://theme/icon-m-enter-close"
                    EnterKey.onClicked: {

                        getName.visible = false
                        splash.visible = false
                        highscores.visible = true
                        pullDownMenu.enabled = true
                        root.interactive = true
                        functions.saveHighscore(text.toUpperCase(),scoreValue)
                    }
                }
        }

    }
    function generateUUID(){
        var d = new Date().getTime();
        var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            var r = (d + Math.random()*16)%16 | 0;
            d = Math.floor(d/16);
            return (c === 'x' ? r : (r&0x3|0x8)).toString(16);
        });
        return uuid;
    }

    Component.onCompleted: splash.visible = true
}