Option Strict On
Option Explicit On

Imports System
Imports Nexamas.UI.Architecture
Imports Nexamas.UI.Components
Imports Nexamas.UI.Composition
Imports Nexamas.UI.General
Imports Nexamas.UI.Layout
Imports Nexamas.UI.Rendering
Imports Nexamas.UI.Theming
Imports Nexamas.UI.Values
Imports SkiaSharp

Namespace Nexamas.UI.Controls

    Partial Public NotInheritable Class MASProgressBar
#Region "Core Properties"

        Public Property Minimum As Double
            Get
                Return _minimum
            End Get
            Set(value As Double)
                Dim nextMinimum As Double = NormalizeRangeEndpoint(value, 0.0R)
                If NearlyEqual(_minimum, nextMinimum) Then Return

                _minimum = nextMinimum
                Dim valueChanged As Boolean = NormalizeRange()
                StopValueMotion(syncToSemanticValue:=True)
                If valueChanged Then RaiseEvent ValueChanged(Me, EventArgs.Empty)
                InvalidateVisual()
            End Set
        End Property

        Public Property Maximum As Double
            Get
                Return _maximum
            End Get
            Set(value As Double)
                Dim nextMaximum As Double = NormalizeRangeEndpoint(value, 100.0R)
                If NearlyEqual(_maximum, nextMaximum) Then Return

                _maximum = nextMaximum
                Dim valueChanged As Boolean = NormalizeRange()
                StopValueMotion(syncToSemanticValue:=True)
                If valueChanged Then RaiseEvent ValueChanged(Me, EventArgs.Empty)
                InvalidateVisual()
            End Set
        End Property

        Public Property Value As Double
            Get
                Return _value
            End Get
            Set(v As Double)
                Dim nv As Double = MASProgressBarValuePolicy.NormalizeValue(v, _minimum, _maximum)
                If Math.Abs(_value - nv) < 0.0000001R Then Return

                Dim previousValue As Double = _value
                _value = nv
                StartValueMotion(previousValue, _value)
                RaiseEvent ValueChanged(Me, EventArgs.Empty)
                InvalidateVisual()
            End Set
        End Property

        Public Property VisualState As MASProgressBarState
            Get
                Return _visualState
            End Get
            Set(value As MASProgressBarState)
                Dim nextState As MASProgressBarState = MASProgressBarValuePolicy.NormalizeVisualState(value)
                If _visualState = nextState Then Return
                _visualState = nextState
                InvalidateVisual()
            End Set
        End Property

        ''' <summary>
        ''' Optional MASLabel supplied by the application. The progress bar imports and arranges this MASLabel as a child;
        ''' it does not create a System.Windows.Forms.Label or any parallel text renderer.
        ''' </summary>
        Public Property Label As MASLabel
            Get
                Return _label
            End Get
            Set(value As MASLabel)
                If Object.ReferenceEquals(_label, value) Then Return

                If _label IsNot Nothing Then
                    RemoveHandler _label.TextChanged, AddressOf OnLabelContentChanged
                    UnregisterChild(_label)
                End If

                _label = value

                If _label IsNot Nothing Then
                    RegisterChild(_label)
                    AddHandler _label.TextChanged, AddressOf OnLabelContentChanged
                End If

                ArrangeLabel()
                InvalidateVisual()
            End Set
        End Property

        ''' <summary>
        ''' Decides whether the imported MASLabel is placed above, below, beside, or inside the progress track.
        ''' </summary>
        Public Property LabelPlacement As MASProgressBarLabelPlacement
            Get
                Return _labelPlacement
            End Get
            Set(value As MASProgressBarLabelPlacement)
                Dim nextValue As MASProgressBarLabelPlacement = NormalizeLabelPlacement(value)
                If _labelPlacement = nextValue Then Return

                _labelPlacement = nextValue
                ArrangeLabel()
                InvalidateVisual()
            End Set
        End Property

        ''' <summary>
        ''' Logical spacing between the progress track and an outside label. Ignored for None and InsideCenter.
        ''' </summary>
        <Global.System.ComponentModel.EditorBrowsable(Global.System.ComponentModel.EditorBrowsableState.Advanced)>
        Friend Property LabelGap As Single
            Get
                Return _labelGap
            End Get
            Set(value As Single)
                Dim nextValue As Single = SafeNonNegative(value)
                If NearlyEqual(_labelGap, nextValue) Then Return

                _labelGap = nextValue
                ArrangeLabel()
                InvalidateVisual()
            End Set
        End Property

        ''' <summary>
        ''' Optional logical label slot size. For Top/Bottom this is label height; for Left/Right this is label width.
        ''' A value of 0 keeps the Nexamas UI recommended label extent.
        ''' </summary>
        <Global.System.ComponentModel.EditorBrowsable(Global.System.ComponentModel.EditorBrowsableState.Advanced)>
        Friend Property LabelExtent As Single
            Get
                Return _labelExtent
            End Get
            Set(value As Single)
                Dim nextValue As Single = SafeNonNegative(value)
                If NearlyEqual(_labelExtent, nextValue) Then Return

                _labelExtent = nextValue
                ArrangeLabel()
                InvalidateVisual()
            End Set
        End Property

        ''' <summary>
        ''' When enabled, the progress bar sets the imported MASLabel alignment to match its assigned slot.
        ''' Disable it when the external project wants to fully control MASLabel text alignment.
        ''' </summary>
        Public Property AutoArrangeLabelAlignment As Boolean
            Get
                Return _autoArrangeLabelAlignment
            End Get
            Set(value As Boolean)
                If _autoArrangeLabelAlignment = value Then Return

                _autoArrangeLabelAlignment = value
                ArrangeLabel()
                InvalidateVisual()
            End Set
        End Property

        ''' <summary>
        ''' Advanced progress-track recommendation preset used by RecommendedSize. Public element sizing
        ''' should use WithSize(MASSize) and the shared MASSize fluent helpers.
        ''' </summary>
        <Global.System.ComponentModel.EditorBrowsable(Global.System.ComponentModel.EditorBrowsableState.Advanced)>
        Friend Property SizeMode As MASProgressBarSize
            Get
                Return _sizeMode
            End Get
            Set(value As MASProgressBarSize)
                Dim nextValue As MASProgressBarSize = NormalizeSizeMode(value)
                If _sizeMode = nextValue Then Return

                _sizeMode = nextValue
                InvalidateVisual()
            End Set
        End Property

        ''' <summary>
        ''' Controls whether MASProgressBar paints only the progress track or also paints a themed container field.
        ''' The default is None so MASProgressBar stays a pure progress-track control. Operation-level containers
        ''' are owned by MASOperationProgressBox.
        ''' </summary>
        Public Property FrameMode As MASProgressBarFrameMode
            Get
                Return _frameMode
            End Get
            Set(value As MASProgressBarFrameMode)
                Dim nextValue As MASProgressBarFrameMode = NormalizeFrameMode(value)
                If _frameMode = nextValue Then Return

                _frameMode = nextValue
                ArrangeLabel()
                InvalidateVisual()
            End Set
        End Property

        ''' <summary>
        ''' Surface material key used by the automatically drawn progress container.
        ''' The default is MASSurfaceMaterialIds.PlatformDefault so the container consumes the platform surface material,
        ''' while the inner progress track and fill continue to use IMASProgressTheme.
        ''' </summary>
        Public Property ContainerSurfaceMaterialKey As String
            Get
                Return _containerSurfaceMaterialKey
            End Get
            Set(value As String)
                Dim nextValue As String = NormalizeContainerMaterialKey(value)
                If String.Equals(_containerSurfaceMaterialKey, nextValue, StringComparison.OrdinalIgnoreCase) Then Return

                _containerSurfaceMaterialKey = nextValue
                InvalidateVisual()
            End Set
        End Property

        ''' <summary>
        ''' Border strength used by the themed progress container material. ThemeDefault delegates to surface theme chrome.
        ''' </summary>
        Public Property ContainerBorderStrength As MASSurfaceStrength
            Get
                Return _containerBorderStrength
            End Get
            Set(value As MASSurfaceStrength)
                Dim nextValue As MASSurfaceStrength = NormalizeSurfaceStrength(value)
                If _containerBorderStrength = nextValue Then Return

                _containerBorderStrength = nextValue
                InvalidateVisual()
            End Set
        End Property

        ''' <summary>
        ''' Surface strength used by the themed progress container material. ThemeDefault delegates to surface theme chrome.
        ''' </summary>
        Public Property ContainerSurfaceStrength As MASSurfaceStrength
            Get
                Return _containerSurfaceStrength
            End Get
            Set(value As MASSurfaceStrength)
                Dim nextValue As MASSurfaceStrength = NormalizeSurfaceStrength(value)
                If _containerSurfaceStrength = nextValue Then Return

                _containerSurfaceStrength = nextValue
                InvalidateVisual()
            End Set
        End Property

#End Region
    End Class

End Namespace
