Option Strict On
Option Explicit On

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

#Region "Input"

        Protected Overrides Sub OnMouseMove(ctx As MASThemeContext, ptPx As SKPoint)
            Dim hit As PivotCellHit = HitTestCell(ptPx)
            Dim rowKey As String = If(hit IsNot Nothing, hit.RowKey, String.Empty)
            Dim columnKey As String = If(hit IsNot Nothing, hit.ColumnKey, String.Empty)
            If Not String.Equals(_hoverRowKey, rowKey, StringComparison.Ordinal) OrElse Not String.Equals(_hoverColumnKey, columnKey, StringComparison.Ordinal) Then
                _hoverRowKey = rowKey
                _hoverColumnKey = columnKey
                InvalidateVisual()
            End If
        End Sub

        Protected Overrides Function OnMouseDown(ctx As MASThemeContext,
                                                 ptPx As SKPoint,
                                                 button As Integer) As Boolean
            If button <> CInt(MouseButtons.Left) Then Return False
            Dim hit As PivotCellHit = HitTestCell(ptPx)
            If hit Is Nothing Then Return False
            _pressedRowKey = hit.RowKey
            _pressedColumnKey = hit.ColumnKey
            InvalidateVisual()
            Return True
        End Function

        Protected Overrides Function OnMouseUp(ctx As MASThemeContext,
                                               ptPx As SKPoint,
                                               button As Integer) As Boolean
            If button <> CInt(MouseButtons.Left) Then Return False
            Dim hit As PivotCellHit = HitTestCell(ptPx)
            Dim handled As Boolean = False
            If hit IsNot Nothing AndAlso String.Equals(hit.RowKey, _pressedRowKey, StringComparison.Ordinal) AndAlso String.Equals(hit.ColumnKey, _pressedColumnKey, StringComparison.Ordinal) Then
                handled = SelectCell(hit.RowKey, hit.ColumnKey)
            End If
            _pressedRowKey = String.Empty
            _pressedColumnKey = String.Empty
            InvalidateVisual()
            Return handled
        End Function

        Protected Overrides Sub OnMouseLeave(ctx As MASThemeContext)
            _hoverRowKey = String.Empty
            _hoverColumnKey = String.Empty
            InvalidateVisual()
        End Sub

        Protected Overrides Sub OnMouseCancel(ctx As MASThemeContext)
            _pressedRowKey = String.Empty
            _pressedColumnKey = String.Empty
            InvalidateVisual()
        End Sub

        Protected Overrides Sub OnHostLostFocus(ctx As MASThemeContext)
            _pressedRowKey = String.Empty
            _pressedColumnKey = String.Empty
            InvalidateVisual()
        End Sub

        Friend Overrides Function WantsPointerWheel(ctx As MASThemeContext,
                                                      ptPx As SKPoint) As Boolean
            Return Visible AndAlso Enabled AndAlso
                   _gridRect.Contains(ptPx.X, ptPx.Y) AndAlso
                   HasScrollableRowViewport()
        End Function

        Friend Overrides Function CanHandlePointerWheel(ctx As MASThemeContext,
                                                        delta As Integer,
                                                        ptPx As SKPoint) As Boolean
            If delta = 0 OrElse Not WantsPointerWheel(ctx, ptPx) Then Return False
            Return CanScrollRowViewport(delta)
        End Function

        Protected Overrides Sub OnMouseWheel(ctx As MASThemeContext,
                                             delta As Integer,
                                             ptPx As SKPoint)
            If Not CanScrollRowViewport(delta) Then Return
            If delta < 0 Then
                _topRowIndex = Math.Min(ResolveRowViewportMaxTop(), _topRowIndex + 1)
            ElseIf delta > 0 Then
                _topRowIndex = Math.Max(0, _topRowIndex - 1)
            End If
            InvalidateVisual()
        End Sub

        Protected Overrides Function OnKeyDown(ctx As MASThemeContext,
                                               key As Keys) As Boolean
            If _rows.Count = 0 OrElse _columns.Count = 0 Then Return False
            Select Case key
                Case Keys.Left
                    MoveSelectionBy(0, If(MASPivotTablePolicy.ResolveRightToLeft(), 1, -1))
                    Return True
                Case Keys.Right
                    MoveSelectionBy(0, If(MASPivotTablePolicy.ResolveRightToLeft(), -1, 1))
                    Return True
                Case Keys.Up
                    MoveSelectionBy(-1, 0)
                    Return True
                Case Keys.Down
                    MoveSelectionBy(1, 0)
                    Return True
                Case Keys.Home
                    SetSelection(0, 0, True)
                    Return True
                Case Keys.End
                    SetSelection(_rows.Count - 1, _columns.Count - 1, True)
                    Return True
            End Select
            Return False
        End Function

        Protected Overrides Function WantsKeyboardFocus() As Boolean
            Return MASCompositeContentFocusPolicy.CanReceiveKeyboardFocus(Me.ArchitectureContract, Visible, Enabled)
        End Function

        Protected Overrides Function WantsPointerFocus() As Boolean
            Return MASCompositeContentFocusPolicy.AllowsPointerFocusForCompositeContent(Me.ArchitectureContract, Visible, Enabled)
        End Function

#End Region

    End Class

End Namespace
