Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Windows.Forms
Imports Nexamas.UI.Architecture
Imports Nexamas.UI.Composition
Imports Nexamas.UI.Controls
Imports Nexamas.UI.General
Imports Nexamas.UI.Layout
Imports Nexamas.UI.Rendering
Imports Nexamas.UI.TextRendering
Imports Nexamas.UI.Theming
Imports Nexamas.UI.Values
Imports SkiaSharp

Namespace Nexamas.UI.Components

    Partial Public NotInheritable Class MASMasterDetailView

#Region "Geometry / Hit Testing"

        Private Sub ResolvePaneRects(content As SKRect,
                                     dpi As Single,
                                     plan As MASMasterDetailViewLayoutPlan,
                                     isRtl As Boolean)
            Dim safePlan As MASMasterDetailViewLayoutPlan = If(plan, MASMasterDetailViewLayoutPlan.Create(MASResponsiveLayoutResolver.FromLogicalSize(MASSizeLayoutIntegrationContext.Empty, SKSize.Empty, SizeIntent, MASMasterDetailViewLayoutPlan.Thresholds)))
            Dim top As Single = content.Top + safePlan.HeaderHeightPx + If(safePlan.HeaderHeightPx > 0.0F, safePlan.HeaderGapPx, 0.0F)
            Dim bottom As Single = content.Bottom - safePlan.FooterHeightPx - If(safePlan.FooterHeightPx > 0.0F, safePlan.FooterGapPx, 0.0F)
            Dim available As New SKRect(content.Left, top, content.Right, Math.Max(top, bottom))
            Dim gap As Single = safePlan.PaneGapPx

            If available.Width <= 1.0F OrElse available.Height <= 1.0F Then
                _masterRect = SKRect.Empty
                _detailRect = SKRect.Empty
                Return
            End If

            If safePlan.IsStacked Then
                Dim masterRowsHeight As Single = safePlan.PanePaddingPx * 2.0F + CSng(safePlan.MaxVisibleItems) * safePlan.ItemHeightPx + CSng(Math.Max(0, safePlan.MaxVisibleItems - 1)) * safePlan.ItemGapPx
                Dim maxMasterHeight As Single = Math.Max(available.Height * 0.36F, Math.Min(available.Height * 0.5F, masterRowsHeight))
                Dim masterHeight As Single = Math.Min(maxMasterHeight, Math.Max(safePlan.ItemHeightPx + safePlan.PanePaddingPx * 2.0F, available.Height * 0.42F))
                If available.Height - masterHeight - gap < Math.Max(48.0F * dpi, safePlan.DetailLineHeightPx * 2.0F) Then
                    masterHeight = Math.Max(safePlan.ItemHeightPx + safePlan.PanePaddingPx * 2.0F, available.Height * 0.5F)
                End If
                masterHeight = Math.Min(masterHeight, Math.Max(0.0F, available.Height - gap - 48.0F * dpi))
                _masterRect = PixelSnap.SnapRect(New SKRect(available.Left, available.Top, available.Right, available.Top + masterHeight), dpi)
                _detailRect = PixelSnap.SnapRect(New SKRect(available.Left, _masterRect.Bottom + gap, available.Right, available.Bottom), dpi)
                Return
            End If

            Dim masterWidth As Single = Math.Max(safePlan.MasterMinWidthPx, available.Width * safePlan.MasterWidthRatio)
            masterWidth = Math.Min(masterWidth, available.Width * safePlan.MasterMaxRatio)
            If isRtl Then
                _masterRect = PixelSnap.SnapRect(New SKRect(available.Right - masterWidth, available.Top, available.Right, available.Bottom), dpi)
                _detailRect = PixelSnap.SnapRect(New SKRect(available.Left, available.Top, _masterRect.Left - gap, available.Bottom), dpi)
            Else
                _masterRect = PixelSnap.SnapRect(New SKRect(available.Left, available.Top, available.Left + masterWidth, available.Bottom), dpi)
                _detailRect = PixelSnap.SnapRect(New SKRect(_masterRect.Right + gap, available.Top, available.Right, available.Bottom), dpi)
            End If
        End Sub

        Private Function HitTest(point As SKPoint) As MasterDetailItemHit
            For Each hit As MasterDetailItemHit In _hits
                If hit.Rect.Contains(point.X, point.Y) Then Return hit
            Next
            Return Nothing
        End Function

        Private Shared Function Inset(rect As SKRect,
                                      amount As Single) As SKRect
            Return New SKRect(rect.Left + amount, rect.Top + amount, rect.Right - amount, rect.Bottom - amount)
        End Function

#End Region

    End Class

End Namespace
