Option Strict On
Option Explicit On

Imports System
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 MASSplitView

#Region "Geometry"

        Private Function BuildGeometry(body As SKRect,
                                       dpi As Single,
                                       isRtl As Boolean) As SplitViewGeometry
            Dim gap As Single = SplitViewTokens.PaneGapDip * dpi
            Dim dividerWidth As Single = SplitViewTokens.DividerHitWidthDip * dpi
            Dim collapseWidth As Single = SplitViewTokens.CollapseStripWidthDip * dpi
            Dim leftWidth As Single = If(_leftPaneCollapsed, collapseWidth, body.Width * _leftPaneRatio)
            Dim rightWidth As Single = If(_rightPaneCollapsed, collapseWidth, body.Width * _rightPaneRatio)
            Dim minContent As Single = Math.Min(260.0F * dpi, body.Width * 0.46F)
            Dim availableSides As Single = Math.Max(collapseWidth * 2.0F, body.Width - minContent - (gap * 4.0F) - (dividerWidth * 2.0F))
            If leftWidth + rightWidth > availableSides Then
                Dim scale As Single = availableSides / Math.Max(1.0F, leftWidth + rightWidth)
                If Not _leftPaneCollapsed Then leftWidth *= scale
                If Not _rightPaneCollapsed Then rightWidth *= scale
            End If

            Dim result As New SplitViewGeometry()
            Dim innerTop As Single = body.Top + gap
            Dim innerBottom As Single = body.Bottom - gap
            If isRtl Then
                result.LeftPane = PixelSnap.SnapRect(New SKRect(body.Right - gap - leftWidth, innerTop, body.Right - gap, innerBottom), dpi)
                result.LeftDivider = PixelSnap.SnapRect(New SKRect(result.LeftPane.Left - dividerWidth, innerTop, result.LeftPane.Left, innerBottom), dpi)
                result.RightPane = PixelSnap.SnapRect(New SKRect(body.Left + gap, innerTop, body.Left + gap + rightWidth, innerBottom), dpi)
                result.RightDivider = PixelSnap.SnapRect(New SKRect(result.RightPane.Right, innerTop, result.RightPane.Right + dividerWidth, innerBottom), dpi)
                result.ContentPane = PixelSnap.SnapRect(New SKRect(result.RightDivider.Right + gap, innerTop, result.LeftDivider.Left - gap, innerBottom), dpi)
            Else
                result.LeftPane = PixelSnap.SnapRect(New SKRect(body.Left + gap, innerTop, body.Left + gap + leftWidth, innerBottom), dpi)
                result.LeftDivider = PixelSnap.SnapRect(New SKRect(result.LeftPane.Right, innerTop, result.LeftPane.Right + dividerWidth, innerBottom), dpi)
                result.RightPane = PixelSnap.SnapRect(New SKRect(body.Right - gap - rightWidth, innerTop, body.Right - gap, innerBottom), dpi)
                result.RightDivider = PixelSnap.SnapRect(New SKRect(result.RightPane.Left - dividerWidth, innerTop, result.RightPane.Left, innerBottom), dpi)
                result.ContentPane = PixelSnap.SnapRect(New SKRect(result.LeftDivider.Right + gap, innerTop, result.RightDivider.Left - gap, innerBottom), dpi)
            End If
            If result.ContentPane.Width < 1.0F Then result.ContentPane = New SKRect(body.Left + gap, innerTop, body.Right - gap, innerBottom)
            Return result
        End Function

        
        Private Function HitTestDivider(point As SKPoint) As SplitDividerSide
            If _bodyRect.Width <= 1.0F OrElse _bodyRect.Height <= 1.0F Then Return SplitDividerSide.None

            Dim geometry As SplitViewGeometry = BuildGeometry(_bodyRect, MASResizeInteractionPolicy.SafeDpi(_lastDpi), MASSplitViewPolicy.ResolveRightToLeft())
            If HitTestDividerGrip(geometry.LeftDivider, point, _hoverDivider = SplitDividerSide.Left) Then Return SplitDividerSide.Left
            If HitTestDividerGrip(geometry.RightDivider, point, _hoverDivider = SplitDividerSide.Right) Then Return SplitDividerSide.Right
            Return SplitDividerSide.None
        End Function

        
        Private Function HitTestDividerGrip(dividerRect As SKRect,
                                            point As SKPoint,
                                            retainExistingHover As Boolean) As Boolean
            If dividerRect.Width <= 1.0F OrElse dividerRect.Height <= 1.0F Then Return False
            Dim halfWidthDip As Single = If(retainExistingHover,
                                            SplitViewTokens.DividerGripRetainHalfWidthDip,
                                            SplitViewTokens.DividerGripHalfWidthDip)
            Dim grip As SKRect = MASResizeInteractionPolicy.ResolveVerticalGripRect(
                dividerRect.MidX,
                dividerRect.Top,
                dividerRect.Bottom,
                MASResizeInteractionPolicy.SafeDpi(_lastDpi),
                halfWidthDip)

            Dim boundedGrip As New SKRect(
                Math.Max(grip.Left, dividerRect.Left),
                grip.Top,
                Math.Min(grip.Right, dividerRect.Right),
                grip.Bottom)
            Return boundedGrip.Contains(point.X, point.Y)
        End Function

        
#End Region

    End Class

End Namespace
