Option Strict On
Option Explicit On

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

Namespace Nexamas.UI.Controls


    Partial Public NotInheritable Class MASGroupBox
        Friend ReadOnly Property Controls As ControlsLayer
            Get
                Return ChildLayerInternal
            End Get
        End Property




        <Global.System.ComponentModel.EditorBrowsable(Global.System.ComponentModel.EditorBrowsableState.Advanced)>
        Friend Sub SetPadding(all As Single)
            Dim v As Single = MASGroupBoxSurfacePolicy.NormalizePadding(all)

            If Math.Abs(_paddingLeft - v) < 0.001F AndAlso
               Math.Abs(_paddingTop - v) < 0.001F AndAlso
               Math.Abs(_paddingRight - v) < 0.001F AndAlso
               Math.Abs(_paddingBottom - v) < 0.001F Then
                Return
            End If

            _paddingLeft = v
            _paddingTop = v
            _paddingRight = v
            _paddingBottom = v

            RequestSizeLayoutRefreshForSizeAffectingChange("MASGroupBox.SetPadding")
            InvalidateVisual()
        End Sub




        <Global.System.ComponentModel.EditorBrowsable(Global.System.ComponentModel.EditorBrowsableState.Advanced)>
        Friend Sub SetPadding(horizontal As Single, vertical As Single)
            Dim h As Single = MASGroupBoxSurfacePolicy.NormalizePadding(horizontal)
            Dim v As Single = MASGroupBoxSurfacePolicy.NormalizePadding(vertical)

            If Math.Abs(_paddingLeft - h) < 0.001F AndAlso
               Math.Abs(_paddingRight - h) < 0.001F AndAlso
               Math.Abs(_paddingTop - v) < 0.001F AndAlso
               Math.Abs(_paddingBottom - v) < 0.001F Then
                Return
            End If

            _paddingLeft = h
            _paddingRight = h
            _paddingTop = v
            _paddingBottom = v

            RequestSizeLayoutRefreshForSizeAffectingChange("MASGroupBox.SetPadding")
            InvalidateVisual()
        End Sub




        Public Sub AddChild(child As MASControlBase)
            If child Is Nothing Then Throw New ArgumentNullException(NameOf(child))
            ChildLayerInternal.Add(child)
            InvalidateVisual()
        End Sub




        Public Sub AddChild(child As MASControlBase, relativeContentBounds As SKRect)
            If child Is Nothing Then Throw New ArgumentNullException(NameOf(child))

            Dim normalized As SKRect = MASGroupBoxSurfacePolicy.NormalizeRelativeBounds(relativeContentBounds)
            _relativeChildBounds(child) = normalized
            ChildLayerInternal.Add(child)
            SetChildBoundsInContent(child, normalized)

            InvalidateVisual()
        End Sub




        Public Sub RemoveChild(child As MASControlBase)
            If child Is Nothing Then Return

            If HasChildLayerInternal() Then
                ChildLayerInternal.Remove(child)
            End If

            _relativeChildBounds.Remove(child)
            InvalidateVisual()
        End Sub




        Public Sub ClearChildren()
            If HasChildLayerInternal() Then
                ChildLayerInternal.Clear()
            End If

            _relativeChildBounds.Clear()
            InvalidateVisual()
        End Sub




        Public Function GetContentBoundsLogical() As SKRect
            Dim slotContent As SKRect = GetLayoutContentBoundsLogicalInternal()
            If slotContent.Width > 1.0F AndAlso slotContent.Height > 1.0F Then
                Return slotContent
            End If

            Dim b As SKRect = BoundsLogical
            If b.Width <= 1.0F OrElse b.Height <= 1.0F Then Return SKRect.Empty

            Dim headerH As Single = ResolveHeaderHeightLogical()

            Return MASGroupBoxSurfacePolicy.ResolveContentBounds(
                b,
                headerH,
                _paddingLeft,
                _paddingTop,
                _paddingRight,
                _paddingBottom)
        End Function




        Public Sub SetChildBoundsInContent(child As MASControlBase, relativeContentBounds As SKRect)
            If child Is Nothing Then Throw New ArgumentNullException(NameOf(child))

            Dim normalized As SKRect = MASGroupBoxSurfacePolicy.NormalizeRelativeBounds(relativeContentBounds)
            Dim content As SKRect = GetContentBoundsLogical()

            If content.Width <= 1.0F OrElse content.Height <= 1.0F OrElse normalized.Width <= 0.0F OrElse normalized.Height <= 0.0F Then
                child.SetLocalLayoutBoundsInternal(SKRect.Empty)
                Return
            End If

            child.SetLocalLayoutBoundsInternal(New SKRect(
                content.Left + normalized.Left,
                content.Top + normalized.Top,
                content.Left + normalized.Right,
                content.Top + normalized.Bottom))
        End Sub




        Protected Overrides Sub OnBoundsChanged()
            MyBase.OnBoundsChanged()

            If _relativeChildBounds.Count = 0 Then Return

            Dim snapshot As New List(Of KeyValuePair(Of MASControlBase, SKRect))(_relativeChildBounds)

            For Each kv As KeyValuePair(Of MASControlBase, SKRect) In snapshot
                If kv.Key Is Nothing Then Continue For
                SetChildBoundsInContent(kv.Key, kv.Value)
            Next
        End Sub

    End Class

End Namespace
