/*
  Q Light Controller Plus
  RGBMatrixEditor.qml

  Copyright (c) Massimo Callegari

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0.txt

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Dialogs

import org.qlcplus.classes 1.0

import "TimeUtils.js" as TimeUtils
import "."

Rectangle
{
    id: rgbmeContainer
    //anchors.fill: parent
    color: "transparent"

    property int functionID: -1
    property var algoColors: rgbMatrixEditor ? rgbMatrixEditor.algoColors : null

    signal requestView(int ID, string qmlSrc, bool back)

    onAlgoColorsChanged:
    {
        var cCount = rgbMatrixEditor.algoColorsCount
        color1Button.color = algoColors[0]
        color2Button.color = cCount > 1 && rgbMatrixEditor.hasColorAtIndex(1) ? algoColors[1] : "transparent"
        color3Button.color = cCount > 2 && rgbMatrixEditor.hasColorAtIndex(2) ? algoColors[2] : "transparent"
        color4Button.color = cCount > 3 && rgbMatrixEditor.hasColorAtIndex(3) ? algoColors[3] : "transparent"
        color5Button.color = cCount > 4 && rgbMatrixEditor.hasColorAtIndex(4) ? algoColors[4] : "transparent"
    }

    TimeEditTool
    {
        id: timeEditTool

        parent: mainView
        z: 99
        x: rightSidePanel.x - width
        visible: false
        tempoType: rgbMatrixEditor.tempoType

        onValueChanged:
        {
            if (speedType == QLCFunction.FadeIn)
                rgbMatrixEditor.fadeInSpeed = val
            else if (speedType == QLCFunction.Hold)
                rgbMatrixEditor.holdSpeed = val
            else if (speedType == QLCFunction.FadeOut)
                rgbMatrixEditor.fadeOutSpeed = val
        }
    }

    ColorTool
    {
        id: colorTool
        x: -width - (UISettings.iconSizeDefault * 1.25)
        y: UISettings.bigItemHeight
        visible: false
        closeOnSelect: true

        property int colorIndex: -1
        property Item previewBtn

        function showTool(index, button)
        {
            colorIndex = index
            previewBtn = button
            currentRGB = rgbMatrixEditor.colorAtIndex(colorIndex)
            visible = true
        }

        function hide()
        {
            visible = false
            colorIndex = -1
            previewBtn = null
        }

        onToolColorChanged:
            function(r, g, b, w, a, uv)
            {
                previewBtn.color = Qt.rgba(r, g, b, 1.0)
                rgbMatrixEditor.setColorAtIndex(colorIndex, previewBtn.color)
            }
        onClose: visible = false
    }

    EditorTopBar
    {
        id: topBar
        text: rgbMatrixEditor.functionName
        onTextChanged: rgbMatrixEditor.functionName = text

        onBackClicked:
        {
            var prevID = rgbMatrixEditor.previousID
            requestView(prevID, functionManager.getEditorResource(prevID), true)
        }
    }

    Flickable
    {
        id: editorFlickable
        x: 5
        y: topBar.height + 2
        width: parent.width - 10
        height: parent.height - y

        contentHeight: editorColumn.height
        boundsBehavior: Flickable.StopAtBounds

        Component.onCompleted: console.log("Flickable height: " + height + ", Grid height: " + editorColumn.height + ", parent height: " + parent.height)

        Column
        {
            id: editorColumn
            width: parent.width
            spacing: 2

            property int itemsHeight: UISettings.listItemHeight
            property int firstColumnWidth: 0
            property int colWidth: parent.width - (sbar.visible ? sbar.width : 0)

            //onHeightChanged: editorFlickable.contentHeight = height //console.log("Grid layout height changed: " + height)

            function checkLabelWidth(w)
            {
                firstColumnWidth = Math.max(w, firstColumnWidth)
            }

            // row 1
            RowLayout
            {
                width: editorColumn.colWidth

                RobotoText
                {
                    label: qsTr("Fixture Group")
                    height: editorColumn.itemsHeight
                    onWidthChanged:
                    {
                        editorColumn.checkLabelWidth(width)
                        width = Qt.binding(function() { return editorColumn.firstColumnWidth })
                    }
                }
                CustomComboBox
                {
                    Layout.fillWidth: true
                    height: editorColumn.itemsHeight
                    model: fixtureGroupEditor.groupsListModel
                    currValue: rgbMatrixEditor.fixtureGroup
                    onValueChanged: (value) => rgbMatrixEditor.fixtureGroup = value
                }
            }

            // row 2
            RGBMatrixPreview
            {
                width: editorColumn.width
                matrixSize: rgbMatrixEditor.previewSize
                matrixData: rgbMatrixEditor.previewData
                maximumHeight: rgbmeContainer.height / 3
            }


            GridLayout
            {
                width: editorColumn.colWidth
                columns: 3

                // row 3
                RobotoText
                {
                    id: patternLabel
                    label: qsTr("Pattern")
                    height: editorColumn.itemsHeight
                    onWidthChanged:
                    {
                        editorColumn.checkLabelWidth(width)
                        width = Qt.binding(function() { return editorColumn.firstColumnWidth })
                    }
                }
                CustomComboBox
                {
                    id: algoCombo
                    Layout.fillWidth: true
                    height: editorColumn.itemsHeight
                    textRole: ""
                    model: rgbMatrixEditor.algorithms
                    currentIndex: rgbMatrixEditor.algorithmIndex
                    onDisplayTextChanged:
                    {
                        rgbMatrixEditor.algorithmIndex = currentIndex
                        paramSection.sectionContents = null
                        if (displayText === "Text")
                            paramSection.sectionContents = textAlgoComponent
                        else if (displayText === "Image")
                            paramSection.sectionContents = imageAlgoComponent
                        else
                            paramSection.sectionContents = scriptAlgoComponent
                    }
                }

                IconButton
                {
                    width: UISettings.listItemHeight
                    height: width
                    imgSource: "qrc:/sequence.svg"
                    tooltip: qsTr("Save this matrix to a sequence")
                    onClicked: rgbMatrixEditor.saveToSequence()
                }

                // row 4
                RobotoText
                {
                    label: qsTr("Blend mode")
                    height: editorColumn.itemsHeight
                    onWidthChanged:
                    {
                        editorColumn.checkLabelWidth(width)
                        width = Qt.binding(function() { return editorColumn.firstColumnWidth })
                    }
                }
                CustomComboBox
                {
                    Layout.columnSpan: 2
                    Layout.fillWidth: true
                    height: editorColumn.itemsHeight
                    model: [
                        { mLabel: qsTr("Default (HTP)") },
                        { mLabel: qsTr("Mask") },
                        { mLabel: qsTr("Additive") },
                        { mLabel: qsTr("Subtractive") }
                    ]

                    currentIndex: rgbMatrixEditor.blendMode
                    onCurrentIndexChanged: rgbMatrixEditor.blendMode = currentIndex
                }

                // row 5
                RobotoText
                {
                    label: qsTr("Color mode")
                    height: editorColumn.itemsHeight
                    onWidthChanged:
                    {
                        editorColumn.checkLabelWidth(width)
                        width = Qt.binding(function() { return editorColumn.firstColumnWidth })
                    }
                }
                CustomComboBox
                {
                    Layout.columnSpan: 2
                    Layout.fillWidth: true
                    height: editorColumn.itemsHeight
                    model: [
                        { mLabel: qsTr("Default (RGB)") },
                        { mLabel: qsTr("White") },
                        { mLabel: qsTr("Amber") },
                        { mLabel: qsTr("UV") },
                        { mLabel: qsTr("Dimmer") },
                        { mLabel: qsTr("Shutter") }
                    ]

                    currentIndex: rgbMatrixEditor.controlMode
                    onCurrentIndexChanged: rgbMatrixEditor.controlMode = currentIndex
                }

                // row 6
                RobotoText
                {
                    id: colorLabel
                    label: qsTr("Colors")
                    visible: rgbMatrixEditor.algoColorsCount > 0 ? true : false
                    height: editorColumn.itemsHeight
                    onWidthChanged:
                    {
                        editorColumn.checkLabelWidth(width)
                        width = Qt.binding(function() { return editorColumn.firstColumnWidth })
                    }
                }

                Row
                {
                    //width: editorColumn.colWidth
                    Layout.columnSpan: 2
                    height: editorColumn.itemsHeight
                    spacing: 4

                    Rectangle
                    {
                        id: color1Button
                        width: UISettings.iconSizeDefault * 2
                        height: editorColumn.itemsHeight
                        radius: 5
                        border.color: color1MouseArea.containsMouse ? "white" : UISettings.bgLight
                        border.width: 2
                        visible: rgbMatrixEditor.algoColorsCount > 0 ? true : false

                        MouseArea
                        {
                            id: color1MouseArea
                            anchors.fill: parent
                            hoverEnabled: true
                            onClicked:
                            {
                                if (colorTool.visible)
                                    colorTool.hide()
                                else
                                    colorTool.showTool(0, color1Button)
                            }
                        }
                    }
                    Rectangle
                    {
                        width: UISettings.listItemHeight
                        height: width
                        color: "transparent"
                        visible: rgbMatrixEditor.algoColorsCount > 2 ? true : false
                    }

                    Rectangle
                    {
                        id: color2Button
                        width: UISettings.iconSizeDefault * 2
                        height: editorColumn.itemsHeight
                        radius: 5
                        border.color: color2MouseArea.containsMouse ? "white" : UISettings.bgLight
                        border.width: 2
                        visible: rgbMatrixEditor.algoColorsCount > 1 ? true : false

                        MouseArea
                        {
                            id: color2MouseArea
                            anchors.fill: parent
                            hoverEnabled: true
                            onClicked:
                            {
                                if (colorTool.visible)
                                    colorTool.hide()
                                else
                                    colorTool.showTool(1, color2Button)
                            }
                        }
                    }
                    IconButton
                    {
                        width: UISettings.listItemHeight
                        height: width
                        faSource: FontAwesome.fa_xmark
                        faColor: "darkred"
                        tooltip: qsTr("Reset color 2")
                        visible: rgbMatrixEditor.algoColorsCount > 1 ? true : false
                        onClicked:
                        {
                            color2Button.color = "transparent"
                            rgbMatrixEditor.resetColorAtIndex(1)
                        }
                    }
                }

                // row 7
                Rectangle
                {
                    id: colorRow1
                    height: editorColumn.itemsHeight
                    width: colorLabel.width
                    color: "transparent"
                    visible: rgbMatrixEditor.algoColorsCount > 4 ? true : false
                }

                Row
                {
                    Layout.columnSpan: 2
                    //width: editorColumn.colWidth
                    height: editorColumn.itemsHeight
                    spacing: 4
                    visible: rgbMatrixEditor.algoColorsCount > 4 ? true : false

                    Rectangle
                    {
                        id: color3Button
                        width: UISettings.iconSizeDefault * 2
                        height: editorColumn.itemsHeight
                        radius: 5
                        border.color: color3MouseArea.containsMouse ? "white" : UISettings.bgLight
                        border.width: 2
                        visible: rgbMatrixEditor.algoColorsCount > 2 ? true : false

                        MouseArea
                        {
                            id: color3MouseArea
                            anchors.fill: parent
                            hoverEnabled: true
                            onClicked:
                            {
                                if (colorTool.visible)
                                    colorTool.hide()
                                else
                                    colorTool.showTool(2, color3Button)
                            }
                        }
                    }
                    IconButton
                    {
                        width: UISettings.listItemHeight
                        height: width
                        faSource: FontAwesome.fa_xmark
                        faColor: "darkred"
                        tooltip: qsTr("Reset color 3")
                        visible: rgbMatrixEditor.algoColorsCount > 2 ? true : false
                        onClicked:
                        {
                            color3Button.color = "transparent"
                            rgbMatrixEditor.resetColorAtIndex(2)
                        }
                    }

                    Rectangle
                    {
                        id: color4Button
                        width: UISettings.iconSizeDefault * 2
                        height: editorColumn.itemsHeight
                        radius: 5
                        border.color: color4MouseArea.containsMouse ? "white" : UISettings.bgLight
                        border.width: 2
                        visible: rgbMatrixEditor.algoColorsCount > 3 ? true : false

                        MouseArea
                        {
                            id: color4MouseArea
                            anchors.fill: parent
                            hoverEnabled: true
                            onClicked:
                            {
                                if (colorTool.visible)
                                    colorTool.hide()
                                else
                                    colorTool.showTool(3, color4Button)
                            }
                        }
                    }
                    IconButton
                    {
                        width: UISettings.listItemHeight
                        height: width
                        faSource: FontAwesome.fa_xmark
                        faColor: "darkred"
                        tooltip: qsTr("Reset color 4")
                        visible: rgbMatrixEditor.algoColorsCount > 3 ? true : false
                        onClicked:
                        {
                            color4Button.color = "transparent"
                            rgbMatrixEditor.resetColorAtIndex(3)
                        }
                    }
                }

                // row 8
                Rectangle
                {
                    id: colorRow2
                    height: editorColumn.itemsHeight
                    width: colorLabel.width
                    color: "transparent"
                    visible: rgbMatrixEditor.algoColorsCount > 4 ? true : false
                }

                Row
                {
                    Layout.columnSpan: 2
                    //width: editorColumn.colWidth
                    height: editorColumn.itemsHeight
                    spacing: 4
                    visible: rgbMatrixEditor.algoColorsCount > 4 ? true : false

                    Rectangle
                    {
                        id: color5Button
                        width: UISettings.iconSizeDefault * 2
                        height: editorColumn.itemsHeight
                        radius: 5
                        border.color: color5MouseArea.containsMouse ? "white" : UISettings.bgLight
                        border.width: 2
                        visible: rgbMatrixEditor.algoColorsCount > 4 ? true : false

                        MouseArea
                        {
                            id: color5MouseArea
                            anchors.fill: parent
                            hoverEnabled: true
                            onClicked:
                            {
                                if (colorTool.visible)
                                    colorTool.hide()
                                else
                                    colorTool.showTool(4, color5Button)
                            }
                        }
                    }
                    IconButton
                    {
                        width: UISettings.listItemHeight
                        height: width
                        faSource: FontAwesome.fa_xmark
                        faColor: "darkred"
                        tooltip: qsTr("Reset color 5")
                        visible: rgbMatrixEditor.algoColorsCount > 4 ? true : false
                        onClicked:
                        {
                            color5Button.color = "transparent"
                            rgbMatrixEditor.resetColorAtIndex(4)
                        }
                    }
                }
            }

            SectionBox
            {
                id: paramSection
                width: editorColumn.colWidth - 5
                visible: sectionContents ? true : false

                sectionLabel: qsTr("Parameters")
                sectionContents: null
            }

            SectionBox
            {
                id: speedSection
                width: editorColumn.colWidth - 5
                isExpanded: false
                sectionLabel: qsTr("Speed")
                sectionContents:
                    GridLayout
                    {
                        width: parent.width
                        columns: 3
                        columnSpacing: 5
                        rowSpacing: 4

                        function showTimeTool(item, titleLabel, timeLabel, type)
                        {
                            timeEditTool.allowFractions = QLCFunction.ByTwoFractions
                            timeEditTool.show(-1, item.mapToItem(mainView, 0, 0).y - timeEditTool.height,
                                              titleLabel, timeLabel, type)
                        }

                        // Row 1
                        RobotoText
                        {
                            id: fiLabel
                            label: qsTr("Steps fade in")
                            height: UISettings.listItemHeight
                        }

                        Rectangle
                        {
                            Layout.fillWidth: true
                            height: UISettings.listItemHeight
                            color: UISettings.bgMedium

                            RobotoText
                            {
                                id: fiTimeLabel
                                x: 3
                                height: parent.height
                                label: TimeUtils.timeToQlcString(rgbMatrixEditor.fadeInSpeed, rgbMatrixEditor.tempoType)
                            }
                            MouseArea
                            {
                                anchors.fill: parent
                                onDoubleClicked: showTimeTool(this, fiLabel.label, fiTimeLabel.label, QLCFunction.FadeIn)
                            }
                        }

                        IconButton
                        {
                            width: height
                            height: UISettings.listItemHeight
                            faSource: FontAwesome.fa_clock
                            faColor: UISettings.fgMain
                            onClicked: showTimeTool(this, fiLabel.label, fiTimeLabel.label, QLCFunction.FadeIn)
                        }

                        // Row 2
                        RobotoText
                        {
                            id: hLabel
                            height: UISettings.listItemHeight
                            label: qsTr("Steps hold")
                        }

                        Rectangle
                        {
                            Layout.fillWidth: true
                            height: UISettings.listItemHeight
                            color: UISettings.bgMedium

                            RobotoText
                            {
                                id: hTimeLabel
                                x: 3
                                height: parent.height
                                label: TimeUtils.timeToQlcString(rgbMatrixEditor.holdSpeed, rgbMatrixEditor.tempoType)
                            }
                            MouseArea
                            {
                                anchors.fill: parent
                                onDoubleClicked: showTimeTool(this, hLabel.label, hTimeLabel.label, QLCFunction.Hold)
                            }
                        }

                        IconButton
                        {
                            width: height
                            height: UISettings.listItemHeight
                            faSource: FontAwesome.fa_clock
                            faColor: UISettings.fgMain
                            onClicked: showTimeTool(this, hLabel.label, hTimeLabel.label, QLCFunction.Hold)
                        }

                        // Row 3
                        RobotoText
                        {
                            id: foLabel
                            height: UISettings.listItemHeight
                            label: qsTr("Steps fade out")
                        }

                        Rectangle
                        {
                            Layout.fillWidth: true
                            height: UISettings.listItemHeight
                            color: UISettings.bgMedium

                            RobotoText
                            {
                                id: foTimeLabel
                                x: 3
                                height: parent.height
                                label: TimeUtils.timeToQlcString(rgbMatrixEditor.fadeOutSpeed, rgbMatrixEditor.tempoType)
                            }
                            MouseArea
                            {
                                anchors.fill: parent
                                onDoubleClicked: showTimeTool(this, foLabel.label, foTimeLabel.label, QLCFunction.FadeOut)
                            }
                        }

                        IconButton
                        {
                            width: height
                            height: UISettings.listItemHeight
                            faSource: FontAwesome.fa_clock
                            faColor: UISettings.fgMain
                            onClicked: showTimeTool(this, foLabel.label, foTimeLabel.label, QLCFunction.FadeOut)
                        }

                        // Row 4
                        RobotoText
                        {
                            id: ttLabel
                            height: UISettings.listItemHeight
                            label: qsTr("Tempo type")
                        }
                        CustomComboBox
                        {
                            Layout.columnSpan: 2
                            Layout.fillWidth: true
                            height: UISettings.listItemHeight
                            model: [
                                { mLabel: qsTr("Time"), mValue: QLCFunction.Time },
                                { mLabel: qsTr("Beats"), mValue: QLCFunction.Beats }
                            ]

                            currValue: rgbMatrixEditor.tempoType
                            onValueChanged: rgbMatrixEditor.tempoType = value
                        }
                        Item
                        {
                            width: UISettings.listItemHeight
                            height: width
                        }
                    }
            }

            SectionBox
            {
                id: directionSection
                width: editorColumn.colWidth - 5
                sectionLabel: qsTr("Order and direction")
                sectionContents:
                    GridLayout
                    {
                        width: parent.width
                        columns: 4
                        columnSpacing: 4
                        rowSpacing: 4

                        // Row 1
                        IconPopupButton
                        {
                            model: [
                                { mLabel: qsTr("Loop"), faIcon: FontAwesome.fa_retweet, mValue: QLCFunction.Loop },
                                { mLabel: qsTr("Single Shot"), faIcon: FontAwesome.fa_right_long, mValue: QLCFunction.SingleShot },
                                { mLabel: qsTr("Ping Pong"), faIcon: FontAwesome.fa_right_left, mValue: QLCFunction.PingPong }
                            ]

                            currValue: rgbMatrixEditor.runOrder
                            onValueChanged: rgbMatrixEditor.runOrder = value
                        }
                        RobotoText
                        {
                            label: qsTr("Run Order")
                            Layout.fillWidth: true
                        }

                        IconPopupButton
                        {
                            model: [
                                { mLabel: qsTr("Forward"), faIcon: FontAwesome.fa_angles_right, mValue: QLCFunction.Forward },
                                { mLabel: qsTr("Backward"), faIcon: FontAwesome.fa_angles_left, mValue: QLCFunction.Backward }
                            ]

                            currValue: rgbMatrixEditor.direction
                            onValueChanged: rgbMatrixEditor.direction = value
                        }
                        RobotoText
                        {
                            label: qsTr("Direction")
                            Layout.fillWidth: true
                        }

                    } // GridLayout
            }
        } // Column
        ScrollBar.vertical: CustomScrollBar { id: sbar }
    } // Flickable

    /* *************************************************************
     * Here starts all the Algorithm-specific Component definitions,
     * loaded at runtime depending on the selected algorithm
     * *********************************************************** */

    /* *************************************************************
     * **************** Text Algorithm parameters **************** */
    Component
    {
        id: textAlgoComponent
        GridLayout
        {
            columns: 2
            columnSpacing: 5

            // Row 1
            RobotoText
            {
                height: UISettings.listItemHeight
                label: qsTr("Text")
            }

            Rectangle
            {
                Layout.fillWidth: true
                height: editorColumn.itemsHeight
                color: "transparent"

                Rectangle
                {
                    height: parent.height
                    width: parent.width - fontButton.width - 5
                    radius: 3
                    color: UISettings.bgMedium
                    border.color: "#222"

                    TextInput
                    {
                        id: algoTextEdit
                        anchors.fill: parent
                        anchors.margins: 4
                        anchors.verticalCenter: parent.verticalCenter
                        text: rgbMatrixEditor.algoText
                        font.family: rgbMatrixEditor.algoTextFont.font.family
                        font.bold: rgbMatrixEditor.algoTextFont.font.bold
                        font.italic: rgbMatrixEditor.algoTextFont.font.italic
                        font.pixelSize: UISettings.textSizeDefault * 0.8
                        color: "white"

                        onTextEdited: rgbMatrixEditor.algoText = text
                    }
                }
                IconButton
                {
                    id: fontButton
                    width: UISettings.iconSizeMedium
                    height: width
                    anchors.right: parent.right
                    faSource: FontAwesome.fa_font
                    faColor: "lightcyan"

                    onClicked: fontDialog.visible = true

                    FontDialog
                    {
                        id: fontDialog
                        title: qsTr("Please choose a font")
                        selectedFont: rgbMatrixEditor.algoTextFont
                        visible: false

                        onAccepted:
                        {
                            console.log("Selected font: " + selectedFont)
                            rgbMatrixEditor.algoTextFont = selectedFont
                        }
                    }
                }
            }

            // Row 2
            RobotoText
            {
                height: UISettings.listItemHeight
                label: qsTr("Animation")
            }
            CustomComboBox
            {
                Layout.fillWidth: true
                height: editorColumn.itemsHeight
                model: [
                    { mLabel: qsTr("Letters") },
                    { mLabel: qsTr("Horizontal") },
                    { mLabel: qsTr("Vertical") }
                ]

                currentIndex: rgbMatrixEditor.animationStyle
                onCurrentIndexChanged: rgbMatrixEditor.animationStyle = currentIndex
            }

            // Row 3
            RobotoText
            {
                height: UISettings.listItemHeight
                label: qsTr("Offset")
            }
            Rectangle
            {
                Layout.fillWidth: true
                height: editorColumn.itemsHeight
                color: "transparent"

                Row
                {
                    id: toffRow
                    spacing: 20
                    anchors.fill: parent

                    property size algoOffset: rgbMatrixEditor.algoOffset

                    RobotoText { height: UISettings.listItemHeight; label: qsTr("X") }
                    CustomSpinBox
                    {
                        height: parent.height
                        from: -255
                        to: 255
                        value: toffRow.algoOffset.width
                        onValueModified:
                        {
                            var newOffset = toffRow.algoOffset
                            newOffset.width = value
                            rgbMatrixEditor.algoOffset = newOffset
                        }
                    }

                    RobotoText { height: UISettings.listItemHeight; label: qsTr("Y") }
                    CustomSpinBox
                    {
                        height: parent.height
                        from: -255
                        to: 255
                        value: toffRow.algoOffset.height
                        onValueModified:
                        {
                            var newOffset = toffRow.algoOffset
                            newOffset.height = value
                            rgbMatrixEditor.algoOffset = newOffset
                        }
                    }
                }
            }
        }
    }

    /* *************************************************************
     * **************** Image Algorithm parameters *************** */
    Component
    {
        id: imageAlgoComponent

        GridLayout
        {
            id: imageAlgoGrid
            columns: 2
            columnSpacing: 5

            // Row 1
            RobotoText
            {
                height: UISettings.listItemHeight
                label: qsTr("Image")
            }
            Rectangle
            {
                Layout.fillWidth: true
                height: editorColumn.itemsHeight
                color: "transparent"

                Rectangle
                {
                    height: parent.height
                    width: parent.width - imgButton.width - 5
                    radius: 3
                    color: UISettings.bgMedium
                    border.color: UISettings.bgStrong
                    clip: true

                    TextInput
                    {
                        id: algoTextEdit
                        anchors.fill: parent
                        anchors.margins: 4
                        anchors.verticalCenter: parent.verticalCenter
                        text: rgbMatrixEditor.algoImagePath
                        font.pixelSize: UISettings.textSizeDefault
                        color: "white"

                        onTextEdited: rgbMatrixEditor.algoImagePath = text
                    }
                }
                IconButton
                {
                    id: imgButton
                    width: UISettings.iconSizeMedium
                    height: width
                    anchors.right: parent.right
                    faSource: FontAwesome.fa_image
                    faColor: "lightyellow"
                    tooltip: qsTr("Set a custom background")

                    onClicked: fileDialog.visible = true

                    FileDialog
                    {
                        id: fileDialog
                        visible: false
                        title: qsTr("Select an image")
                        nameFilters: [ "Image files (*.png *.bmp *.jpg *.jpeg *.gif)", "All files (*)" ]

                        onAccepted: rgbMatrixEditor.algoImagePath = fileDialog.selectedFile
                    }
                }
            }

            // Row 2
            RobotoText
            {
                height: UISettings.listItemHeight
                label: qsTr("Animation")
            }
            CustomComboBox
            {
                Layout.fillWidth: true
                height: editorColumn.itemsHeight
                model: [
                    { mLabel: qsTr("Static") },
                    { mLabel: qsTr("Horizontal") },
                    { mLabel: qsTr("Vertical") },
                    { mLabel: qsTr("Animation") }
                ]

                currentIndex: rgbMatrixEditor.animationStyle
                onCurrentIndexChanged: rgbMatrixEditor.animationStyle = currentIndex
            }

            // Row 3
            RobotoText
            {
                height: UISettings.listItemHeight
                label: qsTr("Offset")
            }
            Rectangle
            {
                Layout.fillWidth: true
                height: editorColumn.itemsHeight
                color: "transparent"

                Row
                {
                    id: ioffRow
                    spacing: 20
                    anchors.fill: parent

                    property size algoOffset: rgbMatrixEditor.algoOffset

                    RobotoText { height: UISettings.listItemHeight; label: qsTr("X") }
                    CustomSpinBox
                    {
                        height: parent.height
                        from: -255
                        to: 255
                        value: ioffRow.algoOffset.width
                        onValueModified:
                        {
                            var newOffset = ioffRow.algoOffset
                            newOffset.width = value
                            rgbMatrixEditor.algoOffset = newOffset
                        }
                    }

                    RobotoText { height: UISettings.listItemHeight; label: qsTr("Y") }
                    CustomSpinBox
                    {
                        height: parent.height
                        from: -255
                        to: 255
                        value: ioffRow.algoOffset.height
                        onValueModified:
                        {
                            var newOffset = ioffRow.algoOffset
                            newOffset.height = value
                            rgbMatrixEditor.algoOffset = newOffset
                        }
                    }
                }
            }
        }
    }

    /* ************************************************************ */
    /* ***************  Script Algorithm parameters *************** */
    Component
    {
        id: scriptAlgoComponent

        GridLayout
        {
            id: scriptAlgoGrid
            columns: 2
            columnSpacing: 5

            function addLabel(text)
            {
                labelComponent.createObject(scriptAlgoGrid,
                               {"propName": text });
                if (labelComponent.status !== Component.Ready)
                    console.log("Label component is not ready !!")
            }

            function addComboBox(propName, model, currentIndex)
            {
                comboComponent.createObject(scriptAlgoGrid,
                               {"propName": propName, "model": model, "currentIndex": currentIndex });
                if (comboComponent.status !== Component.Ready)
                    console.log("Combo component is not ready !!")
            }

            function addSpinBox(propName, min, max, currentValue)
            {
                spinComponent.createObject(scriptAlgoGrid,
                              {"propName": propName, "from": min, "to": max, "value": currentValue });
                if (spinComponent.status !== Component.Ready)
                    console.log("Spin component is not ready !!")
            }

            function addDoubleSpinBox(propName, currentValue)
            {
                doubleSpinComponent.createObject(scriptAlgoGrid,
                              {"propName": propName, "realValue": currentValue });
                if (spinComponent.status !== Component.Ready)
                    console.log("Double spin component is not ready !!")
            }

            function addTextEdit(propName, currentText)
            {
                textEditComponent.createObject(scriptAlgoGrid,
                               {"propName": propName, "text": currentText });
                if (comboComponent.status !== Component.Ready)
                    console.log("TextEdit component is not ready !!")
            }

            Component.onCompleted:
            {
                rgbMatrixEditor.createScriptObjects(scriptAlgoGrid)
            }
        }
    }

    // Script algorithm text label
    Component
    {
        id: labelComponent

        RobotoText
        {
            implicitHeight: UISettings.listItemHeight
            implicitWidth: width
            property string propName

            label: propName
        }
    }

    // Script algorithm combo box property
    Component
    {
        id: comboComponent

        CustomComboBox
        {
            Layout.fillWidth: true
            property string propName

            onCurrentTextChanged: rgbMatrixEditor.setScriptStringProperty(propName, currentText)
        }
    }

    // Script algorithm spin box property
    Component
    {
        id: spinComponent

        CustomSpinBox
        {
            Layout.fillWidth: true
            property string propName

            onValueModified: rgbMatrixEditor.setScriptIntProperty(propName, value)
        }
    }

    // Script algorithm float box property
    Component
    {
        id: doubleSpinComponent

        CustomDoubleSpinBox
        {
            Layout.fillWidth: true
            property string propName

            decimals: 3
            suffix: ""
            onRealValueChanged: rgbMatrixEditor.setScriptFloatProperty(propName, realValue)
        }
    }

    // Script algorithm combo box property
    Component
    {
        id: textEditComponent

        CustomTextEdit
        {
            Layout.fillWidth: true
            property string propName

            onTextEdited: rgbMatrixEditor.setScriptStringProperty(propName, text)
        }
    }
}
