Option Strict On
Option Explicit On

Imports System
Imports Nexamas.UI.Layout
Imports Nexamas.UI.Theming
Imports Nexamas.UI.Values
Imports SkiaSharp

Namespace Nexamas.UI.Controls

    Friend NotInheritable Class MASNotificationPanelLayoutPlan
        Friend Shared ReadOnly Thresholds As New MASResponsiveLayoutThresholds(
            fullWidthDip:=NotificationPanelTokens.DefaultWidthDip,
            denseWidthDip:=360.0F,
            compactWidthDip:=NotificationPanelTokens.MinWidthDip,
            minimalWidthDip:=220.0F,
            fullHeightDip:=360.0F,
            denseHeightDip:=NotificationPanelTokens.MinHeightDip,
            compactHeightDip:=150.0F,
            minimalHeightDip:=86.0F)

        Friend ReadOnly Property ResponsiveProfile As MASResponsiveLayoutProfile
        Friend ReadOnly Property PixelDpi As Single
        Friend ReadOnly Property MetricDpi As Single
        Friend ReadOnly Property ContentRectPx As SKRect

        Private Sub New(profile As MASResponsiveLayoutProfile,
                        metricDpi As Single,
                        contentRectPx As SKRect)
            Dim safeProfile As MASResponsiveLayoutProfile = If(profile, MASResponsiveLayoutResolver.FromLogicalSize(MASSizeLayoutIntegrationContext.Empty, SKSize.Empty, MASSize.Default, Thresholds))
            Me.ResponsiveProfile = safeProfile
            Me.PixelDpi = safeProfile.DpiScale
            Me.MetricDpi = Math.Max(0.25F, metricDpi)
            Me.ContentRectPx = SanitizeRect(contentRectPx)
        End Sub

        Friend Shared Function Create(ctx As MASThemeContext,
                                      boundsPx As SKRect,
                                      sizeIntent As MASSize) As MASNotificationPanelLayoutPlan
            Dim profile As MASResponsiveLayoutProfile = MASResponsiveLayoutResolver.FromTheme(ctx, boundsPx, sizeIntent, Thresholds)
            Dim metricDpi As Single = profile.DpiScale * ClampScale(profile.ContentScale, 0.66F, 1.22F)
            Dim chromeDpi As Single = profile.DpiScale * ClampScale(profile.ChromeScale, 0.62F, 1.2F)
            Dim gapDpi As Single = profile.DpiScale * ClampScale(profile.GapScale, 0.54F, 1.16F)

            Dim left As Single = boundsPx.Left + NotificationPanelTokens.PaddingLeftDip * chromeDpi
            Dim top As Single = boundsPx.Top + NotificationPanelTokens.PaddingTopDip * chromeDpi + NotificationPanelTokens.HeaderHeightDip * metricDpi + NotificationPanelTokens.HeaderContentGapDip * gapDpi
            Dim right As Single = boundsPx.Right - NotificationPanelTokens.PaddingRightDip * chromeDpi
            Dim bottom As Single = boundsPx.Bottom - NotificationPanelTokens.PaddingBottomDip * chromeDpi

            If profile.IsCollapsed OrElse right <= left + 1.0F OrElse bottom <= top + 1.0F Then
                Return New MASNotificationPanelLayoutPlan(profile, metricDpi, SKRect.Empty)
            End If

            Return New MASNotificationPanelLayoutPlan(profile, metricDpi, New SKRect(left, top, right, bottom))
        End Function

        Private Shared Function ClampScale(value As Single, minValue As Single, maxValue As Single) As Single
            If Single.IsNaN(value) OrElse Single.IsInfinity(value) OrElse value <= 0.0F Then Return 1.0F
            Return Math.Max(minValue, Math.Min(maxValue, value))
        End Function

        Private Shared Function SanitizeRect(rect As SKRect) As SKRect
            If rect.IsEmpty OrElse rect.Width <= 1.0F OrElse rect.Height <= 1.0F Then Return SKRect.Empty
            Return rect
        End Function
    End Class

End Namespace
