// Copyright (c) 2020 Proton Technologies AG
//
// This file is part of ProtonMail Bridge.
//
// ProtonMail Bridge 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.
//
// ProtonMail Bridge 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 ProtonMail Bridge.  If not, see <https://www.gnu.org/licenses/>.

// This is main window

import QtQuick 2.8
import QtQuick.Window 2.2
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.3
import ImportExportUI 1.0
import ProtonUI 1.0


// Main Window
Window {
    id                               : root
    property alias tabbar            : tabbar
    property alias viewContent       : viewContent
    property alias viewAccount       : viewAccount
    property alias dialogAddUser     : dialogAddUser
    property alias dialogGlobal      : dialogGlobal
    property alias dialogCredits     : dialogCredits
    property alias dialogVersionInfo : dialogVersionInfo
    property alias dialogUpdate      : dialogUpdate
    property alias popupMessage      : popupMessage
    property alias popupFolderEdit   : popupFolderEdit
    property alias updateState       : infoBar.state
    property alias dialogExport      : dialogExport
    property alias dialogImport      : dialogImport
    property alias addAccountTip     : addAccountTip
    property int   heightContent     : height-titleBar.height

    property real   innerWindowBorder   : go.goos=="darwin" ? 0 : Style.main.border

    // main window appearance
    width  : Style.main.width
    height : Style.main.height
    flags  : go.goos=="darwin" ? Qt.Window : Qt.Window | Qt.FramelessWindowHint
    color: go.goos=="windows" ? Style.main.background : Style.transparent
    title: go.programTitle

    minimumWidth  : Style.main.width
    minimumHeight : Style.main.height

    property bool isOutdateVersion : root.updateState == "forceUpgrade"

    property bool activeContent :
    !dialogAddUser     .visible &&
    !dialogCredits     .visible &&
    !dialogVersionInfo .visible &&
    !dialogGlobal      .visible &&
    !dialogUpdate      .visible &&
    !dialogImport      .visible &&
    !dialogExport      .visible &&
    !popupFolderEdit   .visible &&
    !popupMessage      .visible

    Accessible.role: Accessible.Grouping
    Accessible.description: qsTr("Window %1").arg(title)
    Accessible.name: Accessible.description

    WindowTitleBar {
        id: titleBar
        window: root
        visible: go.goos!="darwin"
    }

    Rectangle {
        anchors {
            top   : titleBar.bottom
            left  : parent.left
            right : parent.right
            bottom : parent.bottom
        }
        color: Style.title.background
    }

    InformationBar {
        id: infoBar
        anchors {
            left  : parent.left
            right : parent.right
            top   : titleBar.bottom
            leftMargin: innerWindowBorder
            rightMargin: innerWindowBorder
        }
    }

    TabLabels  {
        id: tabbar
        currentIndex : 0
        enabled: root.activeContent
        anchors {
            top   : infoBar.bottom
            right : parent.right
            left  : parent.left
            leftMargin: innerWindowBorder
            rightMargin: innerWindowBorder
        }
        model: [
            { "title" : qsTr("Import-Export" , "title of tab that shows account list"             ), "iconText": Style.fa.home      },
            { "title" : qsTr("Settings"      , "title of tab that allows user to change settings" ), "iconText": Style.fa.cogs      },
            { "title" : qsTr("Help"          , "title of tab that shows the help menu"            ), "iconText": Style.fa.life_ring }
        ]
    }

    // Content of tabs
    StackLayout  {
        id: viewContent
        enabled: root.activeContent
        // dimensions
        anchors {
            left   : parent.left
            right  : parent.right
            top    : tabbar.bottom
            bottom : parent.bottom
            leftMargin: innerWindowBorder
            rightMargin: innerWindowBorder
            bottomMargin: innerWindowBorder
        }
        // attributes
        currentIndex : { return root.tabbar.currentIndex}
        clip         : true
        // content
        AccountView  {
            id           : viewAccount
            onAddAccount : dialogAddUser.show()
            model        : accountsModel
            hasFooter    : false
            delegate     : AccountDelegate {
                row_width : viewContent.width
            }
        }
        SettingsView { id: viewSettings; }
        HelpView     { id: viewHelp;     }
    }


    // Bubble prevent action
    Rectangle {
        anchors {
            left: parent.left
            right: parent.right
            top: titleBar.bottom
            bottom: parent.bottom
        }
        visible: bubbleNote.visible
        color: "#aa222222"
        MouseArea {
            anchors.fill: parent
            hoverEnabled: true
        }
    }
    BubbleNote {
        id      : bubbleNote
        visible : false
        Component.onCompleted : {
            bubbleNote.place(0)
        }
    }

    BubbleNote {
        id:addAccountTip
        anchors.topMargin: viewAccount.separatorNoAccount - 2*Style.main.fontSize
        text : qsTr("Click here to start", "on first launch, this is displayed above the Add Account button to tell the user what to do first")
        state: (go.isFirstStart && viewAccount.numAccounts==0 && root.viewContent.currentIndex==0) ? "Visible" : "Invisible"
        bubbleColor: Style.main.textBlue

        Component.onCompleted : {
            addAccountTip.place(-1)
        }
        enabled: false

        states: [
            State {
                name: "Visible"
                // hack: opacity 100% makes buttons dialog windows quit wrong color
                PropertyChanges{target: addAccountTip; opacity: 0.999; visible: true}
            },
            State {
                name: "Invisible"
                PropertyChanges{target: addAccountTip; opacity: 0.0; visible: false}
            }
        ]

        transitions: [
            Transition {
                from: "Visible"
                to: "Invisible"

                SequentialAnimation{
                    NumberAnimation {
                        target: addAccountTip
                        property: "opacity"
                        duration: 0
                        easing.type: Easing.InOutQuad
                    }
                    NumberAnimation {
                        target: addAccountTip
                        property: "visible"
                        duration: 0
                    }
                }
            },
            Transition {
                from: "Invisible"
                to: "Visible"
                SequentialAnimation{
                    NumberAnimation {
                        target: addAccountTip
                        property: "visible"
                        duration: 300
                    }
                    NumberAnimation {
                        target: addAccountTip
                        property: "opacity"
                        duration: 500
                        easing.type: Easing.InOutQuad
                    }
                }
            }
        ]
    }


    // Dialogs

    DialogAddUser {
        id: dialogAddUser

        anchors {
            top   : infoBar.bottom
            bottomMargin: innerWindowBorder
            leftMargin: innerWindowBorder
            rightMargin: innerWindowBorder
        }

        onCreateAccount: Qt.openUrlExternally("https://protonmail.com/signup")
    }

    DialogUpdate {
        id: dialogUpdate

        title: root.isOutdateVersion ?
        qsTr("%1 is outdated", "title of outdate dialog").arg(go.programTitle):
        qsTr("%1 update to %2", "title of update dialog").arg(go.programTitle).arg(go.newversion)
        introductionText: {
            if (root.isOutdateVersion) {
                if (go.goos=="linux") {
                    return qsTr('You are using an outdated version of our software.<br>
                    Please dowload and install the latest version to continue using %1.<br><br>
                    <a href="%2">%2</a>',
                    "Message for force-update in Linux").arg(go.programTitle).arg(go.landingPage)
                } else {
                    return qsTr('You are using an outdated version of our software.<br>
                    Please dowload and install the latest version to continue using %1.<br><br>
                    You can continue with update or download and install the new version manually from<br><br>
                    <a href="%2">%2</a>',
                    "Message for force-update in Win/Mac").arg(go.programTitle).arg(go.landingPage)
                }
            } else {
                if (go.goos=="linux") {
                    return qsTr('A new version of %1 is available.<br>
                    Check <a href="%2">release notes</a> to learn what is new in %3.<br>
                    Use your package manager to update or download and install new the version manually from<br><br>
                    <a href="%4">%4</a>',
                    "Message for update in Linux").arg(go.programTitle).arg("releaseNotes").arg(go.newversion).arg(go.landingPage)
                } else {
                    return qsTr('A new version of %1 is available.<br>
                    Check <a href="%2">release notes</a> to learn what is new in %3.<br>
                    You can continue with update or download and install new the version manually from<br><br>
                    <a href="%4">%4</a>',
                    "Message for update in Win/Mac").arg(go.programTitle).arg("releaseNotes").arg(go.newversion).arg(go.landingPage)
                }
            }
        }
    }


    DialogExport {
        id: dialogExport
        anchors {
            top   : infoBar.bottom
            bottomMargin: innerWindowBorder
            leftMargin: innerWindowBorder
            rightMargin: innerWindowBorder
        }

    }

    DialogImport {
        id: dialogImport
        anchors {
            top   : infoBar.bottom
            bottomMargin: innerWindowBorder
            leftMargin: innerWindowBorder
            rightMargin: innerWindowBorder
        }

    }

    Dialog {
        id: dialogCredits
        anchors {
            top   : infoBar.bottom
            bottomMargin: innerWindowBorder
            leftMargin: innerWindowBorder
            rightMargin: innerWindowBorder
        }

        title: qsTr("Credits", "title for list of credited libraries")

        Credits { }
    }

    Dialog {
        id: dialogVersionInfo
        anchors {
            top   : infoBar.bottom
            bottomMargin: innerWindowBorder
            leftMargin: innerWindowBorder
            rightMargin: innerWindowBorder
        }
        property bool checkVersion : false
        title: qsTr("Information about", "title of release notes page") + " v" + go.newversion
        VersionInfo { }
        onShow : {
            // Hide information bar with olde version
            if ( infoBar.state=="oldVersion" ) {
                infoBar.state="upToDate"
                dialogVersionInfo.checkVersion = true
            }
        }
        onHide : {
            // Reload current version based on online status
            if (dialogVersionInfo.checkVersion) go.runCheckVersion(false)
            dialogVersionInfo.checkVersion = false
        }
    }

    DialogYesNo {
        id: dialogGlobal
        question : ""
        answer   : ""
        z: 100
    }

    PopupEditFolder {
        id: popupFolderEdit
        anchors {
            left: parent.left
            right: parent.right
            top: infoBar.bottom
            bottom: parent.bottom
        }
    }

    // Popup
    PopupMessage {
        id: popupMessage
        anchors {
            left   : parent.left
            right  : parent.right
            top    : infoBar.bottom
            bottom : parent.bottom
        }

        onClickedNo: popupMessage.hide()
        onClickedOkay: popupMessage.hide()
        onClickedCancel: popupMessage.hide()
        onClickedYes: {
            if (popupMessage.text == gui.areYouSureYouWantToQuit) Qt.quit()
        }
    }

    // resize
    MouseArea { // bottom
        id: resizeBottom
        property int diff: 0
        anchors {
            bottom : parent.bottom
            left   : parent.left
            right  : parent.right
        }
        cursorShape: Qt.SizeVerCursor
        height: Style.main.fontSize
        onPressed: {
            var globPos = mapToGlobal(mouse.x, mouse.y)
            resizeBottom.diff = root.height
            resizeBottom.diff -= globPos.y
        }
        onMouseYChanged : {
            var globPos = mapToGlobal(mouse.x, mouse.y)
            root.height =  Math.max(root.minimumHeight, globPos.y + resizeBottom.diff)
        }
    }

    MouseArea { // right
        id: resizeRight
        property int diff: 0
        anchors {
            top    : titleBar.bottom
            bottom : parent.bottom
            right  : parent.right
        }
        cursorShape: Qt.SizeHorCursor
        width: Style.main.fontSize/2
        onPressed: {
            var globPos = mapToGlobal(mouse.x, mouse.y)
            resizeRight.diff = root.width
            resizeRight.diff -= globPos.x
        }
        onMouseXChanged : {
            var globPos = mapToGlobal(mouse.x, mouse.y)
            root.width =  Math.max(root.minimumWidth, globPos.x + resizeRight.diff)
        }
    }

    function showAndRise(){
        go.loadAccounts()
        root.show()
        root.raise()
        if (!root.active) {
            root.requestActivate()
        }
    }

    // Toggle window
    function toggle() {
        go.loadAccounts()
        if (root.visible) {
            if (!root.active) {
                root.raise()
                root.requestActivate()
            } else {
                root.hide()
            }
        } else {
            root.show()
            root.raise()
        }
    }

    onClosing : {
        close.accepted=false
        if (
            (dialogImport.visible && dialogImport.currentIndex == 4 && go.progress!=1) ||
            (dialogExport.visible && dialogExport.currentIndex == 2 && go.progress!=1)
        ) {
            popupMessage.buttonOkay   .visible = false
            popupMessage.buttonYes    .visible = false
            popupMessage.buttonQuit   .visible = true
            popupMessage.buttonCancel .visible = true
            popupMessage.show ( gui.areYouSureYouWantToQuit )
            return
        }

        close.accepted=true
        go.processFinished()
    }
}
