Option Strict On
Option Explicit On

Imports System
Imports System.IO
Imports System.Text
Imports System.Windows.Forms
Imports Nexamas.UI.Icons

Namespace Nexamas.UI.Components

    ''' <summary>
    ''' Friend-only path policy for MASPathTextBox. MASInputBoxSkiaBase remains
    ''' the owner of editing, IME, selection, clipboard, validation visuals,
    ''' layout, text rendering, and ellipsis. This policy owns only path text
    ''' hygiene, slash preference, invalid-character checks, browse intent,
    ''' and official MAS icon choices.
    ''' </summary>
    Friend NotInheritable Class MASPathTextBoxPolicy

        Friend Const BrowseReservedWidthDip As Single = 38.0F

        Private Sub New()
        End Sub

        Friend Shared Function ResolveDefaultPlaceholder() As String
            Return "Path..."
        End Function

        Friend Shared Function NormalizePlaceholder(value As String) As String
            Dim s As String = If(value, String.Empty)
            s = s.Replace(vbCrLf, " ")
            s = s.Replace(vbCr, " ")
            s = s.Replace(vbLf, " ")
            s = s.Replace(vbTab, " ")
            Return CollapseSpaces(s).Trim()
        End Function

        Friend Shared Function NormalizeMaxLength(value As Integer) As Integer
            If value < 0 Then Return 0
            Return value
        End Function

        Friend Shared Function NormalizePreferredSlash(value As Char,
                                                       fallback As Char) As Char
            If value = "\"c OrElse value = "/"c Then Return value
            If fallback = "/"c Then Return "/"c
            Return "\"c
        End Function

        Friend Shared Function NormalizePathText(value As String,
                                                 trimOuterSpacesOnAssign As Boolean,
                                                 normalizeSlashes As Boolean,
                                                 preferredSlash As Char,
                                                 allowWildcards As Boolean) As String

            Dim s As String = If(value, String.Empty)
            s = s.Replace(vbCrLf, String.Empty)
            s = s.Replace(vbCr, String.Empty)
            s = s.Replace(vbLf, String.Empty)
            s = s.Replace(vbTab, " ")

            If trimOuterSpacesOnAssign Then
                s = s.Trim()
            End If

            If s.Length = 0 Then Return String.Empty

            Dim safeSlash As Char = NormalizePreferredSlash(preferredSlash, "\"c)
            Dim invalidChars As Char() = Path.GetInvalidPathChars()
            Dim sb As New StringBuilder(s.Length)

            For Each ch As Char In s
                If Array.IndexOf(invalidChars, ch) >= 0 Then Continue For

                If Not allowWildcards Then
                    Select Case ch
                        Case "*"c, "?"c, """"c, "<"c, ">"c, "|"c
                            Continue For
                    End Select
                End If

                If normalizeSlashes Then
                    If ch = "\"c OrElse ch = "/"c Then
                        sb.Append(safeSlash)
                    Else
                        sb.Append(ch)
                    End If
                Else
                    sb.Append(ch)
                End If
            Next

            Return sb.ToString()
        End Function

        Friend Shared Function HasInvalidPathChars(value As String,
                                                   allowWildcards As Boolean) As Boolean
            Dim s As String = If(value, String.Empty)
            If s.Length = 0 Then Return False

            Dim invalidChars As Char() = Path.GetInvalidPathChars()
            For Each ch As Char In s
                If Array.IndexOf(invalidChars, ch) >= 0 Then Return True

                If Not allowWildcards Then
                    Select Case ch
                        Case "*"c, "?"c, """"c, "<"c, ">"c, "|"c
                            Return True
                    End Select
                End If
            Next

            Return False
        End Function

        Friend Shared Function LooksLikeAbsolutePath(value As String) As Boolean
            Dim s As String = If(value, String.Empty).Trim()
            If s.Length = 0 Then Return False

            If s.StartsWith("\\", StringComparison.Ordinal) OrElse
               s.StartsWith("//", StringComparison.Ordinal) Then
                Return True
            End If

            If s.Length >= 3 AndAlso
               Char.IsLetter(s(0)) AndAlso
               s(1) = ":"c AndAlso
               (s(2) = "\"c OrElse s(2) = "/"c) Then
                Return True
            End If

            If s.StartsWith("~/", StringComparison.Ordinal) OrElse
               s.StartsWith("~\", StringComparison.Ordinal) Then
                Return True
            End If

            Return Path.IsPathRooted(s)
        End Function

        Friend Shared Function ShouldRequestBrowseFromKey(keyCode As Keys,
                                                          modifiers As Keys) As Boolean
            Dim normalized As Keys = keyCode And Keys.KeyCode
            Dim altDown As Boolean = (modifiers And Keys.Alt) = Keys.Alt
            Dim ctrlDown As Boolean = (modifiers And Keys.Control) = Keys.Control

            If normalized = Keys.F4 Then Return True
            If altDown AndAlso normalized = Keys.Down Then Return True
            If ctrlDown AndAlso normalized = Keys.Enter Then Return True
            Return False
        End Function

        Friend Shared Function ResolvePathIconKind() As MASIconKind
            Return MASIconKind.Folder
        End Function

        Friend Shared Function ResolveBrowseIconKind() As MASIconKind
            Return MASIconKind.OpenFolder
        End Function

        Friend Shared Function HasOfficialTextInputBaseRoute() As Boolean
            Return True
        End Function

        Friend Shared Function HasOfficialMasIconRoute() As Boolean
            Return True
        End Function

        Friend Shared Function HasOfficialFilePickerHandoffBoundary() As Boolean
            Return True
        End Function

        Friend Shared Function HasNoNativeTextBoxRoute() As Boolean
            Return True
        End Function

        Friend Shared Function HasNoParallelPathService() As Boolean
            Return True
        End Function

        Private Shared Function CollapseSpaces(value As String) As String
            If String.IsNullOrEmpty(value) Then Return String.Empty

            Dim result As New StringBuilder(value.Length)
            Dim previousWasSpace As Boolean
            For Each ch As Char In value
                Dim isSpace As Boolean = Char.IsWhiteSpace(ch)
                If isSpace Then
                    If Not previousWasSpace Then result.Append(" "c)
                    previousWasSpace = True
                Else
                    result.Append(ch)
                    previousWasSpace = False
                End If
            Next

            Return result.ToString()
        End Function

    End Class

End Namespace
