Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Globalization
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 MASKanbanBoard

#Region "Item model"


        Private NotInheritable Class KanbanCardState
            Friend Sub New(key As String,
                           title As String,
                           detail As String,
                           badgeText As String)
                Me.Key = key
                Me.Title = title
                Me.Detail = detail
                Me.BadgeText = badgeText
            End Sub

            Friend ReadOnly Property Key As String
            Friend Property Title As String
            Friend Property Detail As String
            Friend Property BadgeText As String
        End Class

        Private NotInheritable Class KanbanColumnState
            Friend Sub New(key As String,
                           title As String)
                Me.Key = key
                Me.Title = title
                Me.Cards = New List(Of KanbanCardState)()
            End Sub

            Friend ReadOnly Property Key As String
            Friend Property Title As String
            Friend ReadOnly Property Cards As List(Of KanbanCardState)
            Friend Property TopCardIndex As Integer
        End Class

        Private NotInheritable Class KanbanCardHit
            Friend Sub New(columnIndex As Integer,
                           cardIndex As Integer,
                           rect As SKRect)
                Me.ColumnIndex = columnIndex
                Me.CardIndex = cardIndex
                Me.Rect = rect
            End Sub

            Friend ReadOnly Property ColumnIndex As Integer
            Friend ReadOnly Property CardIndex As Integer
            Friend ReadOnly Property Rect As SKRect
        End Class

        Private Function FindColumn(columnKey As String) As KanbanColumnState
            Dim normalized As String = If(columnKey, String.Empty).Trim()
            If normalized.Length = 0 Then Return Nothing
            Dim column As KanbanColumnState = Nothing
            If _columnLookup.TryGetValue(normalized, column) Then Return column
            Return Nothing
        End Function

        Private Function FindCard(cardKey As String) As KanbanCardState
            Dim location As Tuple(Of Integer, Integer) = FindCardLocation(cardKey)
            If location Is Nothing Then Return Nothing
            If location.Item1 < 0 OrElse location.Item1 >= _columns.Count Then Return Nothing
            Dim column As KanbanColumnState = _columns(location.Item1)
            If location.Item2 < 0 OrElse location.Item2 >= column.Cards.Count Then Return Nothing
            Return column.Cards(location.Item2)
        End Function

        Private Function FindCardLocation(cardKey As String) As Tuple(Of Integer, Integer)
            Dim normalized As String = If(cardKey, String.Empty).Trim()
            If normalized.Length = 0 Then Return Nothing
            Dim location As Tuple(Of Integer, Integer) = Nothing
            If _cardLocationByKey.TryGetValue(normalized, location) Then Return location
            Return Nothing
        End Function

        Private Function ResolveColumnIndex(column As KanbanColumnState) As Integer
            If column Is Nothing Then Return -1
            Dim index As Integer = -1
            If _columnIndexByKey.TryGetValue(column.Key, index) Then Return index
            Return -1
        End Function

        Private Sub ReindexCardLocationsForColumn(columnIndex As Integer)
            If columnIndex < 0 OrElse columnIndex >= _columns.Count Then Return
            Dim column As KanbanColumnState = _columns(columnIndex)
            For cardIndex As Integer = 0 To column.Cards.Count - 1
                Dim card As KanbanCardState = column.Cards(cardIndex)
                If card IsNot Nothing Then _cardLocationByKey(card.Key) = Tuple.Create(columnIndex, cardIndex)
            Next
        End Sub

        Private Shared Function ResolveInsertCardIndex(column As KanbanColumnState,
                                                       requestedIndex As Integer) As Integer
            If column Is Nothing OrElse column.Cards Is Nothing Then Return 0
            If requestedIndex < 0 Then Return 0
            If requestedIndex > column.Cards.Count Then Return column.Cards.Count
            Return requestedIndex
        End Function

        Private Shared Function ResolveCardIndex(column As KanbanColumnState,
                                                 cardKey As String) As Integer
            If column Is Nothing OrElse column.Cards Is Nothing Then Return -1
            Dim normalized As String = If(cardKey, String.Empty).Trim()
            If normalized.Length = 0 Then Return -1
            For i As Integer = 0 To column.Cards.Count - 1
                Dim card As KanbanCardState = column.Cards(i)
                If card IsNot Nothing AndAlso String.Equals(card.Key, normalized, StringComparison.OrdinalIgnoreCase) Then Return i
            Next
            Return -1
        End Function

        Private Shared Function ResolveColumnMaxTop(column As KanbanColumnState) As Integer
            If column Is Nothing Then Return 0
            Return Math.Max(0, column.Cards.Count - KanbanBoardTokens.MaxVisibleCardsPerColumn)
        End Function

#End Region

    End Class

End Namespace
