Option Strict On
Option Explicit On

Imports System
Imports SkiaSharp

Namespace Nexamas.UI.TextInput

    ' CONTRACT:
    ' MASTextWrappedLine represents one visual line produced from a logical line.
    '
    ' It is immutable layout data:
    ' - global text range
    ' - visual bounds
    ' - baseline
    ' - inline layout for caret/hit-test inside this wrapped line
    '
    ' It must not mutate state, render directly, or handle input.
    Friend NotInheritable Class MASTextWrappedLine

        Friend Sub New(wrappedLineIndex As Integer,
                       logicalLineIndex As Integer,
                       startIndex As Integer,
                       length As Integer,
                       text As String,
                       bounds As SKRect,
                       baselineY As Single,
                       isRtl As Boolean,
                       inlineLayout As MASTextInlineLayout)

            If wrappedLineIndex < 0 Then Throw New ArgumentOutOfRangeException(NameOf(wrappedLineIndex))
            If logicalLineIndex < 0 Then Throw New ArgumentOutOfRangeException(NameOf(logicalLineIndex))
            If startIndex < 0 Then Throw New ArgumentOutOfRangeException(NameOf(startIndex))
            If length < 0 Then Throw New ArgumentOutOfRangeException(NameOf(length))

            Me.WrappedLineIndex = wrappedLineIndex
            Me.LogicalLineIndex = logicalLineIndex
            Me.StartIndex = startIndex
            Me.Length = length
            Me.Text = If(text, String.Empty)
            Me.Bounds = bounds
            Me.BaselineY = baselineY
            Me.IsRtl = isRtl
            Me.InlineLayout = inlineLayout
        End Sub

        Friend ReadOnly Property WrappedLineIndex As Integer
        Friend ReadOnly Property LogicalLineIndex As Integer
        Friend ReadOnly Property StartIndex As Integer
        Friend ReadOnly Property Length As Integer
        Friend ReadOnly Property Text As String
        Friend ReadOnly Property Bounds As SKRect
        Friend ReadOnly Property BaselineY As Single
        Friend ReadOnly Property IsRtl As Boolean
        Friend ReadOnly Property InlineLayout As MASTextInlineLayout

        Friend ReadOnly Property EndIndexExclusive As Integer
            Get
                Return StartIndex + Length
            End Get
        End Property

        Friend Function ContainsTextIndex(index As Integer) As Boolean
            Return index >= StartIndex AndAlso index <= EndIndexExclusive
        End Function

        Friend Function ClampTextIndex(index As Integer) As Integer
            If index < StartIndex Then Return StartIndex
            If index > EndIndexExclusive Then Return EndIndexExclusive
            Return index
        End Function

        Friend Function ToLocalIndex(textIndex As Integer) As Integer
            Dim clamped As Integer = ClampTextIndex(textIndex)
            Return clamped - StartIndex
        End Function

        Friend Function ToGlobalIndex(localIndex As Integer) As Integer
            If localIndex < 0 Then localIndex = 0
            If localIndex > Length Then localIndex = Length
            Return StartIndex + localIndex
        End Function

    End Class

End Namespace
