import QtQuick 2.15
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Extras 1.4
import QtQuick.Extras.Private 1.0
import QtQuick.Shapes 1.15
import QtQuick.Controls 2.15
import QtGraphicalEffects 1.12
import "./components"

// WRAPPER FOR VARIABLES
Item {
    id: root
    objectName: "gauge"
    // EXTERNALLY CONFIGURABLE PROPERTIES
    property real size: 300
    property real padding: 10
    property real min: -10.0
    property real max: 10.0
    property real step: 1.0
    property real minor_step_n: -4  // positive for count negative for angle
    property real value: 0.0
    property string unit: "number"
    property real min_angle: -60
    property real max_angle: +60
    property
    var colorRanges: []
    // SHOWN HEIGHT AND WIDTH
    height: wrapper.height
    width: wrapper.width
    // COLOR
    function _get_color(value) {
        var rs, r;
        for (var i = 0; i < root.colorRanges.length; i += 1) {
            rs = root.colorRanges[i];
            for (var j = 0; j < rs[0].length; j += 1) {
                r = rs[0][j];
                if (value >= r[0] && value <= r[1]) {
                    return rs[1];
                }
            }
        }
        return "#c8c8c8";
    }
    // PADDING
    Control {
        id: wrapper
        width: root.size * 1.2 * Math.sin((gauge.angleRange / 2) * (Math.PI / 180)) + padding * 2
        property real max_side_angle: Math.max(Math.abs(root.min_angle), Math.abs(root.max_angle))
        height: root.size * 1.2 / 2 * (max_side_angle <= 90 ? 1 : (1 + Math.sin((max_side_angle - 90) * (Math.PI / 180)))) + padding * 2
        padding: root.padding
        background: Rectangle {
            color: "#555"
        }
        // CROP TO THIS RECTANGLE
        contentItem: Rectangle {
            clip: true
            color: "transparent"
            // GAUGE
            CircularGauge {
                id: gauge
                value: root.value
                minimumValue: root.min
                maximumValue: root.max
                // STYLING
                // align
                anchors.horizontalCenter: parent.horizontalCenter
                // anchors.verticalCenter: parent.bottom
                y: root.size * 0.03
                tickmarksVisible: true
                property real valueRange: maximumValue - minimumValue
                property real valueCenter: (root.min + root.max) / 2
                property real angleRange: Math.abs(root.min_angle) + Math.abs(root.max_angle)
                property real angleCenter: (root.min_angle + root.max_angle) / 2
                // labels, ticks, minor ticks density
                property real minorTickmarkAngleStep: Math.abs(root.minor_step_n)
                // apply styling
                style: CircularGaugeStyle {
                    id: style
                    objectName: "style"
                    // GAUGE ANGLE
                    minimumValueAngle: -(gauge.angleRange / 2)
                    maximumValueAngle: +(gauge.angleRange / 2)
                    // value to angle
                    function _valueToAngle(value) {
                        return ((value - gauge.valueCenter) / gauge.valueRange) * gauge.angleRange + gauge.angleCenter
                    }
                    // BACKGROUND (COLORED RANGES)
                    background: Rectangle {
                        id: background
                        // implicitWidth and implicitHeight set outerRadius for the style
                        implicitWidth: root.size - root.padding
                        implicitHeight: root.size - root.padding
                        width: implicitWidth
                        height: implicitHeight
                        color: "transparent"
                        Connections {
                            target: root
                            function onColorRangesChanged() {
                                var rs, color, r;
                                for (var i = 0; i < root.colorRanges.length; i += 1) {
                                    rs = root.colorRanges[i];
                                    color = rs[1];
                                    for (var j = 0; j < rs[0].length; j += 1) {
                                        r = rs[0][j];
                                        Qt.createQmlObject(`
                                                import "./components"
                                                Arch {
                                                    radius: outerRadius
                                                    startAngle: ${_valueToAngle(r[0])}
                                                    stopAngle: ${_valueToAngle(r[1])}
                                                    strokeWidth: outerRadius * 0.02
                                                    color: "${color}"
                                                }
                                        `, background);
                                    }
                                }
                            }
                        }
                    }
                    // // NEEDLE
                    // needle: Component
                    // // FOREGROUND (CENTRAL DIAL)
                    // foreground: Component
                    // LABELS
                    tickmarkLabel: Text {
                        font.pixelSize: Math.max(6, outerRadius * 0.1)
                        text: styleData.value % 1 == 0 ? styleData.value : styleData.value.toFixed(2)
                        color: "#c8c8c8"  // root._get_color(styleData.value)
                        antialiasing: true
                    }
                    labelStepSize: root.step
                    property real labelCount: Math.floor(gauge.valueRange / labelStepSize)
                    // labelInset: 0.0
                    // TICKS
                    tickmark: Rectangle {
                        implicitWidth: outerRadius * 0.02
                        implicitHeight: outerRadius * 0.075
                        color: root._get_color(styleData.value)
                        antialiasing: true
                    }
                    tickmarkStepSize: root.step
                    tickmarkInset: 0.0
                    // MINOR TICKS
                    minorTickmark: Rectangle {
                        implicitWidth: outerRadius * 0.01
                        implicitHeight: outerRadius * 0.05
                        color: root._get_color(styleData.value)
                        antialiasing: true
                    }
                    minorTickmarkCount: root.minor_step_n > 0 ? Math.floor(root.minor_step_n) : Math.floor(gauge.angleRange / tickmarkCount / gauge.minorTickmarkAngleStep) // every minorTickmarkAngleStep degreees or more
                    minorTickmarkInset: 0.0
                }
            }

            Rectangle {
                anchors.centerIn: parent
                width: root.size * 0.4
                height: root.size * 0.25
                color: "transparent"

                Text {
                    id: value_text
                    anchors.centerIn: parent
                    property real font_size: root.size * 0.1
                    font.pixelSize: font_size
                    fontSizeMode: Text.Fit
                    font.bold: true
                    text: root.value % 1 == 0 ? root.value : root.value.toFixed(2)
                    color: "#c8c8c8"  // root._get_color(root.value)
                    antialiasing: true
                }

                Text {
                    anchors.top: value_text.bottom
                    anchors.horizontalCenter: parent.horizontalCenter
                    font.pixelSize: value_text.font_size * 0.5
                    fontSizeMode: Text.Fit
                    font.bold: true
                    text: root.unit
                    color: "#c8c8c8"  // root._get_color(root.value)
                    antialiasing: true
                }
            }
        }
    }
}
