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 "Layout Participant"

        Friend Function GetPreferredLayoutSize(context As MASLayoutMeasureContext) As SKSize Implements IMASLayoutParticipant.GetPreferredLayoutSize
            Return MeasureIntrinsicSize(CreateSizeContext(context), SizeIntent).DesiredSize
        End Function

        Friend Function GetMinLayoutSize(context As MASLayoutMeasureContext) As SKSize Implements IMASLayoutParticipant.GetMinLayoutSize
            Return MeasureIntrinsicSize(CreateSizeContext(context), SizeIntent).MinSize
        End Function

        Friend Function MeasureIntrinsicSize(context As MASSizeContext, intent As MASSize) As MASSizeResult Implements IMASIntrinsicSizeContract.MeasureIntrinsicSize
            Dim safeContext As MASSizeContext = MASIntrinsicControlSizeMetrics.EnsureContext(context)
            Dim desired As SKSize = RecommendedSize
            Dim minimum As SKSize = ResolveIntrinsicMinimumSize()
            Dim frameExtra As Single = ResolveFrameExtraLogical(_frameMode)

            Return MASSizeResolver.FromMeasured(
                desiredSize:=desired,
                minSize:=minimum,
                maxSize:=New SKSize(Single.PositiveInfinity, Single.PositiveInfinity),
                intent:=intent,
                context:=safeContext,
                canGrowWidth:=True,
                canGrowHeight:=False,
                contentInset:=MASIntrinsicControlSizeMetrics.CreateProgressBarContentInset(frameExtra),
                visualOverflowInset:=MASIntrinsicControlSizeMetrics.DefaultVisualOverflowInset,
                hitOverflowInset:=MASIntrinsicControlSizeMetrics.CreateTouchHitOverflowInset(desired, safeContext.Density),
                isFallback:=False)
        End Function

        Private Function ResolveIntrinsicMinimumSize() As SKSize
            Dim placement As MASProgressBarLabelPlacement = ResolveActiveLabelPlacement()

            Return MASIntrinsicControlSizeMetrics.ResolveProgressBarMinimumSize(
                labelAxis:=ResolveIntrinsicLabelAxis(placement),
                labelGap:=ResolveOutsideGap(placement),
                labelExtent:=ResolveLabelExtent(placement),
                frameExtra:=ResolveFrameExtraLogical(_frameMode))
        End Function

        Private Shared Function CreateSizeContext(context As MASLayoutMeasureContext) As MASSizeContext
            If context Is Nothing Then Return New MASSizeContext(New SKSize(Single.PositiveInfinity, Single.PositiveInfinity))
            Return context.ToSizeContext()
        End Function

#End Region

