/*!
 *
 * Copyright (c) 2021-2025 Diality Inc. - All Rights Reserved.
 * \copyright
 * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN
 * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER.
 *
 * \file    ValueAdjuster.qml
 * \author  (last)      Nico Ramirez
 * \date    (last)      21-Aug-2025
 * \author  (original)  Nico Ramirez
 * \date    (original)  21-Aug-2025
 *
 */

import "qrc:/globals"
import "qrc:/components"

import QtQuick 2.12
import QtQuick.Controls 2.2

Item { id: _root
    property real   decimal     : 0
    property real   minimum     : 0
    property real   maximum     : 0
    property real   value       : 0
    property real   defaultValue: 0
    property real   step        : 0
    property bool   isActive    : false
    property bool   editable    : true
    property bool   canOff      : false
    property bool   canRefresh  : false

    // fix floating-point precision issue
    readonly property real stepVal  : Math.round(step       * 100) / 100
    readonly property real minVal   : Math.round(minimum    * 100) / 100
    readonly property real val      : Math.round(value      * 100) / 100

    readonly property bool canIncrement  : isActive ? value  < maximum : true
    readonly property bool canDecrement  : isActive ? canOff ? value > 0 :
                                                               value > minimum : true

    signal didChange        (real vValue)
    signal didActiveChange  (bool vState)

    onIsActiveChanged             : {
        if ( canRefresh )   { canRefresh = false; return;   }

        if ( isActive )     { didChange(_root.defaultValue) }
    }

    function refresh()      { canRefresh    = true          }

    function clear()        { didActiveChange(false)        }

    function increment() {
        let tValue = value
        if ( ! isActive )   { didActiveChange(true); return;                    }

        if ( canOff )       { tValue = val < minVal ? minVal : val + stepVal    }
        else                { tValue += stepVal                                 }

        didChange(tValue)

    }

    function decrement(vValue) {
        let tValue = value
        if ( ! isActive )   { didActiveChange(true); return;            }

        if ( canOff )       { tValue = val > minVal ? val - stepVal : 0 }
        else                { tValue -= stepVal                         }

        didChange(tValue)
    }

    Text { id: _text
        anchors.centerIn: parent
        text            : _root.isActive ? _root.canOff ? _root.value === 0 ?
                                                          qsTr("OFF") :
                                                          _root.value.toFixed( _root.decimal ) :
                                        _root.value.toFixed( _root.decimal ) : Variables.emptyEntry
        color           : Colors.offWhite
        font.pixelSize  : Fonts.fontPixelValueControl
    }

    Slider { id: _slider
        property real pos           : 0

        anchors.fill        : parent
        anchors.rightMargin : Variables.defaultMargin * 3
        anchors.leftMargin  : Variables.defaultMargin * 2
        anchors.topMargin   : 5
        enabled             : _root.editable
        visible             : enabled
        opacity             : 0
        stepSize            : _root.step
        from                : _root.minimum .toFixed ( _root.decimal )
        to                  : _root.maximum .toFixed ( _root.decimal )
        value               : _root.value   .toFixed ( _root.decimal )
        snapMode            : Slider.SnapOnRelease

        background: Rectangle {
            color: "transparent"
            Rectangle {
                anchors{
                    top         : parent.top
                    topMargin   : 1.5
                    left        : parent.left
                    right       : parent.right
                    rightMargin : Variables.defaultMargin * -1
                }
                height  : 1
                width   : parent.width
                color   : Colors.panelBorderColor
            }
        }

        handle: Rectangle { id: _knob
            width   : 20
            height  : 4
            radius  : height
            color   : Colors.borderButton
            x       : _slider.pos * _slider.width
        }

        MouseArea { id: _sliderMouseArea
            property bool grabbed: false

            anchors.fill        : parent
            pressAndHoldInterval: 0

            onClicked: {
                if ( _root.editable ) { didActiveChange(true); focus = true }

                _slider.opacity = 0
            }

            onReleased: {
                _sliderMouseArea.grabbed = true
.                grabbed = false
                _slider.opacity = 0
            }

            onPressAndHold: {
                if ( _root.editable ) { didActiveChange(true); focus = true }

                _sliderMouseArea.grabbed = true
            }

            onPositionChanged: {
                if (grabbed) {
                    if ( _slider.opacity === 0 ) { _animator.start() }

                    _slider.pos = Math.max(0, Math.min(1, mouse.x / parent.width))
                    let raw =  _slider.from + _slider.pos * (_slider.to - _slider.from)
                    let stepped = Math.round((raw - _slider.from) / _root.step) * _root.step + _slider.from
                    didChange(stepped)
                }
            }

            onExited: {
                if ( ! _sliderMouseArea.grabbed ) {
                    _animator.stop()
                    _slider.opacity = 0
                }
            }
        }

        OpacityAnimator { id: _animator
            target  : _slider
            from    : 0
            to      : 1
            duration: 350
            running : _sliderMouseArea.grabbed
        }

        Behavior on opacity { NumberAnimation { duration: 200 } }
    }

    IconButton { id: _leftArrow
        anchors {
            verticalCenter  : _root.verticalCenter
            left            : _root.left
            leftMargin      : Variables.defaultMargin
        }
        iconSize                : Variables.circleButtonDefaultDiameter
        enabled                 : _root.canDecrement
        visible                 : _root.editable
        iconImageSource         : enabled ? "qrc:/images/iArrowLeft" :
                                            "qrc:/images/iArrowLeftDisabled"
        onClicked               : decrement()
    }

    IconButton { id: _rightArrow
        anchors {
            verticalCenter  : _root.verticalCenter
            right           : _root.right
            rightMargin     : Variables.defaultMargin
        }
        iconSize                : Variables.circleButtonDefaultDiameter
        enabled                 : _root.canIncrement
        visible                 : _root.editable
        iconImageSource         : enabled ? "qrc:/images/iArrowRight" :
                                            "qrc:/images/iArrowRightDisabled"
        onClicked               : increment()
    }
}
