Option Strict On
Option Explicit On

Imports System
Imports SkiaSharp
Imports SkiaSharp.HarfBuzz

Namespace Nexamas.UI.TextRendering

    Friend NotInheritable Class MASTextShapedRun

#Region "Fields"

        Private ReadOnly _text As String
        Private ReadOnly _glyphXs As Single()
        Private ReadOnly _clusters As Integer()

#End Region

#Region "Properties"

        Friend ReadOnly Property Text As String
            Get
                Return _text
            End Get
        End Property

        Friend ReadOnly Property GlyphXs As Single()
            Get
                Return _glyphXs
            End Get
        End Property

        Friend ReadOnly Property Clusters As Integer()
            Get
                Return _clusters
            End Get
        End Property

        Friend ReadOnly Property GlyphCount As Integer
            Get
                Return If(_glyphXs Is Nothing, 0, _glyphXs.Length)
            End Get
        End Property

        Friend ReadOnly Property IsEmpty As Boolean
            Get
                Return GlyphCount = 0
            End Get
        End Property

#End Region

#Region "Factory"

        Friend Shared Function Empty(text As String) As MASTextShapedRun
            Return New MASTextShapedRun(
                text:=If(text, String.Empty),
                glyphXs:=Array.Empty(Of Single)(),
                clusters:=Array.Empty(Of Integer)()
            )
        End Function

        Friend Shared Function Shape(text As String,
                                     paint As SKPaint) As MASTextShapedRun

            If String.IsNullOrEmpty(text) OrElse paint Is Nothing Then
                Return Empty(text)
            End If

            Try
                Dim tf As SKTypeface = If(paint.Typeface, SKTypeface.Default)

                Using font As New SKFont(tf, paint.TextSize)
                    Using shaper As New SKShaper(tf)

                        Dim result As SKShaper.Result = shaper.Shape(text, font)
                        If result Is Nothing Then Return Empty(text)

                        If result.Points Is Nothing OrElse result.Clusters Is Nothing Then
                            Return Empty(text)
                        End If

                        Dim xs(result.Points.Length - 1) As Single

                        For i As Integer = 0 To result.Points.Length - 1
                            xs(i) = result.Points(i).X
                        Next

                        Dim rawClusters As UInteger() = result.Clusters
                        Dim clusters(rawClusters.Length - 1) As Integer

                        For i As Integer = 0 To rawClusters.Length - 1
                            If rawClusters(i) > CUInt(Integer.MaxValue) Then
                                clusters(i) = Integer.MaxValue
                            Else
                                clusters(i) = CInt(rawClusters(i))
                            End If
                        Next

                        Return New MASTextShapedRun(text, xs, clusters)

                    End Using
                End Using

            Catch masCaughtException1 As Exception
                Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowTextShapingFallback(masCaughtException1)
                Return Empty(text)
            End Try
        End Function

#End Region

#Region "Ctor"

        Private Sub New(text As String,
                        glyphXs As Single(),
                        clusters As Integer())

            _text = If(text, String.Empty)
            _glyphXs = If(glyphXs, Array.Empty(Of Single)())
            _clusters = If(clusters, Array.Empty(Of Integer)())
        End Sub

#End Region

    End Class

End Namespace
