Option Strict On
Option Explicit On

Imports System
Imports System.Windows.Forms
Imports Nexamas.UI.Architecture
Imports Nexamas.UI.Components
Imports Nexamas.UI.Composition
Imports Nexamas.UI.General
Imports Nexamas.UI.Layout
Imports Nexamas.UI.Motion
Imports Nexamas.UI.Rendering
Imports Nexamas.UI.TextRendering
Imports Nexamas.UI.Theming
Imports Nexamas.UI.Values
Imports SkiaSharp

Namespace Nexamas.UI.Controls


    Partial Public NotInheritable Class MASButton
#Region "Helpers"

        Private Function CanRenderAsEnabled() As Boolean
            Return MASButtonActivationPolicy.CanRenderAsEnabled(Enabled, _isBusy, _disableWhileBusy)
        End Function

        Private Sub SyncInteractionEnabledState()
            ApplyResult(
                _interactionController.HandleEnabledChanged(
                    state:=_state,
                    isEnabled:=CanRenderAsEnabled()))
        End Sub

        Private Function BuildButtonSpec() As MASButtonSpec
            Return New MASButtonSpec(
                text:=MASButtonActivationPolicy.EffectiveText(_text, _busyText, _isBusy),
                personality:=MASButtonActivationPolicy.NormalizePersonality(_personality),
                intent:=MASButtonActivationPolicy.NormalizeIntent(_intent),
                isDefault:=_isDefaultButton,
                isSelected:=_isSelected,
                isEnabled:=CanRenderAsEnabled()
            )
        End Function

        Private Function ToLocalPoint(ctx As MASThemeContext, surfacePoint As SKPoint) As SKPoint
            Dim rPx As SKRect = GetPixelBounds(ctx)
            Return New SKPoint(surfacePoint.X - rPx.Left, surfacePoint.Y - rPx.Top)
        End Function

        Private Function GetLocalPixelBounds(ctx As MASThemeContext) As SKRect
            Dim rPx As SKRect = GetPixelBounds(ctx)
            Return New SKRect(0.0F, 0.0F, rPx.Width, rPx.Height)
        End Function

        Private Function ResolveIntrinsicDesiredSize(context As MASSizeContext) As SKSize
            Dim textMeasure As MASTextMeasureResult =
                MASLayoutTextMeasureGateway.Measure(
                    context.IntegrationContext,
                    MASButtonActivationPolicy.EffectiveText(_text, _busyText, _isBusy),
                    MASTypography.MASTextStyle.Button,
                    Single.PositiveInfinity,
                    allowWrap:=False)

            Dim hasText As Boolean = Not String.IsNullOrEmpty(MASButtonActivationPolicy.EffectiveText(_text, _busyText, _isBusy))
            Dim iconIsHorizontal As Boolean =
                _iconPlacement = MASButtonIconPlacement.Left OrElse
                _iconPlacement = MASButtonIconPlacement.Right

            Return MASIntrinsicControlSizeMetrics.ResolveButtonDesiredSize(
                measuredTextSize:=textMeasure.Size,
                hasText:=hasText,
                hasIcon:=Me.HasIcon,
                iconIsHorizontal:=iconIsHorizontal,
                preferredWidth:=_preferredWidth,
                preferredHeight:=_preferredHeight,
                minimumWidth:=_minWidth,
                minimumHeight:=_minHeight)
        End Function

        Private Shared Function CreateSizeContext(context As MASLayoutMeasureContext) As MASSizeContext
            If context Is Nothing Then Return New MASSizeContext(New SKSize(Single.PositiveInfinity, Single.PositiveInfinity))
            Return context.ToSizeContext()
        End Function

        Private Shared Function NormalizeExtent(value As Single) As Single
            Return MASButtonActivationPolicy.NormalizeExtent(value)
        End Function

        Private Shared Function NormalizeCoordinate(value As Single) As Single
            Return MASButtonActivationPolicy.NormalizeCoordinate(value)
        End Function

        Private Shared Function NormalizeIntent(value As MASButtonIntent) As MASButtonIntent
            Return MASButtonActivationPolicy.NormalizeIntent(value)
        End Function

        Private Shared Function NormalizePersonality(value As MASButtonPersonality) As MASButtonPersonality
            Return MASButtonActivationPolicy.NormalizePersonality(value)
        End Function

        Private Shared Function NormalizeIconPlacement(value As MASButtonIconPlacement) As MASButtonIconPlacement
            Return MASButtonActivationPolicy.NormalizeIconPlacement(value)
        End Function

        Private Sub PulsePressMotion()
            _motionPressActive = True

            StopPressMotion(clearPressed:=False)
            _motionPressActive = True

            Dim plan As MASMotionTransitionPlan = MASMotionSystem.CreateTransitionPlan(MASMotionTokenId.PressDown, 0.0F, 1.0F)

            _pressPulseRunner = MASMotionSystem.CreateTimelineRunner(
                owner:=Me,
                consumerName:="MASButton.PressPulse",
                plan:=plan,
                requestFrame:=AddressOf InvalidateVisual,
                applyFrame:=AddressOf ApplyPressMotionFrame,
                completed:=AddressOf CompletePressMotionFrame)
            _pressPulseRunner.Start()

            InvalidateVisual()
        End Sub

        Private Sub ApplyPressMotionFrame(frame As MASMotionFrame)
            If frame Is Nothing Then Return
            InvalidateVisual()
        End Sub

        Private Sub CompletePressMotionFrame(frame As MASMotionFrame)
            StopPressMotion(clearPressed:=True)
            InvalidateVisual()
        End Sub

        Private Sub StopPressMotion(clearPressed As Boolean)
            If _pressPulseRunner IsNot Nothing Then
                _pressPulseRunner.Dispose()
                _pressPulseRunner = Nothing
            End If

            If clearPressed Then
                _motionPressActive = False
            End If
        End Sub

#End Region

    End Class

End Namespace
