Option Strict On
Option Explicit On

Imports System
Imports System.Globalization
Imports System.IO
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 MASImageViewer
#Region "Footer Rendering"

        Private Sub DrawFooter(canvas As SKCanvas,
                               ctx As MASThemeContext,
                               footerRect As SKRect,
                               dpi As Single,
                               composition As MASComponentSurfaceMaterialComposition,
                               railCornerRadiusPx As Single,
                               chromeScale As Single)
            If footerRect.Width <= 1.0F OrElse footerRect.Height <= 1.0F Then Return

            Dim accent As SKColor = ResolveAccentColor(ctx)
            Dim primaryText As SKColor = ResolvePrimaryTextColor(ctx)
            Dim mutedText As SKColor = ResolveMutedTextColor(ctx)

            Dim visualFooterRect As SKRect = MASMediaFooterLayoutResolver.ResolveVisualSurfaceRect(footerRect, _lastViewerFrameRect, _lastContentRect, dpi, chromeScale)
            DrawFooterRailSurface(canvas, ctx, visualFooterRect, dpi, composition, railCornerRadiusPx)

            Dim footerLayout As MASMediaFooterLayoutPlan = MASMediaFooterLayoutResolver.Resolve(footerRect, dpi, chromeScale)
            DrawFooterIconChip(canvas, ctx, footerLayout.IconChip, dpi)
            DrawImageFileGlyph(canvas, footerLayout.IconGlyph, dpi, accent.WithAlpha(220))

            If footerLayout.InfoLine.Width > 1.0F Then
                Dim footerMetadata As MASMediaFooterMetadata =
                    MASMediaFooterMetadataResolver.Resolve(title:=_title,
                                                           subtitle:=_subtitle,
                                                           defaultTitle:=ImageViewerTokens.DefaultTitle,
                                                           mediaWidth:=ImageWidth,
                                                           mediaHeight:=ImageHeight)

                DrawFooterInfoLine(canvas:=canvas,
                                   ctx:=ctx,
                                   layout:=footerLayout,
                                   dpi:=dpi,
                                   titleText:=footerMetadata.TitleText,
                                   metadataText:=footerMetadata.MetadataText,
                                   primaryText:=primaryText,
                                   mutedText:=mutedText)
            End If

            DrawFooterRightSeparator(canvas, footerLayout.MenuSeparator, dpi, accent)
            DrawZoomBadge(canvas, ctx, footerLayout.ZoomBadge, dpi, accent, primaryText)
            DrawFooterMenuButton(canvas, footerLayout.MenuButton, footerLayout.MenuGlyph, dpi, accent)
        End Sub

        Private Sub DrawFooterInfoLine(canvas As SKCanvas,
                                       ctx As MASThemeContext,
                                       layout As MASMediaFooterLayoutPlan,
                                       dpi As Single,
                                       titleText As String,
                                       metadataText As String,
                                       primaryText As SKColor,
                                       mutedText As SKColor)
            If canvas Is Nothing OrElse ctx Is Nothing Then Return
            If layout.InfoLine.Width <= 1.0F OrElse layout.InfoLine.Height <= 1.0F Then Return

            titleText = MASImageViewerVisualPolicy.NormalizeText(titleText, ImageViewerTokens.DefaultTitle)
            metadataText = MASImageViewerVisualPolicy.NormalizeText(metadataText, String.Empty)

            Dim titlePaintWidth As Single = MeasureFooterTextWidth(ctx, titleText, MASTypography.MASTextStyle.Title)
            Dim maxTitleRight As Single = layout.TitleText.Right
            Dim titleRight As Single = Math.Min(maxTitleRight, layout.InfoLine.Left + titlePaintWidth + 6.0F * dpi)
            If titleRight <= layout.InfoLine.Left + 1.0F Then titleRight = layout.TitleText.Right

            Dim titleRect As New SKRect(layout.InfoLine.Left,
                                        layout.InfoLine.Top,
                                        Math.Min(layout.InfoLine.Right, titleRight),
                                        layout.InfoLine.Bottom)

            TypographyTextPrimitives.DrawSingleLineText(canvas:=canvas,
                                                        ctx:=ctx,
                                                        text:=titleText,
                                                        bounds:=titleRect,
                                                        dpi:=dpi,
                                                        style:=MASTypography.MASTextStyle.Title,
                                                        color:=primaryText.WithAlpha(CByte(Math.Min(255, CInt(ImageViewerTokens.TextAlpha) + 10))),
                                                        align:=TypographyTextPrimitives.TextAlign.Left,
                                                        drawShadow:=False)

            If metadataText.Length = 0 Then Return
            If layout.MetadataText.Width <= 2.0F OrElse layout.MetadataText.Height <= 1.0F Then Return

            Dim metadataRect As SKRect = layout.MetadataText
            If metadataRect.Width <= 2.0F Then Return

            TypographyTextPrimitives.DrawSingleLineText(canvas:=canvas,
                                                        ctx:=ctx,
                                                        text:=metadataText,
                                                        bounds:=metadataRect,
                                                        dpi:=dpi,
                                                        style:=MASTypography.MASTextStyle.Small,
                                                        color:=mutedText.WithAlpha(CByte(Math.Min(255, CInt(ImageViewerTokens.MutedTextAlpha) + 14))),
                                                        align:=TypographyTextPrimitives.TextAlign.Left,
                                                        drawShadow:=False)
        End Sub

        Private Shared Function MeasureFooterTextWidth(ctx As MASThemeContext,
                                                       text As String,
                                                       style As MASTypography.MASTextStyle) As Single
            If ctx Is Nothing OrElse ctx.Typography Is Nothing OrElse String.IsNullOrEmpty(text) Then Return 0.0F
            Dim paint As SKPaint = ctx.Typography.GetPaint(style, SKColors.Black)
            If paint Is Nothing Then Return 0.0F
            Return MASShapedText.MeasureWidth(text, paint)
        End Function

        Private Shared Sub DrawFooterIconChip(canvas As SKCanvas,
                                              ctx As MASThemeContext,
                                              chip As SKRect,
                                              dpi As Single)
            If canvas Is Nothing OrElse chip.Width <= 1.0F OrElse chip.Height <= 1.0F Then Return

            Dim style As MASMediaVisualStyle = ResolveMediaStyle(ctx, dpi)
            MASMediaControlPainter.DrawChipSurface(canvas:=canvas,
                                                   rect:=chip,
                                                   style:=style,
                                                   dpi:=dpi,
                                                   selected:=False)
        End Sub

        Private Shared Sub DrawFooterRailSurface(canvas As SKCanvas,
                                                 ctx As MASThemeContext,
                                                 footerRect As SKRect,
                                                 dpi As Single,
                                                 composition As MASComponentSurfaceMaterialComposition,
                                                 railCornerRadiusPx As Single)
            If canvas Is Nothing OrElse footerRect.Width <= 1.0F OrElse footerRect.Height <= 1.0F Then Return

            Dim surfaceStrength As Integer = MASImageViewerSurfacePolicy.ResolveSurfaceStrengthLevel(MASComponentSurfaceRegion.Footer, 2)
            Dim borderStrength As Integer = 0
            Dim frameStrength As MASSurfaceFrameStrength = MASSurfaceFrameStrength.Level1

            canvas.Save()
            ClipToPanelShellBottomRail(canvas, footerRect, railCornerRadiusPx)
            Try
                MASSurfaceMaterialComponentGateway.TryDrawComposedCardSurface(
                    canvas:=canvas,
                    ctx:=ctx,
                    boundsPx:=footerRect,
                    composition:=composition,
                    region:=MASComponentSurfaceRegion.Footer,
                    fallbackMaterialKey:=MASImageViewerSurfacePolicy.ResolveFallbackMaterialKey(MASComponentSurfaceRegion.Footer),
                    dpi:=dpi,
                    cornerRadiusPx:=0.0F,
                    opacity:=1.0F,
                    surfaceStrengthLevel:=surfaceStrength,
                    borderStrengthLevel:=borderStrength,
                    frameStrength:=frameStrength,
                    fallbackRole:=MASSurfaceRole.ApplicationChrome)
            Finally
                canvas.Restore()
            End Try

        End Sub

        Private Shared Sub DrawFooterRightSeparator(canvas As SKCanvas,
                                                    separator As SKRect,
                                                    dpi As Single,
                                                    accent As SKColor)
            If canvas Is Nothing OrElse separator.Height <= 1.0F Then Return
            dpi = PixelSnap.SafeDpi(dpi)

            Using stroke As New SKPaint With {
                .IsAntialias = True,
                .Style = SKPaintStyle.Stroke,
                .StrokeWidth = Math.Max(1.0F, 1.0F * dpi),
                .Color = accent.WithAlpha(34)
            }
                canvas.DrawLine(separator.Left, separator.Top, separator.Left, separator.Bottom, stroke)
            End Using
        End Sub

        Private Shared Sub DrawFooterMenuButton(canvas As SKCanvas,
                                                buttonRect As SKRect,
                                                glyphRect As SKRect,
                                                dpi As Single,
                                                accent As SKColor)
            If canvas Is Nothing OrElse buttonRect.Width <= 1.0F OrElse buttonRect.Height <= 1.0F Then Return
            If glyphRect.Width <= 1.0F OrElse glyphRect.Height <= 1.0F Then Return

            DrawFooterMenuGlyph(canvas, glyphRect, dpi, accent.WithAlpha(214))
        End Sub

        Private Shared Sub DrawFooterMenuGlyph(canvas As SKCanvas,
                                               glyphRect As SKRect,
                                               dpi As Single,
                                               color As SKColor)
            If canvas Is Nothing OrElse glyphRect.Width <= 1.0F OrElse glyphRect.Height <= 1.0F Then Return
            dpi = PixelSnap.SafeDpi(dpi)

            Using p As New SKPaint With {
                .IsAntialias = True,
                .Style = SKPaintStyle.Stroke,
                .StrokeWidth = Math.Max(1.4F, 1.8F * dpi),
                .Color = color,
                .StrokeCap = SKStrokeCap.Round,
                .StrokeJoin = SKStrokeJoin.Round
            }
                Dim dotRadius As Single = Math.Max(1.2F, 1.45F * dpi)
                Dim xDot As Single = glyphRect.Left + glyphRect.Width * 0.18F
                Dim xLine1 As Single = glyphRect.Left + glyphRect.Width * 0.38F
                Dim xLine2 As Single = glyphRect.Right - glyphRect.Width * 0.12F
                Dim y1 As Single = glyphRect.Top + glyphRect.Height * 0.28F
                Dim y2 As Single = glyphRect.MidY
                Dim y3 As Single = glyphRect.Bottom - glyphRect.Height * 0.28F

                canvas.DrawCircle(xDot, y1, dotRadius, p)
                canvas.DrawCircle(xDot, y2, dotRadius, p)
                canvas.DrawCircle(xDot, y3, dotRadius, p)
                canvas.DrawLine(xLine1, y1, xLine2, y1, p)
                canvas.DrawLine(xLine1, y2, xLine2, y2, p)
                canvas.DrawLine(xLine1, y3, xLine2, y3, p)
            End Using
        End Sub


#End Region

    End Class

End Namespace
