Option Strict On
Option Explicit On

Imports System
Imports Nexamas.UI.Values
Imports SkiaSharp

Namespace Nexamas.UI.Controls

    ''' <summary>
    ''' Friend-only operation progress composition policy. It owns title/status text
    ''' hygiene, percent text handoff, child slot geometry, compact fallback layout,
    ''' and the boundary that keeps operation lifetime, cancellation, actions, async
    ''' work, and progress services outside MASOperationProgressBox.
    ''' </summary>
    Friend NotInheritable Class MASOperationProgressBoxPolicy
        Private Sub New()
        End Sub

        Friend Const DefaultTitleText As String = "Processing..."
        Friend Const DefaultStatusText As String = "Please wait..."

        Friend Shared Function NormalizeTitleText(value As String) As String
            Dim text As String = NormalizeText(value)
            If text.Length = 0 Then Return DefaultTitleText
            Return text
        End Function

        Friend Shared Function NormalizeStatusText(value As String) As String
            Dim text As String = NormalizeText(value)
            If text.Length = 0 Then Return DefaultStatusText
            Return text
        End Function

        Friend Shared Function NormalizeOptionalText(value As String) As String
            Return NormalizeText(value)
        End Function

        Friend Shared Function ResolvePercentText(minimum As Double,
                                                  maximum As Double,
                                                  value As Double) As String
            Return MASProgressBarValuePolicy.ResolvePercentText(minimum, maximum, value)
        End Function

        Friend Shared Function BuildLayoutPlan(owner As SKRect) As MASOperationProgressBoxLayoutPlan
            If owner.Width <= 0.0F OrElse owner.Height <= 0.0F Then
                Return MASOperationProgressBoxLayoutPlan.Empty
            End If

            Dim content As New SKRect(
                owner.Left + OperationProgressBoxTokens.PaddingLeft,
                owner.Top + OperationProgressBoxTokens.PaddingTop,
                owner.Right - OperationProgressBoxTokens.PaddingRight,
                owner.Bottom - OperationProgressBoxTokens.PaddingBottom)

            If content.Width < OperationProgressBoxTokens.MinContentWidth OrElse content.Height <= 1.0F Then
                Return MASOperationProgressBoxLayoutPlan.Empty
            End If

            Dim titleHeight As Single = Math.Min(OperationProgressBoxTokens.TitleHeight, content.Height)
            Dim statusHeight As Single = Math.Min(OperationProgressBoxTokens.StatusHeight, Math.Max(0.0F, content.Height - titleHeight))
            Dim titleGap As Single = OperationProgressBoxTokens.TitleToProgressGap
            Dim statusGap As Single = OperationProgressBoxTokens.ProgressToStatusGap
            Dim availableForProgress As Single = content.Height - titleHeight - statusHeight - titleGap - statusGap

            If availableForProgress < OperationProgressBoxTokens.MinProgressHeight Then
                titleGap = Math.Min(titleGap, Math.Max(0.0F, titleGap + availableForProgress - OperationProgressBoxTokens.MinProgressHeight) * 0.5F)
                statusGap = Math.Min(statusGap, titleGap)
                availableForProgress = content.Height - titleHeight - statusHeight - titleGap - statusGap
            End If

            Dim progressHeight As Single = Math.Max(
                OperationProgressBoxTokens.MinProgressHeight,
                Math.Min(OperationProgressBoxTokens.ProgressHeight, availableForProgress))

            If content.Height < titleHeight + titleGap + progressHeight + statusGap + statusHeight Then
                progressHeight = Math.Max(OperationProgressBoxTokens.MinProgressHeight, content.Height - titleHeight - titleGap - statusGap - statusHeight)
            End If

            Dim y As Single = content.Top
            Dim titleBounds As New SKRect(content.Left, y, content.Right, y + titleHeight)
            y += titleHeight + titleGap
            Dim progressBounds As New SKRect(content.Left, y, content.Right, y + progressHeight)
            Dim statusBounds As New SKRect(content.Left, content.Bottom - statusHeight, content.Right, content.Bottom)

            Return New MASOperationProgressBoxLayoutPlan(titleBounds, progressBounds, statusBounds)
        End Function

        Friend Shared Function HasChildConstructionPolicy() As Boolean
            Return True
        End Function

        Friend Shared Function HasPercentSyncPolicy() As Boolean
            Return True
        End Function

        Friend Shared Function HasNoProgressLifetimeOwner() As Boolean
            Return True
        End Function

        Friend Shared Function HasNoActionOrCancelSlotRoute() As Boolean
            Return True
        End Function

        Private Shared Function NormalizeText(value As String) As String
            Dim text As String = If(value, String.Empty).Trim()
            While text.Contains("  ")
                text = text.Replace("  ", " ")
            End While
            Return text
        End Function
    End Class

    Friend NotInheritable Class MASOperationProgressBoxLayoutPlan
        Friend Shared ReadOnly Property Empty As MASOperationProgressBoxLayoutPlan =
            New MASOperationProgressBoxLayoutPlan(SKRect.Empty, SKRect.Empty, SKRect.Empty)

        Friend Sub New(titleBounds As SKRect,
                       progressBounds As SKRect,
                       statusBounds As SKRect)
            Me.TitleBounds = titleBounds
            Me.ProgressBounds = progressBounds
            Me.StatusBounds = statusBounds
        End Sub

        Friend ReadOnly Property TitleBounds As SKRect
        Friend ReadOnly Property ProgressBounds As SKRect
        Friend ReadOnly Property StatusBounds As SKRect
    End Class

End Namespace
