import QtQuick.Controls 1.1
import QtQuick.Controls 2.12 as QQC2
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 3.0 as PlasmaComponents3
import org.kde.plasma.extras 2.0 as PlasmaExtras
import QtGraphicalEffects 1.0
import QtQuick.Layouts 1.1

import QtQuick 2.8
import SddmComponents 2.0
import QtMultimedia 5.7


import "components"

Rectangle {
    // Main Container
    id: container

    LayoutMirroring.enabled: Qt.locale().textDirection == Qt.RightToLeft
    LayoutMirroring.childrenInherit: true

    property int sessionIndex: session.index

    // Inherited from SDDMComponents
    TextConstants {
        id: textConstants
    }

    // Set SDDM actions
    Connections {
        target: sddm
        onLoginSucceeded: {
        }

        onLoginFailed: {
            error_message.color = "#dc322f"
            error_message.text = textConstants.loginFailed
        }
    }

    // Set Font
    FontLoader {
        id: textFont; name: config.displayFont
    }

    // Background Fill
    Rectangle {
        anchors.fill: parent
        color: "black"
    }

    // Set Background Image
    Image {
        id: image1
        anchors.fill: parent
        //source: config.background
        fillMode: Image.PreserveAspectCrop
    }

    // Set Background Video1
    MediaPlayer {
        id: mediaplayer1
        autoPlay: true; muted: true
        playlist: Playlist {
            id: playlist1
            playbackMode: Playlist.Random
            onLoaded: { mediaplayer1.play() }
        }
    }

    VideoOutput {
        id: video1
        fillMode: VideoOutput.PreserveAspectCrop
        anchors.fill: parent; source: mediaplayer1
        MouseArea {
            id: mouseArea1
            anchors.fill: parent;
            //onPressed: {playlist1.shuffle(); playlist1.next();}
            onPressed: {
                fader1.state = fader1.state == "off" ? "on" : "off" ;
                if (config.autofocusInput == "true") {
                    if (username_input_box.text == "")
                        username_input_box.focus = true
                    else
                        password_input_box.focus = true
                }
            }
        }
        Keys.onPressed: {
            fader1.state = "on";
            if (username_input_box.text == "")
                username_input_box.focus = true
            else
                password_input_box.focus = true
        }
    }
    WallpaperFader {
        id: fader1
        visible: true
        anchors.fill: parent
        state: "off"
        source: video1
        mainStack: login_container
        footer: login_container
    }

    // Set Background Video2
    MediaPlayer {
        id: mediaplayer2
        autoPlay: true; muted: true
        playlist: Playlist {
            id: playlist2; playbackMode: Playlist.Random
            //onLoaded: { mediaplayer2.play() }
        }
    }

    VideoOutput {
        id: video2
        fillMode: VideoOutput.PreserveAspectCrop
        anchors.fill: parent; source: mediaplayer2
        opacity: 0
        MouseArea {
            id: mouseArea2
            enabled: false
            anchors.fill: parent;
            onPressed: {
                fader1.state = fader1.state == "off" ? "on" : "off" ;
                if (config.autofocusInput == "true") {
                    if (username_input_box.text == "")
                        username_input_box.focus = true
                    else
                        password_input_box.focus = true
                }
            }
        }
        Behavior on opacity {
            enabled: true
            NumberAnimation { easing.type: Easing.InOutQuad; duration: 3000 }
        }
        Keys.onPressed: {
            fader2.state = "on";
            if (username_input_box.text == "")
                username_input_box.focus = true
            else
                password_input_box.focus = true
        }
    }

    WallpaperFader {
        id: fader2
        visible: true
        anchors.fill: parent
        state: "off"
        source: video2
        mainStack: login_container
        footer: login_container
    }

    property MediaPlayer currentPlayer: mediaplayer1

    // Timer event to handle fade between videos
    Timer {
        interval: 1000;
        running: true; repeat: true
        onTriggered: {
            if (currentPlayer.duration != -1 && currentPlayer.position > currentPlayer.duration - 10000) { // pre load the 2nd player
                if (video2.opacity == 0) { // toogle opacity
                    mediaplayer2.play()
                } else
                    mediaplayer1.play()
            }
            if (currentPlayer.duration != -1 && currentPlayer.position > currentPlayer.duration - 3000) { // initiate transition
                if (video2.opacity == 0) { // toogle opacity
                    mouseArea1.enabled = false
                    currentPlayer = mediaplayer2
                    video2.opacity = 1
                    triggerTimer.start()
                    mouseArea2.enabled = true
                } else {
                    mouseArea2.enabled = false
                    currentPlayer = mediaplayer1
                    video2.opacity = 0
                    triggerTimer.start()
                    mouseArea1.enabled = true
                }
            }
        }
    }

    Timer { // this timer waits for fade to stop and stops the video
        id: triggerTimer
        interval: 4000; running: false; repeat: false
        onTriggered: {
            if (video2.opacity == 1)
                mediaplayer1.stop()
            else
                mediaplayer2.stop()
        }
    }



    // Clock and Login Area
    Rectangle {
        id: rectangle
        anchors.fill: parent
        color: "transparent"

        MouseArea {
            id: loginScreenRoot
            anchors.fill: parent

            property bool uiVisible: true
            property bool blockUI: mainStack.depth > 1 || userListComponent.mainPasswordBox.text.length > 0 || inputPanel.keyboardActive || config.type !== "image"

            hoverEnabled: true
            drag.filterChildren: true
            onPressed: uiVisible = true;
            onPositionChanged: uiVisible = true;
            onUiVisibleChanged: {
                if (blockUI) {
                    fadeoutTimer.running = false;
                } else if (uiVisible) {
                    fadeoutTimer.restart();
                }
            }
            onBlockUIChanged: {
                if (blockUI) {
                    fadeoutTimer.running = false;
                    uiVisible = true;
                } else {
                    fadeoutTimer.restart();
                }
            }

            Keys.onPressed: {
                uiVisible = true;
                event.accepted = false;
            }

            //takes one full minute for the ui to disappear
            Timer {
                id: fadeoutTimer
                running: true
                interval: 60000
                onTriggered: {
                    if (!loginScreenRoot.blockUI) {
                        loginScreenRoot.uiVisible = false;
                    }
                }
            }

            QQC2.StackView {
                id: mainStack
                anchors.fill: parent
                height: root.height + PlasmaCore.Units.gridUnit * 3

                // If true (depends on the style and environment variables), hover events are always accepted
                // and propagation stopped. This means the parent MouseArea won't get them and the UI won't be shown.
                // Disable capturing those events while the UI is hidden to avoid that, while still passing events otherwise.
                // One issue is that while the UI is visible, mouse activity won't keep resetting the timer, but when it
                // finally expires, the next event should immediately set uiVisible = true again.
                hoverEnabled: loginScreenRoot.uiVisible ? undefined : false

                focus: true //StackView is an implicit focus scope, so we need to give this focus so the item inside will have it

                Timer {
                    //SDDM has a bug in 0.13 where even though we set the focus on the right item within the window, the window doesn't have focus
                    //it is fixed in 6d5b36b28907b16280ff78995fef764bb0c573db which will be 0.14
                    //we need to call "window->activate()" *After* it's been shown. We can't control that in QML so we use a shoddy timer
                    //it's been this way for all Plasma 5.x without a huge problem
                    running: true
                    repeat: false
                    interval: 200
                    onTriggered: mainStack.forceActiveFocus()
                }

                initialItem: Login {
                    id: userListComponent
                    userListModel: userModel
                    loginScreenUiVisible: loginScreenRoot.uiVisible
                    userListCurrentIndex: userModel.lastIndex >= 0 ? userModel.lastIndex : 0
                    lastUserName: userModel.lastUser
                    showUserList: {
                        if ( !userListModel.hasOwnProperty("count")
                        || !userListModel.hasOwnProperty("disableAvatarsThreshold"))
                            return (userList.y + mainStack.y) > 0

                        if ( userListModel.count === 0 ) return false

                        if ( userListModel.hasOwnProperty("containsAllUsers") && !userListModel.containsAllUsers ) return false

                        return userListModel.count <= userListModel.disableAvatarsThreshold && (userList.y + mainStack.y) > 0
                    }

                    notificationMessage: {
                        var text = ""
                        if (keystateSource.data["Caps Lock"]["Locked"]) {
                            text += i18nd("plasma_lookandfeel_org.kde.lookandfeel","Caps Lock is on")
                            if (root.notificationMessage) {
                                text += " • "
                            }
                        }
                        text += root.notificationMessage
                        return text
                    }

                    onLoginRequest: {
                        root.notificationMessage = ""
                        sddm.login(username, password, sessionButton.currentIndex)
                    }
                }

                Behavior on opacity {
                    OpacityAnimator {
                        duration: PlasmaCore.Units.longDuration
                    }
                }

                readonly property real zoomFactor: 3

                popEnter: Transition {
                    ScaleAnimator {
                        from: mainStack.zoomFactor
                        to: 1
                        duration: PlasmaCore.Units.longDuration * (mainStack.zoomFactor / 2)
                        easing.type: Easing.OutCubic
                    }
                    OpacityAnimator {
                        from: 0
                        to: 1
                        duration: PlasmaCore.Units.longDuration * (mainStack.zoomFactor / 2)
                        easing.type: Easing.OutCubic
                    }
                }

                popExit: Transition {
                    ScaleAnimator {
                        from: 1
                        to: 0
                        duration: PlasmaCore.Units.longDuration * (mainStack.zoomFactor / 2)
                        easing.type: Easing.OutCubic
                    }
                    OpacityAnimator {
                        from: 1
                        to: 0
                        duration: PlasmaCore.Units.longDuration * (mainStack.zoomFactor / 2)
                        easing.type: Easing.OutCubic
                    }
                }

                pushEnter: Transition {
                    ScaleAnimator {
                        from: 0
                        to: 1
                        duration: PlasmaCore.Units.longDuration * (mainStack.zoomFactor / 2)
                        easing.type: Easing.OutCubic
                    }
                    OpacityAnimator {
                        from: 0
                        to: 1
                        duration: PlasmaCore.Units.longDuration * (mainStack.zoomFactor / 2)
                        easing.type: Easing.OutCubic
                    }
                }

                pushExit: Transition {
                    ScaleAnimator {
                        from: 1
                        to: mainStack.zoomFactor
                        duration: PlasmaCore.Units.longDuration * (mainStack.zoomFactor / 2)
                        easing.type: Easing.OutCubic
                    }
                    OpacityAnimator {
                        from: 1
                        to: 0
                        duration: PlasmaCore.Units.longDuration * (mainStack.zoomFactor / 2)
                        easing.type: Easing.OutCubic
                    }
                }
            }

            Loader {
                id: inputPanel
                state: "hidden"
                property bool keyboardActive: item ? item.active : false
                onKeyboardActiveChanged: {
                    if (keyboardActive) {
                        state = "visible"
                        // Otherwise the password field loses focus and virtual keyboard
                        // keystrokes get eaten
                        userListComponent.mainPasswordBox.forceActiveFocus();
                    } else {
                        state = "hidden";
                    }
                }

                source: Qt.platform.pluginName.includes("wayland") ? "components/VirtualKeyboard_wayland.qml" : "components/VirtualKeyboard.qml"
                anchors {
                    left: parent.left
                    right: parent.right
                }

                function showHide() {
                    state = state == "hidden" ? "visible" : "hidden";
                }

                states: [
                    State {
                        name: "visible"
                        PropertyChanges {
                            target: mainStack
                            y: Math.min(0, root.height - inputPanel.height - userListComponent.visibleBoundary)
                        }
                    },
                    State {
                        name: "hidden"
                        PropertyChanges {
                            target: mainStack
                            y: 0
                        }
                    }
                ]
                transitions: [
                    Transition {
                        from: "hidden"
                        to: "visible"
                        SequentialAnimation {
                            ParallelAnimation {
                                NumberAnimation {
                                    target: mainStack
                                    property: "y"
                                    duration: PlasmaCore.Units.longDuration
                                    easing.type: Easing.InOutQuad
                                }
                            }
                        }
                    },
                    Transition {
                        from: "visible"
                        to: "hidden"
                        SequentialAnimation {
                            ParallelAnimation {
                                NumberAnimation {
                                    target: mainStack
                                    property: "y"
                                    duration: PlasmaCore.Units.longDuration
                                    easing.type: Easing.InOutQuad
                                }
                            }
                        }
                    }
                ]
            }


            Component {
                id: userPromptComponent
                Login {
                    showUsernamePrompt: true
                    notificationMessage: root.notificationMessage
                    loginScreenUiVisible: loginScreenRoot.uiVisible
                    fontSize: parseInt(config.fontSize) + 2

                    // using a model rather than a QObject list to avoid QTBUG-75900
                    userListModel: ListModel {
                        ListElement {
                            name: ""
                            iconSource: ""
                        }
                        Component.onCompleted: {
                            // as we can't bind inside ListElement
                            setProperty(0, "name", i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Type in Username and Password"));
                        }
                    }

                    onLoginRequest: {
                        root.notificationMessage = ""
                        sddm.login(username, password, sessionButton.currentIndex)
                    }

                }
            }

            DropShadow {
                id: logoShadow
                anchors.fill: logo
                source: logo
                visible: !softwareRendering && config.showlogo == "shown"
                horizontalOffset: 1
                verticalOffset: 1
                radius: 6
                samples: 14
                spread: 0.3
                color : "black" // shadows should always be black
                opacity: loginScreenRoot.uiVisible ? 0 : 1
                Behavior on opacity {
                    //OpacityAnimator when starting from 0 is buggy (it shows one frame with opacity 1)"
                    NumberAnimation {
                        duration: PlasmaCore.Units.longDuration
                        easing.type: Easing.InOutQuad
                    }
                }
            }

            Image {
                id: logo
                visible: config.showlogo == "shown"
                source: config.logo
                anchors.horizontalCenter: parent.horizontalCenter
                anchors.bottom: footer.top
                anchors.bottomMargin: PlasmaCore.Units.largeSpacing
                asynchronous: true
                sourceSize.height: height
                opacity: loginScreenRoot.uiVisible ? 0 : 1
                fillMode: Image.PreserveAspectFit
                height: Math.round(PlasmaCore.Units.gridUnit * 3.5)
                Behavior on opacity {
                    // OpacityAnimator when starting from 0 is buggy (it shows one frame with opacity 1)"
                    NumberAnimation {
                        duration: PlasmaCore.Units.longDuration
                        easing.type: Easing.InOutQuad
                    }
                }
            }

            //Footer
            RowLayout {
                id: footer
                anchors {
                    bottom: parent.bottom
                    left: parent.left
                    right: parent.right
                    margins: PlasmaCore.Units.smallSpacing
                }

                Behavior on opacity {
                    OpacityAnimator {
                        duration: PlasmaCore.Units.longDuration
                    }
                }

                PlasmaComponents3.ToolButton {
                    text: i18ndc("plasma_lookandfeel_org.kde.lookandfeel", "Button to show/hide virtual keyboard", "Virtual Keyboard")
                    font.pointSize: config.fontSize
                    icon.name: inputPanel.keyboardActive ? "input-keyboard-virtual-on" : "input-keyboard-virtual-off"
                    onClicked: inputPanel.showHide()
                    visible: inputPanel.status == Loader.Ready
                }

                KeyboardButton {
                    font.pointSize: config.fontSize
                }

                SessionButton {
                    id: sessionButton
                    font.pointSize: config.fontSize
                }

                Item {
                    Layout.fillWidth: true
                }

                Battery {
                    fontSize: config.fontSize
                }
            }
        }

        Clock {
            id: clock
            y: parent.height * config.relativePositionY - clock.height / 2
            x: parent.width * config.relativePositionX - clock.width / 2
        }

        Rectangle {
            id: login_container

            //y: parent.height * 0.8
            y: clock.y + clock.height + 30
            width: clock.width
            height: parent.height * 0.08
            color: "transparent"
            anchors.left: clock.left

            Rectangle {
                id: username_row
                height: parent.height * 0.36
                color: "transparent"
                anchors.left: parent.left
                anchors.leftMargin: 0
                anchors.right: parent.right
                anchors.rightMargin: 0
                transformOrigin: Item.Center
                anchors.margins: 10

                Text {
                    id: username_label
                    width: parent.width * 0.27
                    height: parent.height * 0.66
                    horizontalAlignment: Text.AlignLeft
                    font.family: textFont.name
                    font.bold: true
                    font.pixelSize: 16
                    color: "white"
                    text: "Username"
                    anchors.verticalCenter: parent.verticalCenter
                }

                TextBox {
                    id: username_input_box
                    height: parent.height
                    text: userModel.lastUser
                    anchors.verticalCenter: parent.verticalCenter
                    anchors.left: username_label.right
                    anchors.leftMargin: config.usernameLeftMargin
                    anchors.right: parent.right
                    anchors.rightMargin: 0
                    font: textFont.name
                    color: "#25000000"
                    borderColor: "transparent"
                    textColor: "white"

                    Keys.onPressed: {
                        if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
                            sddm.login(username_input_box.text, password_input_box.text, session.index)
                            event.accepted = true
                        }
                    }

                    KeyNavigation.backtab: password_input_box
                    KeyNavigation.tab: password_input_box
                }
            }

            Rectangle {
                id: password_row
                y: username_row.height + 10
                height: parent.height * 0.36
                color: "transparent"
                anchors.right: parent.right
                anchors.rightMargin: 0
                anchors.left: parent.left
                anchors.leftMargin: 0

                Text {
                    id: password_label
                    width: parent.width * 0.27
                    text: textConstants.password
                    anchors.verticalCenter: parent.verticalCenter
                    horizontalAlignment: Text.AlignLeft
                    font.family: textFont.name
                    font.bold: true
                    font.pixelSize: 16
                    color: "white"
                }

                PasswordBox {
                    id: password_input_box
                    height: parent.height
                    font: textFont.name
                    color: "#25000000"
                    anchors.verticalCenter: parent.verticalCenter
                    anchors.right: parent.right
                    anchors.rightMargin: parent.height // this sets button width, this way its a square
                    anchors.left: password_label.right
                    anchors.leftMargin: config.passwordLeftMargin
                    borderColor: "transparent"
                    textColor: "white"
                    tooltipBG: "#25000000"
                    tooltipFG: "#dc322f"
                    image: "components/resources/warning_red.png"
                    onTextChanged: {
                        if (password_input_box.text == "") {
                            clear_passwd_button.visible = false
                        }
                        if (password_input_box.text != "" && config.showClearPasswordButton != "false") {
                            clear_passwd_button.visible = true
                        }
                    }

                    Keys.onPressed: {
                        if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
                            sddm.login(username_input_box.text, password_input_box.text, session.index)
                            event.accepted = true
                        }
                    }

                    KeyNavigation.backtab: username_input_box
                    KeyNavigation.tab: login_button
                }

                Button {
                    id: clear_passwd_button
                    height: parent.height
                    width: parent.height
                    color: "transparent"
                    text: "x"
                    font: textFont.name

                    border.color: "transparent"
                    border.width: 0
                    anchors.verticalCenter: parent.verticalCenter
                    anchors.right: parent.right
                    anchors.leftMargin: 0
                    anchors.rightMargin: parent.height

                    disabledColor: "#dc322f"
                    activeColor: "#393939"
                    pressedColor: "#2aa198"

                    onClicked: {
                        password_input_box.text=''
                        password_input_box.focus = true
                    }
                }

                Button {
                    id: login_button
                    height: parent.height
                    color: "#393939"
                    text: ">"
                    border.color: "#00000000"
                    anchors.verticalCenter: parent.verticalCenter
                    anchors.left: password_input_box.right
                    anchors.right: parent.right
                    disabledColor: "#dc322f"
                    activeColor: "#268bd2"
                    pressedColor: "#2aa198"
                    textColor: "white"
                    font: textFont.name

                    onClicked: sddm.login(username_input_box.text, password_input_box.text, session.index)

                    KeyNavigation.backtab: password_input_box
                    KeyNavigation.tab: reboot_button
                }

                Text {
                    id: error_message
                    height: parent.height
                    font.family: textFont.name
                    font.pixelSize: 12
                    color: "white"
                    anchors.top: password_input_box.bottom
                    anchors.left: password_input_box.left
                    anchors.leftMargin: 0
                }
            }

        }
    }

    Component.onCompleted: {
        // Set Focus
        /* if (username_input_box.text == "") */
        /*     username_input_box.focus = true */
        /* else */
        /*     password_input_box.focus = true */

        video1.focus = true

        // load and randomize playlist
        var time = parseInt(new Date().toLocaleTimeString(Qt.locale(),'h'))
        if ( time >= 5 && time <= 17 ) {
            playlist1.load(Qt.resolvedUrl(config.background_vid_day), 'm3u')
            playlist2.load(Qt.resolvedUrl(config.background_vid_day), 'm3u')
            image1.source = config.background_img_day
        } else {
            playlist1.load(Qt.resolvedUrl(config.background_vid_night), 'm3u')
            playlist2.load(Qt.resolvedUrl(config.background_vid_night), 'm3u')
            image1.source = config.background_img_night
        }

        for (var k = 0; k < Math.ceil(Math.random() * 10) ; k++) {
            playlist1.shuffle()
            playlist2.shuffle()
        }

        if (config.showLoginButton == "false") {
            login_button.visible = false
            password_input_box.anchors.rightMargin = 0
            clear_passwd_button.anchors.rightMargin = 0
        }
        clear_passwd_button.visible = false
    }
}
