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 "Toolbar Rendering"

        Private Sub DrawToolbar(canvas As SKCanvas,
                                ctx As MASThemeContext,
                                toolbarRect As SKRect,
                                dpi As Single,
                                isRtl As Boolean,
                                floating As Boolean,
                                composition As MASComponentSurfaceMaterialComposition,
                                railCornerRadiusPx As Single,
                                chromeScale As Single)
            If toolbarRect.Width <= 1.0F OrElse toolbarRect.Height <= 1.0F Then
                _buttons = Array.Empty(Of MASMediaButtonModel)()
                Return
            End If

            If floating Then
                _buttons = BuildToolbarButtons(toolbarRect, SKRect.Empty, dpi, isRtl, True, chromeScale)
                If _buttons.Length = 0 Then Return

                DrawFloatingToolbarSurface(canvas, ctx, toolbarRect, dpi, composition)
                For i As Integer = 0 To _buttons.Length - 1
                    DrawToolbarButton(canvas, ctx, _buttons(i), dpi)
                Next
                Return
            End If

            ' Pinned chrome is root-level Media chrome: the outer PanelShell owns the
            ' title/action background, while the preview frame below groups only image
            ' stage and footer.  On constrained widths, the title is dropped before
            ' the toolbar itself is hidden so the command strip never renders partial actions.
            Dim titleRect As SKRect = MASMediaToolbarLayoutResolver.ResolveTitleRect(toolbarRect, dpi, isRtl, chromeScale)
            _buttons = BuildToolbarButtons(toolbarRect, titleRect, dpi, isRtl, False, chromeScale)
            If _buttons.Length = 0 AndAlso titleRect.Width > 1.0F Then
                titleRect = SKRect.Empty
                _buttons = BuildToolbarButtons(toolbarRect, titleRect, dpi, isRtl, False, chromeScale)
            End If
            If _buttons.Length = 0 Then Return

            DrawToolbarTitleBlock(canvas, ctx, titleRect, dpi, isRtl)
            For i As Integer = 0 To _buttons.Length - 1
                DrawToolbarButton(canvas, ctx, _buttons(i), dpi)
            Next
        End Sub

        Private Function BuildToolbarButtons(toolbarRect As SKRect,
                                             titleRect As SKRect,
                                             dpi As Single,
                                             isRtl As Boolean,
                                             floating As Boolean,
                                             chromeScale As Single) As MASMediaButtonModel()
            Dim commandLane As SKRect = MASMediaToolbarLayoutResolver.ResolveCommandLane(toolbarRect, titleRect, dpi, isRtl, floating, chromeScale)
            If commandLane.Width <= 1.0F OrElse commandLane.Height <= 1.0F Then Return Array.Empty(Of MASMediaButtonModel)()

            Return MASMediaButtonStripLayoutResolver.Build(
                specs:=ResolveToolbarButtonSpecs(),
                laneRect:=commandLane,
                hostRect:=toolbarRect,
                dpi:=dpi,
                isRtl:=isRtl,
                floating:=floating,
                nonCompactVerticalOffsetPx:=MediaToolbarTokens.PinnedActionVerticalOffsetDip * PixelSnap.SafeDpi(dpi) * chromeScale,
                chromeScale:=chromeScale)
        End Function

        Private Sub DrawToolbarTitleBlock(canvas As SKCanvas,
                                          ctx As MASThemeContext,
                                          titleRect As SKRect,
                                          dpi As Single,
                                          isRtl As Boolean)
            If canvas Is Nothing OrElse ctx Is Nothing Then Return
            If titleRect.Width <= 1.0F OrElse titleRect.Height <= 1.0F Then Return

            ' Phase 1 layout lock: the pinned header is a stable preview heading.
            ' Media/file identity stays in the footer so the header mirrors the
            ' target composition: Preview title + action tiles only.
            Dim align As TypographyTextPrimitives.TextAlign = If(isRtl, TypographyTextPrimitives.TextAlign.Right, TypographyTextPrimitives.TextAlign.Left)
            Dim primary As SKColor = ResolvePrimaryTextColor(ctx).WithAlpha(CByte(Math.Min(255, CInt(ImageViewerTokens.TextAlpha) + 10)))

            TypographyTextPrimitives.DrawSingleLineText(
                canvas:=canvas,
                ctx:=ctx,
                text:=ImageViewerTokens.HeaderTitle,
                bounds:=titleRect,
                dpi:=dpi,
                style:=MASTypography.MASTextStyle.Title,
                color:=primary,
                align:=align,
                drawShadow:=False)
        End Sub

        Private Shared Function ResolveToolbarButtonSpecs() As MASMediaButtonSpec()
            Dim actions As ImageViewerAction() = {
                ImageViewerAction.ZoomIn,
                ImageViewerAction.ZoomOut,
                ImageViewerAction.Fit,
                ImageViewerAction.RotateRight,
                ImageViewerAction.FlipHorizontal,
                ImageViewerAction.Export,
                ImageViewerAction.Reset
            }

            Dim specs(actions.Length - 1) As MASMediaButtonSpec
            For i As Integer = 0 To actions.Length - 1
                Dim action As ImageViewerAction = actions(i)
                specs(i) = New MASMediaButtonSpec(
                    actionId:=CInt(action),
                    text:=ResolveToolbarLabel(action),
                    groupIndex:=ResolveToolbarGroup(action),
                    glyphKind:=ResolveToolbarGlyphKind(action))
            Next
            Return specs
        End Function

        Private Shared Function ResolveToolbarGroup(action As ImageViewerAction) As Integer
            Select Case action
                Case ImageViewerAction.ZoomOut, ImageViewerAction.ZoomIn, ImageViewerAction.Fit, ImageViewerAction.Actual
                    Return 0
                Case ImageViewerAction.RotateLeft, ImageViewerAction.RotateRight, ImageViewerAction.FlipHorizontal, ImageViewerAction.FlipVertical
                    Return 1
                Case Else
                    Return 2
            End Select
        End Function

        Private Shared Function ResolveToolbarLabel(action As ImageViewerAction) As String
            Select Case action
                Case ImageViewerAction.ZoomOut
                    Return "Zoom out"
                Case ImageViewerAction.ZoomIn
                    Return "Zoom in"
                Case ImageViewerAction.Fit
                    Return "Fit"
                Case ImageViewerAction.RotateRight
                    Return "Rotate"
                Case ImageViewerAction.FlipHorizontal
                    Return "Flip"
                Case ImageViewerAction.Export
                    Return "Export"
                Case ImageViewerAction.Reset
                    Return "Reset"
                Case Else
                    Return String.Empty
            End Select
        End Function

        Private Shared Function ResolveToolbarGlyphKind(action As ImageViewerAction) As MASMediaButtonGlyphKind
            Select Case action
                Case ImageViewerAction.ZoomOut
                    Return MASMediaButtonGlyphKind.ZoomOut
                Case ImageViewerAction.ZoomIn
                    Return MASMediaButtonGlyphKind.ZoomIn
                Case ImageViewerAction.Fit
                    Return MASMediaButtonGlyphKind.Fit
                Case ImageViewerAction.Actual
                    Return MASMediaButtonGlyphKind.Actual
                Case ImageViewerAction.RotateLeft
                    Return MASMediaButtonGlyphKind.RotateLeft
                Case ImageViewerAction.RotateRight
                    Return MASMediaButtonGlyphKind.RotateRight
                Case ImageViewerAction.FlipHorizontal
                    Return MASMediaButtonGlyphKind.FlipHorizontal
                Case ImageViewerAction.FlipVertical
                    Return MASMediaButtonGlyphKind.FlipVertical
                Case ImageViewerAction.Reset
                    Return MASMediaButtonGlyphKind.Reset
                Case ImageViewerAction.Export
                    Return MASMediaButtonGlyphKind.Export
                Case Else
                    Return MASMediaButtonGlyphKind.None
            End Select
        End Function

        Private Function IsViewMutated() As Boolean
            Return _rotationDegrees <> 0 OrElse _flippedHorizontal OrElse _flippedVertical OrElse
                   Math.Abs(_panX) > 0.5F OrElse Math.Abs(_panY) > 0.5F OrElse Not _fitMode
        End Function

        Private Function IsToolbarActionEnabled(action As ImageViewerAction) As Boolean
            If Not HasImage Then Return False
            Select Case action
                Case ImageViewerAction.ZoomOut
                    Return _zoom > ResolveFitZoom() + 0.0001F
                Case ImageViewerAction.ZoomIn
                    Return _zoom < ImageViewerTokens.MaxZoom - 0.0001F
                Case ImageViewerAction.Reset
                    Return IsViewMutated()
                Case Else
                    Return True
            End Select
        End Function

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

            Dim radius As Single = PixelSnap.SafeRadius(MediaToolbarTokens.FloatingChromeRadiusDip * PixelSnap.SafeDpi(dpi))
            Dim surfaceStrength As Integer = MASImageViewerSurfacePolicy.ResolveSurfaceStrengthLevel(MASComponentSurfaceRegion.Overlay, 4)
            Dim borderStrength As Integer = MASImageViewerSurfacePolicy.ResolveBorderStrengthLevel(MASComponentSurfaceRegion.Overlay, 3)
            Dim frameStrength As MASSurfaceFrameStrength = MASImageViewerSurfacePolicy.ResolveFrameStrength(MASComponentSurfaceRegion.Overlay, MASSurfaceFrameStrength.Level4)

            MASSurfaceMaterialComponentGateway.TryDrawComposedCardSurface(
                canvas:=canvas,
                ctx:=ctx,
                boundsPx:=toolbarRect,
                composition:=composition,
                region:=MASComponentSurfaceRegion.Overlay,
                fallbackMaterialKey:=MASImageViewerSurfacePolicy.ResolveFallbackMaterialKey(MASComponentSurfaceRegion.Overlay),
                dpi:=dpi,
                cornerRadiusPx:=radius,
                opacity:=1.0F,
                surfaceStrengthLevel:=surfaceStrength,
                borderStrengthLevel:=borderStrength,
                frameStrength:=frameStrength,
                fallbackRole:=MASSurfaceRole.ApplicationChrome)
        End Sub

        Private Sub DrawToolbarButton(canvas As SKCanvas,
                                      ctx As MASThemeContext,
                                      button As MASMediaButtonModel,
                                      dpi As Single)
            If canvas Is Nothing OrElse ctx Is Nothing Then Return
            If button.Rect.Width <= 1.0F OrElse button.Rect.Height <= 1.0F Then Return

            Dim action As ImageViewerAction = CType(button.ActionId, ImageViewerAction)
            Dim enabledButton As Boolean = IsToolbarActionEnabled(action)
            Dim mediaStyle As MASMediaVisualStyle = ResolveMediaStyle(ctx, dpi)
            Dim state As New MASMediaButtonState(enabledButton,
                                                enabledButton AndAlso _hoverAction = action,
                                                enabledButton AndAlso _pressedAction = action,
                                                enabledButton AndAlso action = ImageViewerAction.Fit AndAlso _fitMode)

            MASMediaButtonRenderer.Draw(canvas, ctx, mediaStyle, button, state, dpi)
        End Sub

#End Region

    End Class

End Namespace
