Option Strict On
Option Explicit On

Imports System.Collections.Generic

Namespace Nexamas.UI.ThemeStudio

    ''' <summary>
    ''' Immutable product snapshot consumed by Theme Studio, Surface Designer, gates, and future Showcase pages.
    ''' </summary>
    ''' <remarks>
    ''' The snapshot is the official Phase 5 read model. It is intentionally descriptive:
    ''' it never draws, edits, exports, registers themes, writes files, or exposes internal
    ''' theme/rendering owners. UI surfaces can bind to it safely.
    ''' </remarks>
    Friend NotInheritable Class MASThemeStudioSnapshot

        Friend Sub New(contractVersion As Integer,
                       currentThemeId As String,
                       themes As IEnumerable(Of MASThemeStudioThemeEntry),
                       materials As IEnumerable(Of MASSurfaceDesignerMaterialEntry),
                       materialProfiles As IEnumerable(Of MASSurfaceDesignerMaterialProfileEntry),
                       slots As IEnumerable(Of MASSurfaceDesignerSlotEntry),
                       roles As IEnumerable(Of MASSurfaceDesignerRoleEntry),
                       visualStyles As IEnumerable(Of MASSurfaceDesignerVisualStyleEntry),
                       contrastChecks As IEnumerable(Of MASThemeStudioContrastCheck))
            Me.ContractVersion = contractVersion
            Me.CurrentThemeId = Normalize(currentThemeId)
            Me.Themes = CopyThemes(themes)
            Me.Materials = CopyMaterials(materials)
            Me.MaterialProfiles = CopyMaterialProfiles(materialProfiles)
            Me.Slots = CopySlots(slots)
            Me.Roles = CopyRoles(roles)
            Me.VisualStyles = CopyVisualStyles(visualStyles)
            Me.ContrastChecks = CopyContrastChecks(contrastChecks)
        End Sub

        Friend ReadOnly Property ContractVersion As Integer
        Friend ReadOnly Property CurrentThemeId As String
        Friend ReadOnly Property Themes As IReadOnlyList(Of MASThemeStudioThemeEntry)
        Friend ReadOnly Property Materials As IReadOnlyList(Of MASSurfaceDesignerMaterialEntry)
        Friend ReadOnly Property MaterialProfiles As IReadOnlyList(Of MASSurfaceDesignerMaterialProfileEntry)
        Friend ReadOnly Property Slots As IReadOnlyList(Of MASSurfaceDesignerSlotEntry)
        Friend ReadOnly Property Roles As IReadOnlyList(Of MASSurfaceDesignerRoleEntry)
        Friend ReadOnly Property VisualStyles As IReadOnlyList(Of MASSurfaceDesignerVisualStyleEntry)
        Friend ReadOnly Property ContrastChecks As IReadOnlyList(Of MASThemeStudioContrastCheck)

        Friend ReadOnly Property ThemeCount As Integer
            Get
                Return Themes.Count
            End Get
        End Property

        Friend ReadOnly Property MaterialCount As Integer
            Get
                Return Materials.Count
            End Get
        End Property

        Friend ReadOnly Property MaterialProfileCount As Integer
            Get
                Return MaterialProfiles.Count
            End Get
        End Property

        Friend ReadOnly Property SlotCount As Integer
            Get
                Return Slots.Count
            End Get
        End Property

        Friend ReadOnly Property RoleCount As Integer
            Get
                Return Roles.Count
            End Get
        End Property

        Friend ReadOnly Property VisualStyleCount As Integer
            Get
                Return VisualStyles.Count
            End Get
        End Property

        Friend ReadOnly Property ContrastCheckCount As Integer
            Get
                Return ContrastChecks.Count
            End Get
        End Property

        Friend ReadOnly Property ReadyForDesignerPreview As Boolean
            Get
                Return ContractVersion = MASThemeStudioContractVersion.Current AndAlso
                       CurrentThemeId.Length > 0 AndAlso
                       ThemeCount >= 3 AndAlso
                       MaterialCount >= 8 AndAlso
                       MaterialProfileCount >= 5 AndAlso
                       SlotCount >= 10 AndAlso
                       RoleCount >= 8 AndAlso
                       VisualStyleCount >= 1 AndAlso
                       ContrastCheckCount >= ThemeCount * 3 AndAlso
                       Global.System.Linq.Enumerable.Count(Themes, Function(theme) theme IsNot Nothing AndAlso theme.IsCurrent AndAlso theme.Id = CurrentThemeId) = 1 AndAlso
                       Global.System.Linq.Enumerable.All(Themes, Function(theme) theme IsNot Nothing AndAlso theme.Id.Length > 0 AndAlso theme.DisplayName.Length > 0 AndAlso theme.FoundationGroupCount > 0 AndAlso theme.FamilyGroupCount > 0) AndAlso
                       Global.System.Linq.Enumerable.All(Materials, Function(material) material IsNot Nothing AndAlso material.Id.Length > 0 AndAlso material.DisplayName.Length > 0) AndAlso
                       Global.System.Linq.Enumerable.All(MaterialProfiles, Function(profile) profile IsNot Nothing AndAlso profile.Id.Length > 0 AndAlso profile.DisplayName.Length > 0 AndAlso profile.AssignmentCount > 0 AndAlso Global.System.Linq.Enumerable.All(profile.Assignments, Function(assignment) assignment IsNot Nothing AndAlso assignment.SlotName.Length > 0 AndAlso assignment.MaterialId.Length > 0 AndAlso assignment.MaterialDisplayName.Length > 0)) AndAlso
                       Global.System.Linq.Enumerable.All(Slots, Function(slot) slot IsNot Nothing AndAlso slot.Name.Length > 0 AndAlso slot.RoleName.Length > 0 AndAlso slot.ParticipatesInDesignerPreview) AndAlso
                       Global.System.Linq.Enumerable.All(Roles, Function(role) role IsNot Nothing AndAlso role.Name.Length > 0 AndAlso role.ParticipatesInDesignerPreview) AndAlso
                       Global.System.Linq.Enumerable.All(VisualStyles, Function(style) style IsNot Nothing AndAlso style.Id.Length > 0 AndAlso style.MaterialKey.Length > 0 AndAlso style.FrameKey.Length > 0 AndAlso style.ChromeKey.Length > 0 AndAlso style.RoleName.Length > 0) AndAlso
                       Global.System.Linq.Enumerable.All(ContrastChecks, Function(check) check IsNot Nothing AndAlso check.ThemeId.Length > 0 AndAlso check.Name.Length > 0 AndAlso check.ForegroundHex.Length > 0 AndAlso check.BackgroundHex.Length > 0)
            End Get
        End Property

        Private Shared Function Normalize(value As String) As String
            Return If(value, String.Empty).Trim()
        End Function

        Private Shared Function CopyThemes(items As IEnumerable(Of MASThemeStudioThemeEntry)) As IReadOnlyList(Of MASThemeStudioThemeEntry)
            Dim list As New List(Of MASThemeStudioThemeEntry)()
            If items IsNot Nothing Then list.AddRange(items)
            Return list.AsReadOnly()
        End Function

        Private Shared Function CopyMaterials(items As IEnumerable(Of MASSurfaceDesignerMaterialEntry)) As IReadOnlyList(Of MASSurfaceDesignerMaterialEntry)
            Dim list As New List(Of MASSurfaceDesignerMaterialEntry)()
            If items IsNot Nothing Then list.AddRange(items)
            Return list.AsReadOnly()
        End Function

        Private Shared Function CopyMaterialProfiles(items As IEnumerable(Of MASSurfaceDesignerMaterialProfileEntry)) As IReadOnlyList(Of MASSurfaceDesignerMaterialProfileEntry)
            Dim list As New List(Of MASSurfaceDesignerMaterialProfileEntry)()
            If items IsNot Nothing Then list.AddRange(items)
            Return list.AsReadOnly()
        End Function

        Private Shared Function CopySlots(items As IEnumerable(Of MASSurfaceDesignerSlotEntry)) As IReadOnlyList(Of MASSurfaceDesignerSlotEntry)
            Dim list As New List(Of MASSurfaceDesignerSlotEntry)()
            If items IsNot Nothing Then list.AddRange(items)
            Return list.AsReadOnly()
        End Function

        Private Shared Function CopyRoles(items As IEnumerable(Of MASSurfaceDesignerRoleEntry)) As IReadOnlyList(Of MASSurfaceDesignerRoleEntry)
            Dim list As New List(Of MASSurfaceDesignerRoleEntry)()
            If items IsNot Nothing Then list.AddRange(items)
            Return list.AsReadOnly()
        End Function

        Private Shared Function CopyVisualStyles(items As IEnumerable(Of MASSurfaceDesignerVisualStyleEntry)) As IReadOnlyList(Of MASSurfaceDesignerVisualStyleEntry)
            Dim list As New List(Of MASSurfaceDesignerVisualStyleEntry)()
            If items IsNot Nothing Then list.AddRange(items)
            Return list.AsReadOnly()
        End Function

        Private Shared Function CopyContrastChecks(items As IEnumerable(Of MASThemeStudioContrastCheck)) As IReadOnlyList(Of MASThemeStudioContrastCheck)
            Dim list As New List(Of MASThemeStudioContrastCheck)()
            If items IsNot Nothing Then list.AddRange(items)
            Return list.AsReadOnly()
        End Function

    End Class

End Namespace
