import { existsSync, readFileSync } from "node:fs"
import path from "node:path"
import { recolorSvg, stripSvgWrapper, extractRootAttrs } from "./recolor.ts"
import { computeFit, parseViewBox } from "./fit.ts"
import type { SlotSpec } from "./slot-parser.ts"
import type { Brand } from "./config.ts"
import { resolveColor } from "./config.ts"
export type ResolveResult = {
inner: string
contentW: number
contentH: number
rootAttrs: { stroke?: string; fill?: string; strokeWidth?: string }
}
export function resolveSlotContent(
slot: SlotSpec,
brand: Brand,
drawImageDir: string,
slotValue: string,
): ResolveResult | null {
const raw = loadSlotSvg(slotValue, drawImageDir)
if (!raw) return null
const color = resolveColor(brand, slot.recolor)
const recolored = recolorSvg(raw, color)
const rootAttrs = extractRootAttrs(recolored)
const inner = stripSvgWrapper(recolored)
const { width, height } = parseViewBox(raw)
return { inner, contentW: width, contentH: height, rootAttrs }
}
export function loadSlotSvg(value: string, drawImageDir: string): string | null {
if (value.startsWith("./") || value.startsWith("/") || value.startsWith("../")) {
if (!existsSync(value)) return null
return readFileSync(value, "utf-8")
}
const lucidePath = path.join(drawImageDir, "icons", "lucide", `${value}.svg`)
if (existsSync(lucidePath)) {
return readFileSync(lucidePath, "utf-8")
}
const brandPath = path.join(drawImageDir, "brand-logos", `${value}.svg`)
if (existsSync(brandPath)) {
return readFileSync(brandPath, "utf-8")
}
return null
}
export function renderSlotSvg(slot: SlotSpec, resolved: ResolveResult): string {
const fit = computeFit(
slot.fit,
slot.x,
slot.y,
slot.w,
slot.h,
resolved.contentW,
resolved.contentH,
)
const attrs = resolved.rootAttrs
const strokeAttr = attrs.stroke ? ` stroke="${attrs.stroke}"` : ""
const fillAttr = attrs.fill ? ` fill="${attrs.fill}"` : ""
const swAttr = attrs.strokeWidth ? ` stroke-width="${attrs.strokeWidth}"` : ""
return ``
}
export function renderSlotBackground(slot: SlotSpec, brand: Brand): string {
const parts: string[] = []
if (slot.bg !== "none") {
const bg = resolveColor(brand, slot.bg)
const r = slot.radius ? Math.min(slot.w, slot.h) * slot.radius / 2 : 0
parts.push(``)
}
if (slot.border !== "none") {
const border = resolveColor(brand, slot.border)
const r = slot.radius ? Math.min(slot.w, slot.h) * slot.radius / 2 : 0
parts.push(``)
}
return parts.join("\n")
}