import QtQuick 2.6
import QtQuick.Controls 1.4
import QtQuick.Controls 2.0 as NewControls
import QtQuick.Layouts 1.1
import TaskManager 1.0
import QtCharts 2.2

import QtQuick.Window 2.13

ApplicationWindow {
    id: root
    visible: true
    width: container.width * container.scale
    height: container.height * container.scale
    flags: Qt.Window | Qt.FramelessWindowHint

    TaskManager {
        id: taskmgr

        onUpdateProcess: {
            var index = findId(tid_);
            libraryModel.set(index, {"cmd": cmd_, "tid": tid_, "user": euid_, "system_cpu": scpu_,
                                     "user_cpu": ucpu_, "resident_memory": resident_memory_, "state": state_});
        }

        onAddProcess: {
            libraryModel.append({"cmd": cmd_, "tid": tid_, "user": euid_, "system_cpu": scpu_,
                                 "user_cpu": ucpu_, "resident_memory": resident_memory_, "state": state_});
        }

        onRemoveProcess: {
            var index = findId(tid_);
            libraryModel.remove(index);
        }

        function findId(tid) {
            for(var i = 0; i < libraryModel.count; i++) {
                if(tid === libraryModel.get(i).tid) {
                      return i;
                  }
            }
        }

        Component.onCompleted: {
            taskmgr.open(bindingAddress);
        }

        onShowProcessInfo: {
            mainTabview.getTab(0).item.updateInfo(info_);
        }

        onUpdateLoadAverage: {
            mainTabview.getTab(1).item.updateLoadChart(value_);
        }

        onUpdateNetworkStats: {
            mainTabview.getTab(1).item.updateNetChart(in_, out_);
        }
    }

    ListModel {
        id: libraryModel
    }

    Item {
        id: container
        anchors.centerIn: parent
        width: Screen.width
        height: Screen.height
        //scale: screenInfo.scale_factor()
        scale: 1

    TabView {
        id: mainTabview
        currentIndex: 0
        anchors.fill: parent

        Tab {
            id: processesTab
            active: true
            anchors.fill: parent

            title: "Processes"

            Rectangle {
                id: procsView
                width: parent.width
                height: parent.height

                function updateInfo(info_)
                {
                    infoPopup.infoText = info_;
                }

                Row {
                    id: buttonRow
                    width: parent.width

                    RowLayout {
                        id: buttonRowLayout

                        NewControls.Popup {
                            id: infoPopup
                            x: 400 * container.scale
                            y: 400 * container.scale
                            width: 300
                            height: 200
                            modal: true
                            focus: true
                            closePolicy: NewControls.Popup.CloseOnPressOutsideParent
                            property var infoText: "Getting extra information for process"
                            function doOpen(tid) {
                                taskmgr.getExtraInfo(tid)
                                infoPopup.open()
                            }
                            contentItem: Text {
                                text: infoPopup.infoText
                            }
                        }

                        Button {
                            id: infoButton
                            text: "Info"
                            enabled: tableView.currentRow != -1
                            onClicked: infoPopup.doOpen(libraryModel.get(tableView.currentRow).tid)
                        }

                        Button {
                            id: killButton
                            text: "Kill"
                            enabled: tableView.currentRow != -1
                            onClicked: {
                                tableView.selection.forEach( function(rowIndex) {
                                    taskmgr.kill(libraryModel.get(rowIndex).tid)}
                                )
                                tableView.selection.clear()
                            }
                        }
                    }
                }

                TableView {
                    id: tableView
                    height: parent.height - buttonRow.height
                    width: parent.width
                    anchors.top: buttonRow.bottom

                    TableViewColumn {
                        role: "cmd"
                        title: "Process"
                        width: 200 * container.scale
                    }
                    TableViewColumn {
                        role: "tid"
                        title: "ID"
                        width: 100 * container.scale
                    }
                    TableViewColumn {
                        role: "user"
                        title: "User"
                        width: 120 * container.scale
                    }
                    TableViewColumn {
                        role: "system_cpu"
                        title: "System %"
                        width: 160 * container.scale
                    }
                    TableViewColumn {
                        role: "user_cpu"
                        title: "User %"
                        width: 160 * container.scale
                    }
                    TableViewColumn {
                        role: "resident_memory"
                        title: "Memory"
                        width: 160 * container.scale
                    }
                    TableViewColumn {
                        role: "state"
                        title: "State"
                        width: 80 * container.scale
                    }
                    model: libraryModel
                }
            }
        }

        Tab {
            id: systemTab
            active: true
            anchors.fill: parent
            title: "System"

            Rectangle {
                id: graphsView
                width: parent.width
                height: parent.height

                function updateLoadChart(value_)
                {
                    loadChart.tempAdd(value_)
                }
                function updateNetChart(in_, out_)
                {
                    networkChart.updateStats(in_, out_)
                }

                ChartView {
                     id: loadChart
                     title: "System load average"
                     width: parent.width
                     height: parent.height / 3
                     legend.visible: false
                     antialiasing: true

                    LineSeries {
                        id: loadSeries

                        axisX: DateTimeAxis {
                            id: timeLoadAxis
                            labelsVisible: false
                            format: "hh:mm"
                        }

                        axisY: ValueAxis {
                            id: valueAxis
                            max: 2
                            min: 0
                            tickCount: 3
                        }

                        XYPoint { x: new Date().getTime(); y: 0 }
                        XYPoint { x: (new Date().getTime()+ 10); y: 0 }
                    }
                    function tempAdd(value_)
                    {
                        var time_ = new Date();

                        if (value_ > valueAxis.max)
                            valueAxis.max = value_;

                        loadSeries.append(time_.getTime(), value_);
                        timeLoadAxis.max = time_;

                        if (loadSeries.count > 1800)
                        {
                            loadSeries.remove(0);
                            time_.setMinutes(time_.getMinutes() - 30);
                            timeLoadAxis.min = time_;
                        }

                        loadChart.update();
                    }
                }
                ChartView {
                    id: networkChart
                    title: "Network Stats and Charts"
                    width: parent.width
                    height: parent.height / 3
                    legend.visible: true
                    antialiasing: true
                    anchors.top: loadChart.bottom

                    DateTimeAxis {
                        id: timeNetAxis
                        labelsVisible: false
                        format: "hh:mm"
                    }

                    ValueAxis {
                        id: octetsAxis
                        max: 200
                        min: 0
                        tickCount: 3
                    }
                    AreaSeries {
                        name: "InOctets"
                        opacity: 1.0
                        borderColor: "#FF0039A5"
                        borderWidth: 1

                        axisX: timeNetAxis
                        axisY: octetsAxis

                        upperSeries: LineSeries {
                            id: netSeriesIn
                            XYPoint { x: new Date().getTime(); y: 0 }
                        }

                    }
                    AreaSeries {
                        name: "OutOctets"
                        opacity: 0.5
                        borderWidth: 0
                        color: "#FFD52B1E"

                        axisX: timeNetAxis
                        axisY: octetsAxis

                        upperSeries: LineSeries {
                            id: netSeriesOut
                            XYPoint { x: new Date().getTime(); y: 0 }
                        }
                    }
                    function updateStats(in_, out_)
                    {
                        var time_ = new Date();

                        if (in_ > octetsAxis.max)
                            octetsAxis.max = (in_ / 1000 + 1) * 1000;
                        if (out_ > octetsAxis.max)
                            octetsAxis.max = (out_ / 1000 + 1) * 1000;

                        netSeriesIn.append(time_.getTime(), in_);
                        netSeriesOut.append(time_.getTime(), out_);
                        timeNetAxis.max = time_;

                        if (netSeriesIn.count > 1800)
                        {
                            netSeriesIn.remove(0);
                            netSeriesOut.remove(0);
                            time_.setMinutes(time_.getMinutes() - 30);
                            timeNetAxis.min = time_;
                        }

                        networkChart.update();
                    }
                }
            }
        }
    }
    }
}