#Region "Recommended Size"

        Private Shared Function ResolveRecommendedSize(sizeMode As MASProgressBarSize,
                                                       placement As MASProgressBarLabelPlacement,
                                                       frameMode As MASProgressBarFrameMode) As SKSize
            Return MASIntrinsicControlSizeMetrics.ResolveProgressBarDesiredSize(
                trackWidth:=ResolveRecommendedWidth(sizeMode),
                trackHeight:=ResolveTrackHeight(sizeMode),
                labelAxis:=ResolveIntrinsicLabelAxis(placement),
                labelGap:=ResolveDefaultLabelGap(placement),
                labelExtent:=ResolveDefaultLabelExtent(placement),
                frameExtra:=ResolveFrameExtraLogical(frameMode))
        End Function

        Private Shared Function ResolveIntrinsicLabelAxis(placement As MASProgressBarLabelPlacement) As MASIntrinsicControlSizeMetrics.MASProgressBarIntrinsicLabelAxis
            Select Case NormalizeLabelPlacement(placement)
                Case MASProgressBarLabelPlacement.Top, MASProgressBarLabelPlacement.Bottom
                    Return MASIntrinsicControlSizeMetrics.MASProgressBarIntrinsicLabelAxis.VerticalBlock
                Case MASProgressBarLabelPlacement.Left, MASProgressBarLabelPlacement.Right
                    Return MASIntrinsicControlSizeMetrics.MASProgressBarIntrinsicLabelAxis.HorizontalSide
                Case Else
                    Return MASIntrinsicControlSizeMetrics.MASProgressBarIntrinsicLabelAxis.None
            End Select
        End Function

        Private Shared Function ResolveDefaultLabelGap(placement As MASProgressBarLabelPlacement) As Single
            Select Case NormalizeLabelPlacement(placement)
                Case MASProgressBarLabelPlacement.Top,
                     MASProgressBarLabelPlacement.Bottom,
                     MASProgressBarLabelPlacement.Left,
                     MASProgressBarLabelPlacement.Right
                    Return ProgressBarTokens.LabelGap
                Case Else
                    Return 0.0F
            End Select
        End Function

        Private Shared Function ResolveDefaultLabelExtent(placement As MASProgressBarLabelPlacement) As Single
            Select Case NormalizeLabelPlacement(placement)
                Case MASProgressBarLabelPlacement.Left, MASProgressBarLabelPlacement.Right
                    Return ProgressBarTokens.LabelSideExtent
                Case MASProgressBarLabelPlacement.Top, MASProgressBarLabelPlacement.Bottom
                    Return ProgressBarTokens.LabelBlockExtent
                Case Else
                    Return 0.0F
            End Select
        End Function

        Private Shared Function ResolveRecommendedWidth(sizeMode As MASProgressBarSize) As Single
            Select Case NormalizeSizeMode(sizeMode)
                Case MASProgressBarSize.Compact
                    Return ProgressBarTokens.CompactWidth
                Case MASProgressBarSize.Large
                    Return ProgressBarTokens.LargeWidth
                Case MASProgressBarSize.Jumbo
                    Return ProgressBarTokens.JumboWidth
                Case Else
                    Return ProgressBarTokens.DefaultWidth
            End Select
        End Function

        Private Shared Function ResolveTrackHeight(sizeMode As MASProgressBarSize) As Single
            Select Case NormalizeSizeMode(sizeMode)
                Case MASProgressBarSize.Compact
                    Return ProgressBarTokens.CompactHeight
                Case MASProgressBarSize.Large
                    Return ProgressBarTokens.LargeHeight
                Case MASProgressBarSize.Jumbo
                    Return ProgressBarTokens.JumboHeight
                Case Else
                    Return ProgressBarTokens.Height
            End Select
        End Function

        Private Shared Function NormalizeFrameMode(value As MASProgressBarFrameMode) As MASProgressBarFrameMode
            Return MASProgressBarValuePolicy.NormalizeFrameMode(value)
        End Function

        Private Shared Function NormalizeContainerMaterialKey(value As String) As String
            Return MASProgressBarValuePolicy.NormalizeContainerMaterialKey(value)
        End Function

        Private Shared Function NormalizeSurfaceStrength(value As MASSurfaceStrength) As MASSurfaceStrength
            Return MASProgressBarValuePolicy.NormalizeSurfaceStrength(value)
        End Function

        Private Shared Function MapSizeIntentToProgressBarSize(intent As MASSize) As MASProgressBarSize
            Select Case MASSize.Normalize(intent).Kind
                Case MASSizeIntentKind.Compact
                    Return MASProgressBarSize.Compact
                Case MASSizeIntentKind.Large
                    Return MASProgressBarSize.Large
                Case Else
                    Return MASProgressBarSize.[Default]
            End Select
        End Function

        Private Shared Function NormalizeSizeMode(value As MASProgressBarSize) As MASProgressBarSize
            Return MASProgressBarValuePolicy.NormalizeSizeMode(value)
        End Function

        Private Shared Function NormalizeLabelPlacement(value As MASProgressBarLabelPlacement) As MASProgressBarLabelPlacement
            Return MASProgressBarValuePolicy.NormalizeLabelPlacement(value)
        End Function

#End Region
    End Class

End Namespace
