Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
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.Motion
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 MASContentCarousel
#Region "Rendering - cards"

        Private Sub DrawSideCards(canvas As SKCanvas,
                                  ctx As MASThemeContext,
                                  stage As SKRect,
                                  dpi As Single,
                                  plan As MASContentCarouselLayoutPlan,
                                  accent As SKColor,
                                  isRtl As Boolean)
            If _items.Count <= 1 Then Return
            Dim previousIndex As Integer = MASContentCarouselPolicy.MoveIndex(_selectedIndex, -1, _items.Count, _isLooping)
            Dim nextIndex As Integer = MASContentCarouselPolicy.MoveIndex(_selectedIndex, 1, _items.Count, _isLooping)
            If previousIndex = _selectedIndex AndAlso Not _isLooping Then previousIndex = -1
            If nextIndex = _selectedIndex AndAlso Not _isLooping Then nextIndex = -1

            Dim sideWidth As Single = ResolveSideCardWidth(stage, dpi, plan)
            Dim sideHeight As Single = stage.Height * plan.SideCardScale
            Dim y As Single = stage.MidY - sideHeight / 2.0F
            Dim edgeInset As Single = plan.SideCardEdgeInsetPx
            Dim leftRect As New SKRect(stage.Left + edgeInset, y, stage.Left + edgeInset + sideWidth, y + sideHeight)
            Dim rightRect As New SKRect(stage.Right - edgeInset - sideWidth, y, stage.Right - edgeInset, y + sideHeight)

            Dim leadingIndex As Integer = If(isRtl, nextIndex, previousIndex)
            Dim trailingIndex As Integer = If(isRtl, previousIndex, nextIndex)
            If leadingIndex >= 0 Then DrawAdjacentSlideCard(canvas, ctx, leftRect, dpi, plan, accent, leadingIndex)
            If trailingIndex >= 0 Then DrawAdjacentSlideCard(canvas, ctx, rightRect, dpi, plan, accent, trailingIndex)
        End Sub


        Private Sub DrawAdjacentSlideCard(canvas As SKCanvas,
                                    ctx As MASThemeContext,
                                    rect As SKRect,
                                    dpi As Single,
                                    plan As MASContentCarouselLayoutPlan,
                                    accent As SKColor,
                                    index As Integer)
            If index < 0 OrElse index >= _items.Count Then Return
            Using fill As New SKPaint With {.IsAntialias = True, .Style = SKPaintStyle.Fill, .Color = accent.WithAlpha(ContentCarouselTokens.SideCardAlpha)}
                canvas.DrawRoundRect(rect, plan.CardRadiusPx, plan.CardRadiusPx, fill)
            End Using
            Using stroke As New SKPaint With {.IsAntialias = True, .Style = SKPaintStyle.Stroke, .StrokeWidth = Math.Max(1.0F, dpi), .Color = accent.WithAlpha(ContentCarouselTokens.SideCardStrokeAlpha)}
                canvas.DrawRoundRect(rect, plan.CardRadiusPx, plan.CardRadiusPx, stroke)
            End Using
            Dim textRect As SKRect = Inset(rect, Math.Min(plan.CardPaddingPx, 12.0F * dpi * plan.ResponsiveProfile.ChromeScale))
            Dim item As CarouselItemState = _items(index)
            Dim titleRect As New SKRect(textRect.Left, textRect.MidY - 18.0F * dpi, textRect.Right, textRect.MidY + 2.0F * dpi)
            Dim subRect As New SKRect(textRect.Left, titleRect.Bottom + 3.0F * dpi, textRect.Right, titleRect.Bottom + 22.0F * dpi)
            TypographyTextPrimitives.DrawSingleLineText(canvas, ctx, item.Title, titleRect, dpi, MASTypography.MASTextStyle.Small, MASContentCarouselPolicy.ResolvePrimaryTextColor(ctx).WithAlpha(ContentCarouselTokens.SideCardTextAlpha), TypographyTextPrimitives.TextAlign.Center, False)
            If item.Subtitle.Length > 0 Then
                TypographyTextPrimitives.DrawSingleLineText(canvas, ctx, item.Subtitle, subRect, dpi, MASTypography.MASTextStyle.Micro, MASContentCarouselPolicy.ResolveMutedTextColor(ctx).WithAlpha(ContentCarouselTokens.DetailTextAlpha), TypographyTextPrimitives.TextAlign.Center, False)
            End If
            _hits.Add(New CarouselHit(CarouselHitKind.Item, index, rect))
        End Sub


        Private Sub DrawCenterCard(canvas As SKCanvas,
                                   ctx As MASThemeContext,
                                   stage As SKRect,
                                   dpi As Single,
                                   plan As MASContentCarouselLayoutPlan,
                                   accent As SKColor,
                                   isRtl As Boolean)
            DrawCenterCardAtIndex(canvas, ctx, stage, dpi, plan, accent, isRtl, _selectedIndex, 0.0F, 1.0F, True)
        End Sub


        Private Sub DrawTransitioningCenterCards(canvas As SKCanvas,
                                                 ctx As MASThemeContext,
                                                 stage As SKRect,
                                                 dpi As Single,
                                                 plan As MASContentCarouselLayoutPlan,
                                                 accent As SKColor,
                                                 isRtl As Boolean)
            Dim progress As Single = MASMotionSystem.ClampProgress(_motionProgress)
            Dim travel As Single = stage.Width * 0.08F
            Dim fromOffset As Single = -CSng(_motionDirection) * travel * progress
            Dim toOffset As Single = CSng(_motionDirection) * travel * (1.0F - progress)
            DrawCenterCardAtIndex(canvas, ctx, stage, dpi, plan, accent, isRtl, _motionFromIndex, fromOffset, 1.0F - progress, False)
            DrawCenterCardAtIndex(canvas, ctx, stage, dpi, plan, accent, isRtl, _motionToIndex, toOffset, progress, True)
        End Sub


        Private Sub DrawCenterCardAtIndex(canvas As SKCanvas,
                                          ctx As MASThemeContext,
                                          stage As SKRect,
                                          dpi As Single,
                                          plan As MASContentCarouselLayoutPlan,
                                          accent As SKColor,
                                          isRtl As Boolean,
                                          itemIndex As Integer,
                                          offsetX As Single,
                                          opacity As Single,
                                          addHit As Boolean)
            If itemIndex < 0 OrElse itemIndex >= _items.Count Then Return
            Dim alphaScale As Single = MASMotionSystem.ClampProgress(opacity)
            If alphaScale <= 0.001F Then Return
            Dim cardWidth As Single = ResolveCenterCardWidth(stage, dpi, plan)
            Dim cardHeight As Single = Math.Min(stage.Height - 30.0F * dpi * plan.ResponsiveProfile.GapScale, plan.CenterCardMaxHeightPx)
            Dim card As New SKRect(stage.MidX - cardWidth / 2.0F + offsetX,
                                   stage.MidY - cardHeight / 2.0F,
                                   stage.MidX + cardWidth / 2.0F + offsetX,
                                   stage.MidY + cardHeight / 2.0F)
            card = PixelSnap.SnapRect(card, dpi)

            Using fill As New SKPaint With {.IsAntialias = True, .Style = SKPaintStyle.Fill, .Color = WithOpacity(accent.WithAlpha(ContentCarouselTokens.CenterCardAlpha), alphaScale)}
                canvas.DrawRoundRect(card, plan.CardRadiusPx, plan.CardRadiusPx, fill)
            End Using
            Using stroke As New SKPaint With {.IsAntialias = True, .Style = SKPaintStyle.Stroke, .StrokeWidth = Math.Max(1.0F, 1.4F * dpi), .Color = WithOpacity(accent.WithAlpha(ContentCarouselTokens.CardSelectedStrokeAlpha), alphaScale)}
                canvas.DrawRoundRect(card, plan.CardRadiusPx, plan.CardRadiusPx, stroke)
            End Using

            Dim item As CarouselItemState = _items(itemIndex)
            Dim inner As SKRect = Inset(card, plan.CardPaddingPx)
            Dim align As TypographyTextPrimitives.TextAlign = If(isRtl, TypographyTextPrimitives.TextAlign.Right, TypographyTextPrimitives.TextAlign.Left)
            Dim titleRect As New SKRect(inner.Left, inner.Top, inner.Right, inner.Top + 34.0F * dpi)
            Dim subtitleRect As New SKRect(inner.Left, titleRect.Bottom + 2.0F * dpi, inner.Right, titleRect.Bottom + 26.0F * dpi)
            Dim detailRect As New SKRect(inner.Left, subtitleRect.Bottom + 8.0F * dpi, inner.Right, inner.Bottom)

            TypographyTextPrimitives.DrawSingleLineText(canvas, ctx, item.Title, titleRect, dpi, MASTypography.MASTextStyle.Title, WithOpacity(MASContentCarouselPolicy.ResolvePrimaryTextColor(ctx), alphaScale), align, False)
            If plan.ShowSubtitle AndAlso item.Subtitle.Length > 0 Then
                TypographyTextPrimitives.DrawSingleLineText(canvas, ctx, item.Subtitle, subtitleRect, dpi, MASTypography.MASTextStyle.Small, WithOpacity(MASContentCarouselPolicy.ResolveMutedTextColor(ctx), alphaScale), align, False)
            End If
            If plan.ShowDetail AndAlso item.Detail.Length > 0 Then
                TypographyTextPrimitives.DrawSingleLineText(canvas, ctx, item.Detail, detailRect, dpi, MASTypography.MASTextStyle.Body, WithOpacity(MASContentCarouselPolicy.ResolveMutedTextColor(ctx).WithAlpha(ContentCarouselTokens.DetailTextAlpha), alphaScale), align, False)
            End If

            If addHit Then _hits.Add(New CarouselHit(CarouselHitKind.Item, itemIndex, card))
        End Sub


#End Region
    End Class

End Namespace
