Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports System.Windows.Forms
Imports Nexamas.UI.Components
Imports Nexamas.UI.General
Imports Nexamas.UI.Rendering
Imports Nexamas.UI.Scroll
Imports Nexamas.UI.SkiaScroll
Imports Nexamas.UI.Theming
Imports Nexamas.UI.Layout
Imports SkiaSharp

Namespace Nexamas.UI.FloatRuntime

    Partial Friend NotInheritable Class MASMessageBoxFloatContent
#Region "Content Scroll"

        Private Sub EnsureScrollForContext(ctx As MASThemeContext)
            If _disposed Then Return
            If ctx Is Nothing Then Return

            If _scroll Is Nothing Then
                Try
                    _scroll = ScrollFactory.Create(ctx, AddressOf RequestInvalidate)
                    _scrollCtx = ctx
                Catch masCaughtException1 As Exception
                    Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowBoundary(masCaughtException1, "MessageBox.Float.ScrollCreate")
                    _scroll = Nothing
                    _scrollCtx = Nothing
                End Try

                Return
            End If

            If Object.ReferenceEquals(_scrollCtx, ctx) Then
                Return
            End If

            Try
                _scroll.UpdateThemeContext(ctx)
                _scrollCtx = ctx
            Catch masCaughtException2 As Exception
                Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowBoundary(masCaughtException2, "MessageBox.Float.ScrollThemeUpdate")
            End Try
        End Sub

        Private Sub UpdateContentScrollHost(dpi As Single)
            If _layout Is Nothing Then
                _state.ContentScrollOffsetY = 0.0F
                Return
            End If

            If Not _layout.HasScrollableContent Then
                Dim hadScrollState As Boolean =
                    (_scrollDragging OrElse _isOverScrollbar OrElse _state.ContentScrollOffsetY > 0.0F)

                _state.ContentScrollOffsetY = 0.0F

                If hadScrollState Then
                    CancelScrollInteraction()
                End If

                Return
            End If

            If _scroll Is Nothing Then Return
            If _layout.ContentScrollHostRect.IsEmpty Then Return

            Dim contentHeight As Single = Math.Max(
                _layout.ContentScrollHostRect.Height,
                _layout.ContentRect.Height)

            Try
                _scroll.Update(
                    hostRect:=_layout.ContentScrollHostRect,
                    dpi:=dpi,
                    contentHeight:=contentHeight)
            Catch masCaughtException3 As Exception
                Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowBoundary(masCaughtException3, "MessageBox.Float.ScrollUpdate")
            End Try

            SyncScrollOffsetFromAdapter()
        End Sub

        Private Sub SyncScrollOffsetFromAdapter()
            If _scroll Is Nothing Then Return

            Try
                _state.ContentScrollOffsetY = _scroll.Offset
            Catch masCaughtException4 As Exception
                Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowBoundary(masCaughtException4, "MessageBox.Float.ScrollOffset")
            End Try
        End Sub

        Private Sub DrawContentScrollbar(canvas As SKCanvas)
            If _disposed Then Return
            If canvas Is Nothing Then Return
            If _layout Is Nothing Then Return
            If Not _layout.HasScrollableContent Then Return
            If _scroll Is Nothing Then Return

            Try
                _scroll.Draw(canvas, _isOverScrollbar OrElse _scrollDragging)
            Catch masCaughtException5 As Exception
                Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowBoundary(masCaughtException5, "MessageBox.Float.ScrollDraw")
            End Try
        End Sub

        Private Function HandleContentScrollMove(ptPx As SKPoint) As Boolean
            If _layout Is Nothing Then Return False
            If Not _layout.HasScrollableContent Then
                _isOverScrollbar = False
                _scrollDragging = False
                Return False
            End If

            If _scroll Is Nothing Then Return False

            Dim hit As Boolean = IsContentScrollHit(ptPx)

            If _scrollDragging OrElse hit Then
                _isOverScrollbar = True
                ClearButtonHoverStates()
                _state.CloseHover = False
                _state.CheckBoxHover = False

                Try
                    _scroll.MouseMove(ptPx)
                Catch masCaughtException6 As Exception
                    Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowInputBoundary(masCaughtException6, "MessageBox.Float.ScrollMove")
                End Try

                SyncScrollOffsetFromAdapter()
                ClampScrollOffset()
                Return True
            End If

            If _isOverScrollbar Then
                _isOverScrollbar = False
                Return True
            End If

            Return False
        End Function

        Private Function HandleContentScrollDown(ptPx As SKPoint) As Boolean
            If _layout Is Nothing Then Return False
            If Not _layout.HasScrollableContent Then Return False
            If _scroll Is Nothing Then Return False
            If Not IsContentScrollHit(ptPx) Then Return False

            _isOverScrollbar = True
            _scrollDragging = True
            ClearButtonPressedStates()
            ClearButtonHoverStates()

            Dim stepY As Single = Math.Max(12.0F, _layout.ContentViewportRect.Height * 0.12F)

            Try
                _scroll.MouseDown(ptPx, stepY, 0.86F)
            Catch masCaughtException7 As Exception
                Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowInputBoundary(masCaughtException7, "MessageBox.Float.ScrollDown")
                _scrollDragging = False
            End Try

            SyncScrollOffsetFromAdapter()
            ClampScrollOffset()
            RequestInvalidate()

            Return True
        End Function

        Private Sub CompleteContentScrollPointerUp()
            If _scroll Is Nothing Then Return

            Try
                _scroll.MouseUp()
            Catch masCaughtException8 As Exception
                Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowInputBoundary(masCaughtException8, "MessageBox.Float.ScrollUp")
            End Try

            SyncScrollOffsetFromAdapter()
            ClampScrollOffset()
        End Sub

        Private Sub CancelScrollInteraction()
            _scrollDragging = False
            _isOverScrollbar = False

            If _scroll Is Nothing Then Return

            Try
                _scroll.CancelInteraction()
            Catch masCaughtException9 As Exception
                Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowInputBoundary(masCaughtException9, "MessageBox.Float.ScrollCancel")
            End Try
        End Sub

        Private Function IsContentScrollHit(ptPx As SKPoint) As Boolean
            If _layout Is Nothing Then Return False
            If _layout.ContentScrollRailRect.IsEmpty Then Return False

            Dim hitRect As SKRect = _layout.ContentScrollRailRect
            hitRect.Inflate(Math.Max(3.0F, hitRect.Width * 0.35F), 0.0F)

            Return Contains(hitRect, ptPx)
        End Function

#End Region
    End Class

End Namespace
