Option Strict On
Option Explicit On

Imports System
Imports System.Globalization
Imports System.Windows.Forms
Imports Nexamas.UI.Architecture
Imports Nexamas.UI.Components.ListPopup
Imports Nexamas.UI.Controls
Imports Nexamas.UI.FloatRuntime
Imports Nexamas.UI.General
Imports Nexamas.UI.Layout
Imports Nexamas.UI.Rendering
Imports Nexamas.UI.Theming
Imports Nexamas.UI.TextRendering
Imports Nexamas.UI.Composition
Imports Nexamas.UI.Values
Imports SkiaSharp

Namespace Nexamas.UI.Components

    Partial Public NotInheritable Class MASTimePicker
#Region "Clock Popup Runtime"

        Private Sub ToggleClock(ctx As MASThemeContext)
            If ctx Is Nothing Then Return
            If ResolveFloatRuntime() Is Nothing Then Return
            If Me.Host Is Nothing Then Return
            If Not Me.Enabled OrElse Not Me.Visible Then Return

            If _isClockOpen Then
                CloseClockSafe()
                Return
            End If

            Dim preAnchorBoundsPx As SKRect = ResolveClockAnchorBoundsPx(_lastPixelBounds)
            If preAnchorBoundsPx.Width <= 1.0F OrElse preAnchorBoundsPx.Height <= 1.0F Then Return

            _popupService.CloseAny()
            _isClockOpen = True
            _pressed = False
            InvalidateVisual()

            Dim dpi As Single = PixelSnap.SafeDpi(ctx.Dpi)
            Dim popupSize As SKSize = CalculateClockPopupSizePx(ctx, preAnchorBoundsPx)
            Dim boundsPx As SKRect = DropDownPositionPolicy.Calculate(
                preAnchorBoundsPx,
                popupSize,
                dpi,
                ResolveClockPopupGapPx(ctx, popupSize),
                ResolveSurfaceSizeProvider())

            Dim content As MASFloatControlsContent = Nothing

            Dim view As New MASTimePickerClockView(
                owner:=Me,
                selectedTime:=ResolveWorkingTimeForOpen(),
                minimumTime:=_minimumTime,
                maximumTime:=_maximumTime,
                minuteStep:=_minuteStep,
                onTimeSelected:=
                    Sub(value As Nullable(Of TimeSpan))
                        Me.SelectedTime = value
                        CompleteClockSelection(content)
                    End Sub)

            content = New MASFloatControlsContent(
                TimePickerTokens.ClockPopupOwnerKey,
                Me.Host,
                Sub()
                    Me.InvalidateVisual()
                End Sub)

            content.CloseOnEscape = True
            content.CloseOnOutsidePointer = True
            content.AcceptsKeyboardInput = True
            content.AcceptsTextInput = True
            content.AcceptsPointerInput = True
            content.Add(view)

            Try
                _popupService.ShowOwned(Me, content, NormalizeClockFloatBoundsPx(boundsPx))

                If Not IsCurrentClockHandleOpen() Then
                    _popupService.CloseAny()
                    _isClockOpen = False
                    ResetInputAll()
                    InvalidateVisual()
                End If
            Catch masTimePickerShowException As Exception
                Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowInputBoundary(masTimePickerShowException, "MASTimePicker.ToggleClock.ShowOwned")
                _isClockOpen = False
                ResetInputAll()
                InvalidateVisual()
            End Try
        End Sub

        Private Sub CompleteClockSelection(content As MASFloatControlsContent)
            _isClockOpen = False
            ResetInputAll()

            Try
                If content IsNot Nothing AndAlso content.Session IsNot Nothing Then
                    content.Session.Close(MASFloatCloseReason.Accepted)
                End If
            Catch masTimePickerSessionCloseException As Exception
                Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowInputBoundary(masTimePickerSessionCloseException, "MASTimePicker.CompleteClockSelection.SessionClose")
            End Try

            If _popupService IsNot Nothing Then
                _popupService.CloseIfOwnedBy(Me)
            End If

            InvalidateVisual()
        End Sub

        Private Sub CloseClockSafe()
            Dim wasOpen As Boolean = _isClockOpen
            Dim hadOwnedState As Boolean =
                (_popupService IsNot Nothing AndAlso
                 (_popupService.CurrentHandle IsNot Nothing OrElse _popupService.CurrentContent IsNot Nothing))

            _isClockOpen = False
            ResetInputAll()

            If wasOpen OrElse hadOwnedState Then
                _popupService.CloseIfOwnedBy(Me)
            End If

            InvalidateVisual()
        End Sub

        Private Function ShowClockFloat(ownerKey As String,
                                        content As IMASFloatContent,
                                        boundsPx As SKRect) As MASFloatHandle
            Dim runtime As MASFloatRuntime = ResolveFloatRuntime()
            If runtime Is Nothing OrElse content Is Nothing Then Return Nothing

            boundsPx = NormalizeClockFloatBoundsPx(boundsPx)
            If boundsPx.Width <= 1.0F OrElse boundsPx.Height <= 1.0F Then Return Nothing

            If String.IsNullOrWhiteSpace(ownerKey) Then ownerKey = TimePickerTokens.ClockPopupOwnerKey

            Dim request As New MASFloatRequest() With {
                .FloatKey = MASFloatKeys.TimePickerClock,
                .OwnerKey = ownerKey,
                .Content = content,
                .RequestedSlot = MASFloatSlot.Popup,
                .RequestedScope = MASFloatScope.Owner,
                .RequestedLayer = MASFloatLayerLevel.Interactive,
                .ShowPolicy = MASFloatShowPolicy.CloseSameOwnerThenShow,
                .AnchorRectPx = ResolveClockAnchorBoundsPx(boundsPx),
                .InitialBoundsPx = boundsPx,
                .AvailableBoundsPx = ResolveAvailableBoundsPx(boundsPx),
                .RequestedPresentation = MASFloatPresentationProfiles.DropDownList()
            }

            Return runtime.Show(request)
        End Function

        Private Sub CloseClockIfOpenForPolicyChange()
            If _isClockOpen Then CloseClockSafe()
        End Sub

        Private Function ResolveFloatRuntime() As MASFloatRuntime
            If _floatRuntime IsNot Nothing Then Return _floatRuntime
            If _runtimeServices IsNot Nothing Then Return _runtimeServices.TryGetFloatRuntime()
            Return Nothing
        End Function

        Private Function IsCurrentClockHandleOpen() As Boolean
            Dim runtime As MASFloatRuntime = ResolveFloatRuntime()
            If runtime Is Nothing OrElse _popupService Is Nothing OrElse _popupService.CurrentHandle Is Nothing Then Return False

            Try
                Return runtime.IsOpen(_popupService.CurrentHandle)
            Catch masCaughtException5 As Exception
                Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowInputBoundary(masCaughtException5, "MASTimePicker.VerifyClockHandle")
                Return False
            End Try
        End Function

#End Region

    End Class

End Namespace
