Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports Nexamas.UI.Architecture
Imports Nexamas.UI.Composition
Imports Nexamas.UI.General
Imports Nexamas.UI.Icons
Imports Nexamas.UI.Layout
Imports Nexamas.UI.Rendering
Imports Nexamas.UI.TextInput
Imports Nexamas.UI.TextRendering
Imports Nexamas.UI.Theming
Imports Nexamas.UI.Values
Imports SkiaSharp

Namespace Nexamas.UI.Controls

    Partial Public NotInheritable Class MASStatusBanner

#Region "Rendering / geometry"

        Private Shared Function ResolveChromeLayout(bounds As SKRect,
                                                    showIcon As Boolean,
                                                    isRtl As Boolean,
                                                    dpi As Single) As StatusBannerChromeLayout
            Dim layout As New StatusBannerChromeLayout()
            layout.IsRtl = isRtl
            Dim safeDpi As Single = PixelSnap.SafeDpi(dpi)
            Dim accentWidth As Single = Math.Min(
                MASStatusBannerVisualPolicy.ResolveAccentSegmentWidth(showIcon) * safeDpi,
                Math.Max(0.0F, bounds.Width))
            Dim inset As Single = StatusBannerTokens.ContentSurfaceInsetDip * safeDpi

            If isRtl Then
                layout.AccentRect = New SKRect(
                    Math.Max(bounds.Left, bounds.Right - accentWidth),
                    bounds.Top,
                    bounds.Right,
                    bounds.Bottom)
            Else
                layout.AccentRect = New SKRect(
                    bounds.Left,
                    bounds.Top,
                    Math.Min(bounds.Right, bounds.Left + accentWidth),
                    bounds.Bottom)
            End If

            If showIcon Then
                Dim overlap As Single = Math.Min(StatusBannerTokens.AccentContentOverlapDip * safeDpi, Math.Max(0.0F, accentWidth * 0.5F))
                Dim minPlateWidth As Single = Math.Min(bounds.Width, Math.Max(80.0F * safeDpi, bounds.Width * 0.36F))

                If isRtl Then
                    Dim plateRight As Single = Math.Max(bounds.Left + minPlateWidth, bounds.Right - accentWidth + overlap)
                    plateRight = Math.Min(bounds.Right - inset, plateRight)
                    layout.ContentPlateRect = New SKRect(
                        bounds.Left + inset,
                        bounds.Top + inset,
                        plateRight,
                        bounds.Bottom - inset)
                Else
                    Dim plateLeft As Single = Math.Min(bounds.Right - minPlateWidth, bounds.Left + accentWidth - overlap)
                    plateLeft = Math.Max(bounds.Left + inset, plateLeft)
                    layout.ContentPlateRect = New SKRect(
                        plateLeft,
                        bounds.Top + inset,
                        bounds.Right - inset,
                        bounds.Bottom - inset)
                End If

                layout.HasContentPlate = layout.ContentPlateRect.Width > 2.0F AndAlso layout.ContentPlateRect.Height > 2.0F
                layout.HasBadge = layout.HasContentPlate

                If layout.HasBadge Then
                    Dim badgeSize As Single = Math.Min(
                        StatusBannerTokens.IconBadgeDiameterDip * safeDpi,
                        Math.Max(18.0F * safeDpi, bounds.Height - 16.0F * safeDpi))
                    Dim badgeCenterX As Single = If(isRtl, layout.ContentPlateRect.Right, layout.ContentPlateRect.Left)
                    Dim badgeCenterY As Single = bounds.MidY
                    layout.IconBadgeRect = New SKRect(
                        badgeCenterX - badgeSize / 2.0F,
                        badgeCenterY - badgeSize / 2.0F,
                        badgeCenterX + badgeSize / 2.0F,
                        badgeCenterY + badgeSize / 2.0F)
                End If

                layout.TextRect = ResolveTextRect(bounds, layout.ContentPlateRect, layout.IconBadgeRect, showIcon, isRtl, safeDpi)
            Else
                layout.ContentPlateRect = bounds
                layout.HasContentPlate = False
                layout.HasBadge = False
                layout.IconBadgeRect = SKRect.Empty
                layout.TextRect = ResolveTextRect(bounds, bounds, layout.IconBadgeRect, showIcon, isRtl, safeDpi)
            End If

            Return layout
        End Function

        Private Shared Function ResolveTextRect(bounds As SKRect,
                                                contentPlateRect As SKRect,
                                                iconBadgeRect As SKRect,
                                                showIcon As Boolean,
                                                isRtl As Boolean,
                                                dpi As Single) As SKRect
            Dim top As Single = bounds.Top + StatusBannerTokens.PaddingTopDip * dpi
            Dim bottom As Single = bounds.Bottom - StatusBannerTokens.PaddingBottomDip * dpi

            If showIcon Then
                Dim left As Single = contentPlateRect.Left + StatusBannerTokens.ContentTextInsetDip * dpi
                Dim right As Single = contentPlateRect.Right - StatusBannerTokens.PaddingRightDip * dpi

                If isRtl Then
                    right = Math.Min(right, iconBadgeRect.Left - StatusBannerTokens.IconGapDip * dpi)
                Else
                    left = Math.Max(left, iconBadgeRect.Right + StatusBannerTokens.IconGapDip * dpi)
                End If

                Return New SKRect(left, top, right, bottom)
            End If

            Dim compactReserve As Single = StatusBannerTokens.AccentSegmentWithoutIconWidthDip * dpi +
                                           StatusBannerTokens.ContentTextInsetDip * dpi
            If isRtl Then
                Return New SKRect(
                    bounds.Left + StatusBannerTokens.PaddingRightDip * dpi,
                    top,
                    bounds.Right - compactReserve,
                    bottom)
            End If

            Return New SKRect(
                bounds.Left + compactReserve,
                top,
                bounds.Right - StatusBannerTokens.PaddingRightDip * dpi,
                bottom)
        End Function

        Private Shared Function ResolveStatusBannerSurfaceGeometry(bounds As SKRect,
                                                                    dpi As Single) As StatusBannerSurfaceGeometry
            Dim geometry As New StatusBannerSurfaceGeometry With {
                .Bounds = SKRect.Empty,
                .Radius = 0.0F,
                .Dpi = PixelSnap.SafeDpi(dpi),
                .HasValue = False
            }

            If bounds.Width <= 1.0F OrElse bounds.Height <= 1.0F Then Return geometry

            Dim metrics As MASSurfaceInteractionRing.Metrics = MASVisualPrimitivesPainter.ComputeRingMetrics(geometry.Dpi)
            Dim baseRect As SKRect = MASVisualPrimitivesPainter.SnapRectToRingBase(bounds, metrics)
            If baseRect.Width <= 1.0F OrElse baseRect.Height <= 1.0F Then Return geometry

            geometry.Bounds = baseRect
            geometry.Radius = PixelSnap.SafeRadius(
                MASVisualPrimitivesPainter.ResolveSurfaceRadiusPx(_contract, baseRect, geometry.Dpi))
            geometry.HasValue = geometry.Radius > 0.0F
            Return geometry
        End Function

#End Region


    End Class

End Namespace
