Option Strict On
Option Explicit On

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

#Region "Rendering Body"

        Private Sub DrawAgendaBody(canvas As SKCanvas,
                                   ctx As MASThemeContext,
                                   content As SKRect,
                                   dpi As Single,
                                   isRtl As Boolean,
                                   plan As MASAgendaViewLayoutPlan)
            _eventHitRects.Clear()
            Dim headerBottom As Single = content.Top + plan.HeaderHeightPx
            Dim footerTop As Single = content.Bottom - plan.FooterHeightPx
            _eventsRect = PixelSnap.SnapRect(New SKRect(content.Left, headerBottom + plan.RowGapPx, content.Right, footerTop - plan.RowGapPx), dpi)
            If _eventsRect.Width <= 1.0F OrElse _eventsRect.Height <= 1.0F Then Return

            If _viewMode <> MASAgendaViewMode.Day Then
                DrawAgendaRangeBody(canvas, ctx, _eventsRect, dpi, isRtl, plan)
                If GetVisibleEventCountForCurrentView() = 0 Then DrawAgendaEmptyState(canvas, ctx, _eventsRect, dpi, plan)
                Return
            End If

            DrawTimeRail(canvas, ctx, _eventsRect, dpi, isRtl, plan)
            DrawNowMarker(canvas, ctx, _eventsRect, dpi, isRtl, plan)
            If GetVisibleEventCountForCurrentView() = 0 Then
                DrawAgendaEmptyState(canvas, ctx, _eventsRect, dpi, plan)
                Return
            End If

            Dim slots As List(Of AgendaEventLayoutSlot) = BuildTimedEventLayout(_eventsRect, dpi, isRtl, plan)
            If slots.Count = 0 Then
                DrawAgendaEmptyState(canvas, ctx, _eventsRect, dpi, plan)
                Return
            End If

            DrawAgendaEventSelectionMotionOverlay(canvas, ctx, slots, dpi, plan)

            For Each slot As AgendaEventLayoutSlot In slots
                _eventHitRects.Add(New AgendaEventHit(slot.EventIndex, slot.Rect))
                DrawEventRow(canvas, ctx, slot.Rect, dpi, isRtl, slot.EventIndex, plan)
            Next
        End Sub

        Private Sub DrawTimeRail(canvas As SKCanvas,
                                 ctx As MASThemeContext,
                                 body As SKRect,
                                 dpi As Single,
                                 isRtl As Boolean,
                                 plan As MASAgendaViewLayoutPlan)
            If plan Is Nothing Then Return
            Dim railWidth As Single = plan.TimeRailWidthPx
            If railWidth <= 1.0F OrElse Not plan.ShowTimeRail Then Return
            Dim rail As SKRect = If(isRtl,
                                    New SKRect(body.Right - railWidth, body.Top, body.Right, body.Bottom),
                                    New SKRect(body.Left, body.Top, body.Left + railWidth, body.Bottom))
            Dim primary As SKColor = MASAgendaViewPolicy.ResolveMutedTextColor(ctx)
            Dim accent As SKColor = MASAgendaViewPolicy.ResolveAccentColor(ctx)
            Using stroke As New SKPaint With {.IsAntialias = True, .Style = SKPaintStyle.Stroke, .StrokeWidth = Math.Max(1.0F, dpi), .Color = primary.WithAlpha(AgendaViewTokens.DividerAlpha)}
                Dim lineX As Single = If(isRtl, rail.Left, rail.Right)
                canvas.DrawLine(lineX, rail.Top, lineX, rail.Bottom, stroke)
            End Using
            Dim startText As String = _startHour.ToString("00", CultureInfo.InvariantCulture) & ":00"
            Dim endText As String = _endHour.ToString("00", CultureInfo.InvariantCulture) & ":00"
            Dim startRect As New SKRect(rail.Left, rail.Top, rail.Right, rail.Top + 26.0F * dpi)
            Dim endRect As New SKRect(rail.Left, rail.Bottom - 26.0F * dpi, rail.Right, rail.Bottom)
            TypographyTextPrimitives.DrawSingleLineText(canvas, ctx, startText, startRect, dpi, MASTypography.MASTextStyle.Micro, primary, TypographyTextPrimitives.TextAlign.Center, False)
            TypographyTextPrimitives.DrawSingleLineText(canvas, ctx, endText, endRect, dpi, MASTypography.MASTextStyle.Micro, primary, TypographyTextPrimitives.TextAlign.Center, False)
            Dim midHour As Integer = _startHour + Math.Max(1, (_endHour - _startHour) \ 2)
            Dim midText As String = midHour.ToString("00", CultureInfo.InvariantCulture) & ":00"
            Dim midRect As New SKRect(rail.Left, rail.MidY - 13.0F * dpi, rail.Right, rail.MidY + 13.0F * dpi)
            TypographyTextPrimitives.DrawSingleLineText(canvas, ctx, midText, midRect, dpi, MASTypography.MASTextStyle.Micro, primary.WithAlpha(150), TypographyTextPrimitives.TextAlign.Center, False)
            Using dot As New SKPaint With {.IsAntialias = True, .Style = SKPaintStyle.Fill, .Color = accent.WithAlpha(130)}
                canvas.DrawCircle(rail.MidX, rail.MidY, 3.0F * dpi, dot)
            End Using
        End Sub

        Private Sub DrawAgendaEmptyState(canvas As SKCanvas,
                                         ctx As MASThemeContext,
                                         rect As SKRect,
                                         dpi As Single,
                                         plan As MASAgendaViewLayoutPlan)
            Dim accent As SKColor = MASAgendaViewPolicy.ResolveAccentColor(ctx)
            Dim panelWidth As Single = Math.Min(rect.Width * 0.72F, 320.0F * dpi)
            Dim panelHeight As Single = If(plan IsNot Nothing AndAlso CInt(plan.Mode) >= CInt(MASResponsiveLayoutMode.Minimal), 58.0F * dpi, 86.0F * dpi)
            Dim panel As New SKRect(rect.MidX - panelWidth * 0.5F,
                                    rect.MidY - panelHeight * 0.5F,
                                    rect.MidX + panelWidth * 0.5F,
                                    rect.MidY + panelHeight * 0.5F)
            Using fill As New SKPaint With {.IsAntialias = True, .Style = SKPaintStyle.Fill, .Color = accent.WithAlpha(18)}
                canvas.DrawRoundRect(panel, 18.0F * dpi, 18.0F * dpi, fill)
            End Using
            Using stroke As New SKPaint With {.IsAntialias = True, .Style = SKPaintStyle.Stroke, .StrokeWidth = Math.Max(1.0F, dpi), .Color = accent.WithAlpha(44)}
                canvas.DrawRoundRect(panel, 18.0F * dpi, 18.0F * dpi, stroke)
            End Using
            Dim titleRect As New SKRect(panel.Left + 14.0F * dpi, panel.Top + 16.0F * dpi, panel.Right - 14.0F * dpi, panel.Top + 42.0F * dpi)
            Dim subRect As New SKRect(panel.Left + 14.0F * dpi, titleRect.Bottom + 4.0F * dpi, panel.Right - 14.0F * dpi, panel.Bottom - 12.0F * dpi)
            TypographyTextPrimitives.DrawSingleLineText(canvas, ctx, AgendaViewTokens.EmptyAgendaText, titleRect, dpi, MASTypography.MASTextStyle.Body, MASAgendaViewPolicy.ResolvePrimaryTextColor(ctx), TypographyTextPrimitives.TextAlign.Center, False)
            If plan Is Nothing OrElse CInt(plan.Mode) < CInt(MASResponsiveLayoutMode.Minimal) Then
                TypographyTextPrimitives.DrawSingleLineText(canvas, ctx, "Use AddEvent to populate the day timeline", subRect, dpi, MASTypography.MASTextStyle.Micro, MASAgendaViewPolicy.ResolveMutedTextColor(ctx), TypographyTextPrimitives.TextAlign.Center, False)
            End If
        End Sub

        Private Sub DrawNowMarker(canvas As SKCanvas,
                                  ctx As MASThemeContext,
                                  body As SKRect,
                                  dpi As Single,
                                  isRtl As Boolean,
                                  plan As MASAgendaViewLayoutPlan)
            Dim now As DateTime = ResolveNow()
            If _day <> now.Date Then Return
            Dim nowMinute As Integer = now.Hour * 60 + now.Minute
            Dim startMinute As Integer = _startHour * 60
            Dim endMinute As Integer = _endHour * 60
            If nowMinute < startMinute OrElse nowMinute > endMinute OrElse endMinute <= startMinute Then Return
            If plan Is Nothing Then Return
            Dim railWidth As Single = plan.TimeRailWidthPx
            If railWidth <= 1.0F OrElse Not plan.ShowTimeRail Then Return
            Dim rail As SKRect = If(isRtl,
                                    New SKRect(body.Right - railWidth, body.Top, body.Right, body.Bottom),
                                    New SKRect(body.Left, body.Top, body.Left + railWidth, body.Bottom))
            Dim ratio As Single = CSng(nowMinute - startMinute) / CSng(endMinute - startMinute)
            Dim y As Single = body.Top + Math.Max(0.0F, Math.Min(1.0F, ratio)) * body.Height
            Dim accent As SKColor = MASAgendaViewPolicy.ResolveAccentColor(ctx)
            Using stroke As New SKPaint With {.IsAntialias = True, .Style = SKPaintStyle.Stroke, .StrokeWidth = Math.Max(1.0F, dpi), .Color = accent.WithAlpha(70)}
                canvas.DrawLine(body.Left, y, body.Right, y, stroke)
            End Using
            Using dot As New SKPaint With {.IsAntialias = True, .Style = SKPaintStyle.Fill, .Color = accent.WithAlpha(220)}
                canvas.DrawCircle(rail.MidX, y, 4.2F * dpi, dot)
            End Using
            Dim labelRect As New SKRect(rail.Left, y - 10.0F * dpi, rail.Right, y + 10.0F * dpi)
            TypographyTextPrimitives.DrawSingleLineText(canvas, ctx, "now", labelRect, dpi, MASTypography.MASTextStyle.Micro, MASAgendaViewPolicy.ResolvePrimaryTextColor(ctx), TypographyTextPrimitives.TextAlign.Center, False)
        End Sub

#End Region

    End Class

End Namespace
