import QtQuick 2.3
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.1
import Nymea 1.0
import Nymea.AirConditioning 1.0
import "qrc:/ui/components"

ColumnLayout {
    id: root
    Layout.minimumHeight: 100
    property string title: ""

    property ZoneInfo zone: null
    property TemperatureDaySchedule daySchedule: null

    property TemperatureDaySchedule scheduleClipboard: null

    signal copyClicked()

    RowLayout {
        Layout.fillWidth: true

        Label {
            Layout.fillWidth: true
            text: root.title
        }

        ProgressButton {
            imageSource: paste ? "edit-paste" : "edit-copy"
            color: root.scheduleClipboard == root.daySchedule ? Style.accentColor : Style.iconColor
            property bool paste: root.scheduleClipboard != null && root.scheduleClipboard != root.daySchedule
            onClicked: {
                if (paste) {
                    daySchedule.clear();
                    for (var i = 0; i < root.scheduleClipboard.count; i++) {
                        var schedule = root.scheduleClipboard.get(i)
                        daySchedule.createSchedule(schedule.startTime, schedule.endTime, schedule.temperature)
                    }
                } else {
                    root.copyClicked()
                }
            }
        }
    }


    QtObject {
        id: d
        property var freeBlocks: {
            var ret = []
            for (var i = 0; i < daySchedule.count; i++) {
                var previous = i == 0 ? null : daySchedule.get(i - 1)
                var previousMins = previous ? previous.endTime.getHours() * 60 + previous.endTime.getMinutes() : 0
                var schedule = daySchedule.get(i)
                var startMins = schedule.startTime.getHours() * 60 + schedule.startTime.getMinutes()
                var endMins = schedule.endTime.getHours() * 60 + schedule.endTime.getMinutes()

                if (startMins > previousMins + 60 * 3) {
                    ret.push({startMins: previousMins, endMins: startMins})
                }
            }
            var last = daySchedule.count > 0 ? daySchedule.get(daySchedule.count - 1) : null
            var lastMins = last ? last.endTime.getHours() * 60 + last.endTime.getMinutes() : 0
            if (lastMins < (21*60)) {
                ret.push({startMins: lastMins, endMins: 24*60})
            }

            return ret
        }
    }

    Rectangle {
        id: slider
        Layout.fillWidth: true
        Layout.fillHeight: true
        color: Style.tileBackgroundColor
        radius: Style.cornerRadius
        clip: true


        Repeater {
            model: 24
            delegate: Rectangle {
                height: parent.height
                width: 1
                color: Style.tileOverlayColor
                x: slider.width / 24 * index
                visible: index > 0
            }
        }

        Repeater {
            model: root.daySchedule
            delegate: Rectangle {
                id: blockDelegate
                readonly property TemperatureSchedule schedule: root.daySchedule.get(index)
                readonly property int startMinutes: schedule.startTime.getHours() * 60 + schedule.startTime.getMinutes()
                readonly property int endMinutes: schedule.endTime.getHours() * 60 + schedule.endTime.getMinutes()
                readonly property int totalMinutes: 24 * 60
                height: slider.height
                width: endMinutes * slider.width / totalMinutes - x
                x: startMinutes * slider.width / totalMinutes
                radius: Style.cornerRadius
                color: schedule.temperature >= zone.standbySetpoint ? Style.red : Style.blue

                Rectangle {
                    anchors {
                        left: parent.left;
                        leftMargin: Style.extraSmallMargins
                        verticalCenter: parent.verticalCenter
                    }
                    height: Style.font.pixelSize
                    width: 2
                    radius: width / 2
                    color: Style.white
                }
                Rectangle {
                    anchors {
                        right: parent.right
                        rightMargin: Style.extraSmallMargins
                        verticalCenter: parent.verticalCenter
                    }
                    height: Style.font.pixelSize
                    width: 2
                    radius: width / 2
                    color: Style.white
                }

                Label {
                    anchors { left: parent.left; right: parent.right; margins: Style.extraSmallMargins; top: parent.top }
                    anchors.leftMargin: parent.width >= implicitWidth + Style.smallMargins ? Style.extraSmallMargins : -(implicitWidth + Style.extraSmallMargins)
                    horizontalAlignment: Text.AlignLeft
                    font: Style.extraSmallFont
                    text: blockDelegate.schedule.startTime.toLocaleTimeString(Qt.locale(), Locale.ShortFormat)
                }

                Label {
                    anchors { left: parent.left; right: parent.right; margins: Style.smallMargins; verticalCenter: parent.verticalCenter }
                    horizontalAlignment: Text.AlignHCenter
                    font: Style.smallFont
                    text: Types.toUiValue(blockDelegate.schedule.temperature, Types.UnitDegreeCelsius) + "°"
                    elide: Text.ElideRight
                }
                Label {
                    anchors { left: parent.left; right: parent.right; margins: Style.extraSmallMargins; bottom: parent.bottom }
                    anchors.rightMargin: parent.width >= implicitWidth + Style.smallMargins ? Style.extraSmallMargins : -(implicitWidth + Style.extraSmallMargins)
                    horizontalAlignment: Text.AlignRight
                    font: Style.extraSmallFont
                    text: blockDelegate.schedule.endTime.toLocaleTimeString(Qt.locale(), Locale.ShortFormat)
//                    elide: Text.ElideRight
                }

            }
        }



        MouseArea {
            anchors.fill: parent

            property bool moveStart: false
            property bool moveEnd: false
            property TemperatureSchedule previousSchedule: null
            property TemperatureSchedule movedSchedule: null
            property TemperatureSchedule nextSchedule: null

            property int startMouseX: 0
            property int startMins: 0
            property int endMins: 0

            onPressed: {
                movedSchedule = null
                startMouseX = mouseX
                var totalMins = 24 * 60
                for (var i = 0; i < root.daySchedule.count; i++) {
                    var schedule = root.daySchedule.get(i)
                    print("schedule:", schedule.startTime, schedule.endTime)
                    var startMin = schedule.startTime.getHours() * 60 + schedule.startTime.getMinutes()
                    var startPos = startMin * slider.width / totalMins
                    var endMin = schedule.endTime.getHours() * 60 + schedule.endTime.getMinutes()
                    var endPos = endMin * slider.width / totalMins

                    if (Math.abs(startPos - mouseX) < 10) {
                        moveStart = true;
                        print("start")
                    } else if (Math.abs(endPos - mouseX) < 10) {
                        moveEnd = true
                        print("end")
                    } else if (mouseX > startPos && mouseX < endPos) {
                        moveStart = true
                        moveEnd = true
                        print("middle")
                    } else {
                        continue
                    }
                    startMins = startMin
                    endMins = endMin
                    previousSchedule = i > 0 ? root.daySchedule.get(i-1) : null
                    movedSchedule = schedule
                    nextSchedule = i < root.daySchedule.count - 1 ? root.daySchedule.get(i+1) : null
                    break;
                }
            }

            onReleased: {
                moveStart = false;
                moveEnd = false;
                preventStealing = false;
            }

            onClicked: {
                print("clicked")
                if (movedSchedule != null && Math.abs(mouseX - startMouseX) < 5) {
                    print("opening")
                    var dialog = editDialogComponent.createObject(root.parent, {schedule: movedSchedule})
                    dialog.open()

                }
            }

            onPositionChanged: {
                var totalMins = 24 * 60
                var diffX = mouseX - startMouseX

                // dY : height = dM : total
                var diffMins = diffX * totalMins / slider.width
                print("diffX", diffX, "diffMins", diffMins, startMins, startMins + diffMins)

                var newStart = new Date(movedSchedule.startTime);
                var newEnd = new Date(movedSchedule.endTime);

                var newStartMins = startMins + (moveStart ? diffMins : 0);
                var newEndMins = endMins + (moveEnd ? diffMins : 0);

                var snapMinutes = 30

                var leftLimit = previousSchedule ? previousSchedule.endTime.getHours() * 60 + previousSchedule.endTime.getMinutes() + snapMinutes : 0
                var rightLimit = nextSchedule ? nextSchedule.startTime.getHours() * 60 + nextSchedule.startTime.getMinutes() - snapMinutes : totalMins


                if (moveStart && !moveEnd) {
                    newStartMins = Math.max(leftLimit, newStartMins)
                    newStartMins = Math.min(newEndMins - 60, newStartMins)
                } else if (moveEnd && !moveStart) {
                    newEndMins = Math.min(rightLimit, newEndMins)
                    newEndMins = Math.max(newStartMins + 60, newEndMins)
                } else if (moveStart && moveEnd) {
                    newStartMins = Math.max(leftLimit, newStartMins)
                    newEndMins = Math.min(rightLimit, newEndMins)

                    var blockSize = endMins - startMins

                    newStartMins = Math.max(leftLimit, Math.min(newEndMins - blockSize, newStartMins))
                    newEndMins = Math.max(newStartMins + blockSize, newEndMins)

                }

                var startSnapOffset = newStartMins % snapMinutes
                if (startSnapOffset < snapMinutes / 2) {
                    newStartMins -= startSnapOffset
                } else {
                    newStartMins += (snapMinutes - startSnapOffset)
                }
                var endSnapOffset = newEndMins % snapMinutes
                if (endSnapOffset < snapMinutes / 2) {
                    newEndMins -= endSnapOffset
                } else {
                    newEndMins += (snapMinutes - endSnapOffset)
                }
                print("startSnapOffset", startSnapOffset, "endSnapOff", endSnapOffset, "nes start", newStartMins, newEndMins)

                if (newEndMins == totalMins) {
                    newEndMins -= 1
                }

                newStart.setHours(0, newStartMins)
                newEnd.setHours(0, newEndMins)

                if (movedSchedule.startTime.getTime() !== newStart.getTime() || movedSchedule.endTime.getTime() !== newEnd.getTime()) {
                    preventStealing = true;
                }

                movedSchedule.startTime = newStart
                movedSchedule.endTime = newEnd

                print("start time is new", newStart.toLocaleTimeString())
                print("end time is new", newEnd.toLocaleTimeString())

            }
        }

        Repeater {
            model: d.freeBlocks
            delegate: Item {
                id: freeBlockDelegate
                property var block: d.freeBlocks[index]
                x: block.startMins * slider.width / (24*60)
                width: block.endMins * slider.width / (24*60) - x
                height: slider.height

                ProgressButton {
                    anchors.centerIn: parent
                    imageSource: "add"
                    onClicked: {
                        var startTime = new Date()
                        var endTime = new Date()
                        if (root.daySchedule.count == 0) {
                            startTime.setHours(6, 0, 0)
                            endTime.setHours(18, 0, 0)
                        } else {
                            startTime.setHours(0, freeBlockDelegate.block.startMins + 60, 0)
                            endTime.setHours(0, freeBlockDelegate.block.endMins - 60, 0)
                        }

                        root.daySchedule.createSchedule(startTime, endTime, 21)
                    }
                }
            }
        }
    }

    Component {
        id: editDialogComponent
        NymeaDialog {
            id: editDialog
            x: (parent.width - width) / 2
            property TemperatureSchedule schedule: null

            standardButtons: Dialog.NoButton

            Dial {
                id: dial
                Layout.fillWidth: true
                Layout.preferredHeight: width
                activeValue: root.zone.standbySetpoint
                minValue: 10
                maxValue: 30
                precision: 0.5
                value: editDialog.schedule.temperature
                onMoved: editDialog.schedule.temperature = value
                color: activeValue <= value ? Style.red : Style.blue
                ColumnLayout {
                    anchors.centerIn: parent
                    anchors.verticalCenterOffset: -Style.smallMargins
                    width: parent.contentItem.width * 0.6
                    Label {
                        Layout.fillWidth: true
                        text: Types.toUiUnit(Types.UnitDegreeCelsius)
                        font.pixelSize: Math.min(Style.smallFont.pixelSize, dial.height / 16)
                        horizontalAlignment: Text.AlignHCenter
                    }
                    Label {
                        Layout.fillWidth: true
                        text: Types.toUiValue(editDialog.schedule.temperature, Types.UnitDegreeCelsius).toFixed(1)
                        font.pixelSize: Math.min(Style.hugeFont.pixelSize, dial.height / 8)
                        horizontalAlignment: Text.AlignHCenter
                        color: zone.currentSetpoint > zone.standbySetpoint
                                 ? Style.red
                                 : zone.currentSetpoint < zone.standbySetpoint
                                   ? Style.blue
                                   : Style.foregroundColor
                    }
                    Label {
                        Layout.fillWidth: true
                        text: Types.toUiValue(zone.standbySetpoint, Types.UnitDegreeCelsius).toFixed(1)
                        font.pixelSize: Math.min(Style.largeFont.pixelSize, dial.height / 12)
                        wrapMode: Text.WordWrap
                        horizontalAlignment: Text.AlignHCenter
                        elide: Text.ElideRight
                    }


                }


            }

            Label {
                Layout.fillWidth: true
                text: editDialog.schedule.startTime.toLocaleTimeString(Qt.locale(), Locale.ShortFormat)
                      + " - "
                      + editDialog.schedule.endTime.toLocaleTimeString(Qt.locale(), Locale.ShortFormat)
                horizontalAlignment: Text.AlignHCenter
            }

            RowLayout {
                Button {
                    text: qsTr("Remove")
                    Layout.fillWidth: true
                    onClicked: {
                        root.daySchedule.removeSchedule(editDialog.schedule)
                        editDialog.close()
                    }
                }
                Button {
                    text: qsTr("OK")
                    Layout.fillWidth: true
                    onClicked: {
                        editDialog.close()
                    }
                }
            }

        }
    }
}
