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 MASDatePicker
#Region "Rendering"

        Protected Overrides Sub Render(canvas As SKCanvas,
                                       ctx As MASThemeContext,
                                       pixelBounds As SKRect)
            If canvas Is Nothing OrElse ctx Is Nothing Then Return
            If pixelBounds.Width <= 1.0F OrElse pixelBounds.Height <= 1.0F Then Return

            _contract.AssertConsumable()

            Dim dpi As Single = PixelSnap.SafeDpi(ctx.Dpi)
            Dim app As IMASAppTheme = ctx.Theme
            If app Is Nothing Then Return

            Dim surfTheme As IMASFoundationSurfaceTheme = MASAppThemeContracts.Foundation(app).Surface
            If surfTheme Is Nothing Then Return

            Dim ringM As MASSurfaceInteractionRing.Metrics = MASSurfaceInteractionRing.GetMetrics(dpi)
            Dim rBase As SKRect = MASSurfaceInteractionRing.SnapBaseRect(pixelBounds, ringM)
            If rBase.Width <= 1.0F OrElse rBase.Height <= 1.0F Then Return

            _lastPixelBounds = rBase

            If Me.Enabled Then
                _shadowPainter.DrawLayeredShadow(
                    canvas:=canvas,
                    r:=rBase,
                    contract:=_contract,
                    dpi:=dpi,
                    surfaceTheme:=surfTheme)
            End If

            _primitives.DrawAcrylicSurface(canvas:=canvas, ctx:=ctx, r:=rBase, dpi:=dpi, contract:=_contract)
            DrawInteractionOverlay(canvas, app, rBase, dpi)
            DrawCalendarIcon(canvas, ctx, rBase, dpi)
            DrawText(canvas, ctx, rBase, dpi)
        End Sub

        Private Sub DrawInteractionOverlay(canvas As SKCanvas,
                                           app As IMASAppTheme,
                                           rBase As SKRect,
                                           dpi As Single)
            If canvas Is Nothing OrElse app Is Nothing Then Return

            Dim state As MASInteractionState = ResolveInteractionState()
            If state = MASInteractionState.Enabled Then Return

            Dim spec As MASVisualInteractionOverlaySpec = MASInteractionResolver.Build(_contract, state, app)
            If Not spec.FillEnabled AndAlso Not spec.RingEnabled Then Return

            MASSurfaceInteractionRing.DrawOverlay(canvas, rBase, _contract, spec, dpi)
        End Sub

        Private Sub DrawText(canvas As SKCanvas,
                             ctx As MASThemeContext,
                             rBase As SKRect,
                             dpi As Single)
            Dim th As IMASInputTheme = ctx.InputTheme
            If th Is Nothing Then Return

            Dim rawText As String = DisplayText
            Dim drawTextValue As String = If(String.IsNullOrEmpty(rawText), _placeholder, rawText)
            Dim textColor As SKColor = TypographyTextPrimitives.ResolveInputLikeTextColor(th, Not Me.Enabled, rawText)
            Dim textBounds As SKRect = ResolveTextContentBoundsPx(rBase, dpi)

            TypographyTextPrimitives.DrawSingleLineText(
                canvas:=canvas,
                ctx:=ctx,
                text:=drawTextValue,
                bounds:=textBounds,
                dpi:=dpi,
                style:=MASTypography.MASTextStyle.SelectionText,
                color:=textColor,
                align:=TypographyTextPrimitives.TextAlign.Left,
                drawShadow:=False)
        End Sub

        Private Function ResolveTextContentBoundsPx(rBase As SKRect,
                                                    dpi As Single) As SKRect
            Dim slotContentLogical As SKRect = GetLayoutContentBoundsLogicalInternal()
            If slotContentLogical.Width > 1.0F AndAlso slotContentLogical.Height > 1.0F Then
                Dim slotContentPx As New SKRect(
                    slotContentLogical.Left * dpi,
                    slotContentLogical.Top * dpi,
                    slotContentLogical.Right * dpi,
                    slotContentLogical.Bottom * dpi)

                Dim ringM As MASSurfaceInteractionRing.Metrics = MASSurfaceInteractionRing.GetMetrics(dpi)
                Dim ringSafe As Single = Math.Max(0.0F, ringM.RingPathInsetPx)
                Dim resolved As New SKRect(
                    slotContentPx.Left + ringSafe,
                    slotContentPx.Top + ringSafe,
                    slotContentPx.Right - ringSafe,
                    slotContentPx.Bottom - ringSafe)

                If resolved.Width > 1.0F AndAlso resolved.Height > 1.0F Then
                    Return PixelSnap.SnapRectHalf(resolved)
                End If
            End If

            Dim contentRect As SKRect = InputLayoutPrimitives.ComputeInputContentRect(rBase, dpi, False)
            Return InputLayoutPrimitives.ComputeTextBoundsForRightIcon(
                contentRect,
                dpi,
                InputTokens.IconSize + InputTokens.PaddingX,
                0.0F,
                ComboBoxTokens.TextRightPadDip)
        End Function

        Private Sub DrawCalendarIcon(canvas As SKCanvas,
                                     ctx As MASThemeContext,
                                     rBase As SKRect,
                                     dpi As Single)
            If canvas Is Nothing OrElse ctx Is Nothing Then Return

            Dim textTheme As IMASTextColorTheme = ctx.TextColorTheme
            Dim stroke As SKColor = If(textTheme Is Nothing, SKColors.Gray, If(Me.Enabled, textTheme.SecondaryText, textTheme.DisabledText))

            Dim w As Single = DatePickerTokens.CalendarIconWidthDip * dpi
            Dim h As Single = DatePickerTokens.CalendarIconHeightDip * dpi
            Dim rightPad As Single = InputTokens.PaddingX * dpi
            Dim x As Single = rBase.Right - rightPad - w
            Dim y As Single = rBase.MidY - (h * 0.5F)
            Dim rect As SKRect = PixelSnap.SnapRectHalf(New SKRect(x, y, x + w, y + h))
            Dim radius As Single = Math.Max(2.0F, 3.0F * dpi)

            Using p As New SKPaint()
                p.IsAntialias = True
                p.Style = SKPaintStyle.Stroke
                p.StrokeWidth = Math.Max(1.0F, DatePickerTokens.CalendarIconStrokeDip * dpi)
                p.Color = stroke
                canvas.DrawRoundRect(rect, radius, radius, p)

                Dim headerY As Single = rect.Top + (4.2F * dpi)
                canvas.DrawLine(rect.Left, headerY, rect.Right, headerY, p)
                canvas.DrawLine(rect.Left + (4.2F * dpi), rect.Top - (2.0F * dpi), rect.Left + (4.2F * dpi), rect.Top + (2.5F * dpi), p)
                canvas.DrawLine(rect.Right - (4.2F * dpi), rect.Top - (2.0F * dpi), rect.Right - (4.2F * dpi), rect.Top + (2.5F * dpi), p)
            End Using
        End Sub

#End Region

    End Class

End Namespace
