-- VDS_LayoutConfig_Canvas
-- ============================================================================
-- Canvas-view widgets only (picker panel + preview panel). Default-view
-- panels reuse via panel.cell.canvas in VDS_LayoutConfig.lua.
-- ADR-001 multi-field binding on canvasPreview.modelScene; resolver wiring
-- lands when canvas becomes interactive.

VDS = VDS or {}
local LC = VDS.LayoutConfig

-- ===== CANVAS PICKER (canvasPickerPanel, col 1) =====

LC.sections["canvasPicker.body"] = {
    ["in"]  = "canvasPickerPanel",
    order   = 10,
    layout  = "vertical",
    padding = { left = 6, top = 4, right = 6, bottom = 6 },
    gap     = 4,
}

LC.widgets["canvasPicker.title"] = {
    kind    = "label",
    ["in"]  = "canvasPicker.body",
    order   = 10,
    text    = "Dyeable Decor",
    font    = "subheading",
    height  = 20,
    tooltip = false,
}

LC.widgets["canvasPicker.search"] = {
    kind    = "searchBox",
    ["in"]  = "canvasPicker.body",
    order   = 20,
    binding = "canvas.pickerSearch",   -- canvas-scoped; separate from center list's ui.searchText
    height  = 22,
    tooltip = { recipe = "SearchDecor" },
}

-- Category filter dropdown. Sits between search and tree. Selection
-- narrows the tree to one Housing catalog category; nil = "All".
LC.widgets["canvasPicker.categoryDropdown"] = {
    kind    = "categoryDropdown",
    ["in"]  = "canvasPicker.body",
    order   = 25,
    binding = "canvas.category.label",  -- triggers GenerateMenu on change
    width   = 240,
    height  = 25,
    tooltip = { recipe = "CategoryFilter" },
}

-- Flat decor scrollbox (replaces the previous scrollBoxTreeList). Loadouts
-- moved out of the picker -- they live in the col 3 chip wall now.
LC.widgets["canvasPicker.list"] = {
    kind     = "scrollBoxList",
    ["in"]   = "canvasPicker.body",
    order    = 30,
    binding  = "canvas.decor.rows",
    height   = "fill",
    extent   = 24,
    rowKinds = { decor = "decorListRow" },
    tooltip = false,
}

-- Empty hint: scrollbox is silent on empty; this gives the user-facing cue.
LC.widgets["canvasPicker.emptyHint"] = {
    kind     = "label",
    ["in"]   = "canvasPicker.body",
    order    = 40,
    binding  = "canvas.picker.emptyHint",
    visible  = "canvas.picker.isEmpty",
    font     = "body",
    height   = 60,
    justifyH = "CENTER",
    tooltip = false,
}

-- ===== CANVAS PREVIEW (canvasPreviewPanel, col 3) =====

LC.sections["canvasPreview.body"] = {
    ["in"]  = "canvasPreviewPanel",
    order   = 10,
    layout  = "vertical",
    padding = { left = 6, top = 4, right = 6, bottom = 6 },
    gap     = 4,
}

LC.widgets["canvasPreview.title"] = {
    kind    = "label",
    ["in"]  = "canvasPreview.body",
    order   = 10,
    binding = "canvas.preview.title",
    font    = "subheading",
    height  = 20,
    tooltip = false,
}

LC.widgets["canvasPreview.modelScene"] = {
    kind    = "modelPreview",
    ["in"]  = "canvasPreview.body",
    order   = 20,
    binding = {
        decorID = "canvas.selected.decorID",
        dyes    = "canvas.selected.dyes",
    },
    height  = "fill",
    tooltip = false,
}

LC.sections["canvasPreview.channels"] = {
    ["in"]  = "canvasPreview.body",
    order   = 30,
    layout  = "vertical",
    gap     = 2,
    height  = 70,
}

LC.widgets["canvasPreview.ch1"] = {
    kind    = "channelRow",
    ["in"]  = "canvasPreview.channels",
    order   = 10,
    binding = "canvas.channel.1",
    height  = 22,
    tooltip = false,
}

LC.widgets["canvasPreview.ch2"] = {
    kind    = "channelRow",
    ["in"]  = "canvasPreview.channels",
    order   = 20,
    binding = "canvas.channel.2",
    height  = 22,
    tooltip = false,
}

LC.widgets["canvasPreview.ch3"] = {
    kind    = "channelRow",
    ["in"]  = "canvasPreview.channels",
    order   = 30,
    binding = "canvas.channel.3",
    height  = 22,
    tooltip = false,
}

-- Loadouts chip wall section (between channels and actions). Divider + header
-- + single row grid (11 cells = 10 loadouts + 1 save tile).
-- Height = 6 divider + 4 gap + 14 header + 4 gap + 28 grid = 56.
LC.sections["canvasPreview.loadouts"] = {
    ["in"]  = "canvasPreview.body",
    order   = 35,
    layout  = "vertical",
    gap     = 4,
    height  = 56,
}

