/*=====================================================================

 QGroundControl Open Source Ground Control Station

 (c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>

 This file is part of the QGROUNDCONTROL project

 QGROUNDCONTROL 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.

 QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.

 ======================================================================*/

/// @file
///     @brief Radio Calibration
///     @author Don Gagne <don@thegagnes.com>

import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Dialogs 1.2

import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Palette 1.0
import QGroundControl.Controls 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Controllers 1.0

QGCView {
    id:         rootQGCView
    viewPanel:  panel

    QGCPalette { id: qgcPal; colorGroupEnabled: panel.enabled }

    readonly property string dialogTitle: "Radio"
    readonly property real labelToMonitorMargin: defaultTextWidth * 3
    property bool controllerCompleted: false
    property bool controllerAndViewReady: false

    property Fact rcInMode: controller.getParameterFact(-1, "COM_RC_IN_MODE")

    function updateChannelCount()
    {
        if (controllerAndViewReady) {
            if (rcInMode.value == 1) {
                showDialog(joystickEnabledDialogComponent, dialogTitle, 50, 0)
            }
/*
            FIXME: Turned off for now, since it prevents binding. Need to restructure to
            allow binding and still check channel count
            if (controller.channelCount < controller.minChannelCount) {
                showDialog(channelCountDialogComponent, dialogTitle, 50, 0)
            } else {
                hideDialog()
            }
*/
        }
    }

    RadioComponentController {
        id:             controller
        factPanel:      panel
        statusText:     statusText
        cancelButton:   cancelButton
        nextButton:     nextButton
        skipButton:     skipButton

        onChannelCountChanged: updateChannelCount()

        Component.onCompleted: {
            controllerCompleted = true
            if (rootQGCView.completedSignalled) {
                controllerAndViewReady = true
                controller.start()
                updateChannelCount()
            }
        }
    }

    onCompleted: {
        if (controllerCompleted) {
            controllerAndViewReady = true
            controller.start()
            updateChannelCount()
        }
    }

    QGCViewPanel {
        id:             panel
        anchors.fill:   parent

        Component {
            id: copyTrimsDialogComponent

            QGCViewMessage {
                message: "Center your sticks and move throttle all the way down, then press Ok to copy trims. After pressing Ok, reset the trims on your radio back to zero."

                function accept() {
                    hideDialog()
                    controller.copyTrims()
                }
            }
        }

        Component {
            id: zeroTrimsDialogComponent

            QGCViewMessage {
                message: "Before calibrating you should zero all your trims and subtrims. Click Ok to start Calibration."

                function accept() {
                    hideDialog()
                    controller.nextButtonClicked()
                }
            }
        }

        Component {
            id: channelCountDialogComponent

            QGCViewMessage {
                message: controller.channelCount == 0 ? "Please turn on transmitter." : controller.minChannelCount + " channels or more are needed to fly."
            }
        }

        Component {
            id: joystickEnabledDialogComponent

            QGCViewMessage {
                message: "Radio Config is disabled since you have a Joystick enabled."
            }
        }

        Component {
            id: spektrumBindDialogComponent

            QGCViewDialog {

                function accept() {
                    controller.spektrumBindMode(radioGroup.current.bindMode)
                    hideDialog()
                }

                function reject() {
                    hideDialog()
                }

                Column {
                    anchors.fill:   parent
                    spacing:        5

                    QGCLabel {
                        width:      parent.width
                        wrapMode:   Text.WordWrap
                        text:       "Click Ok to place your Spektrum receiver in the bind mode. Select the specific receiver type below:"
                    }

                    ExclusiveGroup { id: radioGroup }

                    QGCRadioButton {
                        exclusiveGroup: radioGroup
                        text:           "DSM2 Mode"

                        property int bindMode: RadioComponentController.DSM2
                    }

                    QGCRadioButton {
                        exclusiveGroup: radioGroup
                        text:           "DSMX (7 channels or less)"

                        property int bindMode: RadioComponentController.DSMX7
                    }

                    QGCRadioButton {
                        exclusiveGroup: radioGroup
                        checked:        true
                        text:           "DSMX (8 channels or more)"

                        property int bindMode: RadioComponentController.DSMX8
                    }
                }
            }
        } // Component - spektrumBindDialogComponent

        // Live channel monitor control component
        Component {
            id: channelMonitorDisplayComponent

            Item {
                property int    rcValue:    1500


                property int            __lastRcValue:      1500
                readonly property int   __rcValueMaxJitter: 2
                property color          __barColor:         qgcPal.windowShade

                // Bar
                Rectangle {
                    id:                     bar
                    anchors.verticalCenter: parent.verticalCenter
                    width:                  parent.width
                    height:                 parent.height / 2
                    color:                  __barColor
                }

                // Center point
                Rectangle {
                    anchors.horizontalCenter:   parent.horizontalCenter
                    width:                      defaultTextWidth / 2
                    height:                     parent.height
                    color:                      qgcPal.window
                }

                // Indicator
                Rectangle {
                    anchors.verticalCenter: parent.verticalCenter
                    width:                  parent.height * 0.75
                    height:                 width
                    x:                      ((Math.abs((rcValue - 1000) - (reversed ? 1000 : 0)) / 1000) * parent.width) - (width / 2)
                    radius:                 width / 2
                    color:                  qgcPal.text
                    visible:                mapped
                }

                QGCLabel {
                    anchors.fill:           parent
                    horizontalAlignment:    Text.AlignHCenter
                    verticalAlignment:      Text.AlignVCenter
                    text:                   "Not Mapped"
                    visible:                !mapped
                }

                ColorAnimation {
                    id:         barAnimation
                    target:     bar
                    property:   "color"
                    from:       "yellow"
                    to:         __barColor
                    duration:   1500
                }

                /*
                // FIXME: Bar animation is turned off for now to figure out better usbaility
                onRcValueChanged: {
                    if (Math.abs(rcValue - __lastRcValue) > __rcValueMaxJitter) {
                        __lastRcValue = rcValue
                        barAnimation.restart()
                    }
                }

                // rcValue debugger
                QGCLabel {
                    anchors.fill: parent
                    text: rcValue
                }
                */
            }
        } // Component - channelMonitorDisplayComponent

        // Main view Qml starts here

        // Left side column
        Column {
            id:             leftColumn
            anchors.top:    parent.top
            anchors.left:   parent.left
            anchors.right:  columnSpacer.left
            spacing:        10

            // Attitude Controls
            Column {
                width:      parent.width
                spacing:    5

                QGCLabel { text: "Attitude Controls" }

                Item {
                    width:  parent.width
                    height: defaultTextHeight * 2

                    QGCLabel {
                        id:     rollLabel
                        width:  defaultTextWidth * 10
                        text:   "Roll"
                    }

                    Loader {
                        id:                 rollLoader
                        anchors.left:       rollLabel.right
                        anchors.right:      parent.right
                        height:             rootQGCView.defaultTextHeight
                        width:              100
                        sourceComponent:    channelMonitorDisplayComponent

                        property real defaultTextWidth: rootQGCView.defaultTextWidth
                        property bool mapped:           controller.rollChannelMapped
                        property bool reversed:         controller.rollChannelReversed
                    }

                    Connections {
                        target: controller

                        onRollChannelRCValueChanged: rollLoader.item.rcValue = rcValue
                    }
                }

                Item {
                    width:  parent.width
                    height: defaultTextHeight * 2

                    QGCLabel {
                        id:     pitchLabel
                        width:  defaultTextWidth * 10
                        text:   "Pitch"
                    }

                    Loader {
                        id:                 pitchLoader
                        anchors.left:       pitchLabel.right
                        anchors.right:      parent.right
                        height:             rootQGCView.defaultTextHeight
                        width:              100
                        sourceComponent:    channelMonitorDisplayComponent

                        property real defaultTextWidth: rootQGCView.defaultTextWidth
                        property bool mapped:           controller.pitchChannelMapped
                        property bool reversed:         controller.pitchChannelReversed
                    }

                    Connections {
                        target: controller

                        onPitchChannelRCValueChanged: pitchLoader.item.rcValue = rcValue
                    }
                }

                Item {
                    width:  parent.width
                    height: defaultTextHeight * 2

                    QGCLabel {
                        id:     yawLabel
                        width:  defaultTextWidth * 10
                        text:   "Yaw"
                    }

                    Loader {
                        id:                 yawLoader
                        anchors.left:       yawLabel.right
                        anchors.right:      parent.right
                        height:             rootQGCView.defaultTextHeight
                        width:              100
                        sourceComponent:    channelMonitorDisplayComponent

                        property real defaultTextWidth: rootQGCView.defaultTextWidth
                        property bool mapped:           controller.yawChannelMapped
                        property bool reversed:         controller.yawChannelReversed
                    }

                    Connections {
                        target: controller

                        onYawChannelRCValueChanged: yawLoader.item.rcValue = rcValue
                    }
                }

                Item {
                    width:  parent.width
                    height: defaultTextHeight * 2

                    QGCLabel {
                        id:     throttleLabel
                        width:  defaultTextWidth * 10
                        text:   "Throttle"
                    }

                    Loader {
                        id:                 throttleLoader
                        anchors.left:       throttleLabel.right
                        anchors.right:      parent.right
                        height:             rootQGCView.defaultTextHeight
                        width:              100
                        sourceComponent:    channelMonitorDisplayComponent

                        property real defaultTextWidth: rootQGCView.defaultTextWidth
                        property bool mapped:           controller.throttleChannelMapped
                        property bool reversed:         controller.throttleChannelReversed
                    }

                    Connections {
                        target: controller

                        onThrottleChannelRCValueChanged: throttleLoader.item.rcValue = rcValue
                    }
                }
            } // Column - Attitude Control labels

            // Command Buttons
            Row {
                spacing: 10

                QGCButton {
                    id:         skipButton
                    showBorder: true
                    text:       "Skip"

                    onClicked: controller.skipButtonClicked()
                }

                QGCButton {
                    id:         cancelButton
                    showBorder: true
                    text:       "Cancel"

                    onClicked: controller.cancelButtonClicked()
                }

                QGCButton {
                    id:         nextButton
                    primary:    true
                    showBorder: true
                    text:       "Calibrate"

                    onClicked: {
                        if (text == "Calibrate") {
                            showDialog(zeroTrimsDialogComponent, dialogTitle, 50, StandardButton.Ok | StandardButton.Cancel)
                        } else {
                            controller.nextButtonClicked()
                        }
                    }
                }
            } // Row - Buttons

            // Status Text
            QGCLabel {
                id:         statusText
                width:      parent.width
                wrapMode:   Text.WordWrap
            }

            Item {
                width: 10
                height: defaultTextHeight * 4
            }

            Rectangle {
                width:          parent.width
                height:         1
                border.color:   qgcPal.text
                border.width:   1
            }

            QGCLabel { text: "Additional Radio setup:" }

            Row {
                spacing: 10

                QGCLabel {
                    anchors.baseline:   bindButton.baseline
                    text:               "Place Spektrum satellite receiver in bind mode:"
                }

                QGCButton {
                    id:         bindButton
                    showBorder: true
                    text:       "Spektrum Bind"

                    onClicked: showDialog(spektrumBindDialogComponent, dialogTitle, 50, StandardButton.Ok | StandardButton.Cancel)
                }
            }

            QGCButton {
                showBorder: true
                text:       "Copy Trims"
                onClicked:  showDialog(copyTrimsDialogComponent, dialogTitle, 50, StandardButton.Ok | StandardButton.Cancel)
            }

        } // Column - Left Column

        Item {
            id:             columnSpacer
            anchors.right:  rightColumn.left
            width:          20
        }

        // Right side column
        Column {
            id:             rightColumn
            anchors.top:    parent.top
            anchors.right:  parent.right
            width:          defaultTextWidth * 35
            spacing:        10

            Row {
                spacing: 10
                ExclusiveGroup { id: modeGroup }

                QGCRadioButton {
                    exclusiveGroup: modeGroup
                    text:           "Mode 1"
                    checked:        controller.transmitterMode == 1

                    onClicked: controller.transmitterMode = 1
                }

                QGCRadioButton {
                    exclusiveGroup: modeGroup
                    text:           "Mode 2"
                    checked:        controller.transmitterMode == 2

                    onClicked: controller.transmitterMode = 2
                }
            }

            Image {
                width:      parent.width
                height:     defaultTextHeight * 15
                fillMode:   Image.PreserveAspectFit
                smooth:     true
                source:     controller.imageHelp
            }

            // Channel monitor
            Column {
                width:      parent.width
                spacing:    5

                QGCLabel { text: "Channel Monitor" }

                Connections {
                    target: controller

                    onChannelRCValueChanged: {
                        if (channelMonitorRepeater.itemAt(channel)) {
                            channelMonitorRepeater.itemAt(channel).loader.item.rcValue = rcValue
                        }
                    }
                }

                Repeater {
                    id:     channelMonitorRepeater
                    model:  controller.channelCount
                    width:  parent.width

                    Row {
                        spacing:    5

                        // Need this to get to loader from Connections above
                        property Item loader: theLoader

                        QGCLabel {
                            id:     channelLabel
                            text:   modelData + 1
                        }

                        Loader {
                            id:                     theLoader
                            anchors.verticalCenter: channelLabel.verticalCenter
                            height:                 rootQGCView.defaultTextHeight
                            width:                  200
                            sourceComponent:        channelMonitorDisplayComponent

                            property real defaultTextWidth:     rootQGCView.defaultTextWidth
                            property bool mapped:               true
                            readonly property bool reversed:    false
                        }
                    }
                }
            } // Column - Channel Monitor
        } // Column - Right Column
    } // QGCViewPanel
}