-- Thin horizontal divider to separate the loadouts band from the channel
-- pickers above. 1px hairline rendered via the divider widget kind.
LC.widgets["canvasPreview.loadoutsDivider"] = {
    kind    = "divider",
    ["in"]  = "canvasPreview.loadouts",
    order   = 5,
    height  = 6,
    tooltip = false,
}

LC.widgets["canvasPreview.loadoutsHeader"] = {
    kind    = "label",
    ["in"]  = "canvasPreview.loadouts",
    order   = 10,
    binding = "canvas.loadouts.headerText",  -- "Loadouts (N/10)"
    font    = "small",
    height  = 14,
    tooltip = false,
}

LC.widgets["canvasPreview.loadoutsWall"] = {
    kind    = "loadoutChipWall",
    ["in"]  = "canvasPreview.loadouts",
    order   = 20,
    binding = {
        loadouts   = "canvas.loadouts.forSelected",
        hasUnsaved = "canvas.hasUnsavedCombo",  -- drives "+" tile pulse
    },
    -- Explicit numeric dimensions trigger the layout engine's cross-axis
    -- centering (default for vertical containers). Without these the spec
    -- defaults to "fill" and the wall left-aligns.
    width   = 348,   -- 11 cols * 28 + 10 gaps * 4
    height  = 28,    -- 1 row
    tooltip = false,
}

LC.sections["canvasPreview.actions"] = {
    ["in"]  = "canvasPreview.body",
    order   = 40,
    layout  = "horizontal",
    gap     = 8,
    height  = 22,
}

LC.widgets["canvasPreview.randomBtn"] = {
    kind     = "button",
    ["in"]   = "canvasPreview.actions",
    order    = 10,
    font     = "body",
    binding  = "canvas.random.buttonText",  -- "Random" or "Random: <scope name>"
    width    = "auto",                       -- grow to fit "Random: <name>"
    height   = 22,
    justifyH = "LEFT",
    tooltip = { recipe = "CanvasRandom" },
}

LC.widgets["canvasPreview.harmoniseBtn"] = {
    kind     = "button",
    ["in"]   = "canvasPreview.actions",
    order    = 15,
    font     = "body",
    text     = "Harmonise",
    width    = "auto",
    height   = 22,
    tooltip  = { recipe = "CanvasHarmonise" },
}

LC.widgets["canvasPreview.actionSpacer"] = {
    kind   = "spacer",
    ["in"] = "canvasPreview.actions",
    order  = 20,
    width  = "fill",
    tooltip = false,
}

LC.widgets["canvasPreview.clearBtn"] = {
    kind    = "button",
    ["in"]  = "canvasPreview.actions",
    order   = 30,
    font    = "body",
    text    = "Clear",
    width   = 80,
    height  = 22,
    tooltip = { recipe = "CanvasClear" },
}

-- Save button retired in Phase 5; the "+" tile in the loadout chip wall is
-- the save affordance now. Action row keeps Random + Clear only.

-- ===== CANVAS SCOPE (canvasScopePanel, row between subfilter and body) =====

LC.sections["canvasScope.body"] = {
    ["in"]  = "canvasScopePanel",
    order   = 10,
    layout  = "horizontal",
    padding = { left = 6, top = 2, right = 6, bottom = 2 },
    gap     = 6,
}

LC.widgets["canvasScope.label"] = {
    kind     = "label",
    ["in"]   = "canvasScope.body",
    order    = 10,
    text     = "Scope:",
    font     = "body",
    height   = 22,
    justifyV = "MIDDLE",
    tooltip = false,
}

LC.widgets["canvasScope.dropdown"] = {
    kind    = "scopeDropdown",
    ["in"]  = "canvasScope.body",
    order   = 20,
    binding = "canvas.scope.label",     -- triggers GenerateMenu on change (text auto-renders via SelectionTextMixin)
    width   = 160,                       -- min-width floor; resizeToText auto-grows past it
    height  = 25,                        -- WowStyle2DropdownTemplate native height
    tooltip = { recipe = "ScopeFilter" },
}

LC.widgets["canvasScope.resetBtn"] = {
    kind    = "button",
    ["in"]  = "canvasScope.body",
    order   = 30,
    text    = "Reset",
    font    = "body",
    visible = "canvas.scope.hasScope",
    width   = 60,
    height  = 22,
    tooltip = { recipe = "ScopeReset" },
}

LC.widgets["canvasScope.spacer"] = {
    kind   = "spacer",
    ["in"] = "canvasScope.body",
    order  = 40,
    width  = "fill",
    tooltip = false,
}
