import type { CADLayer } from '../types/cad.types'; export class LayerManager { private layers: Map = new Map(); private activeLayerId: string = ''; addLayer(layer: CADLayer): void { this.layers.set(layer.id, layer); if (!this.activeLayerId) this.activeLayerId = layer.id; } removeLayer(id: string): void { this.layers.delete(id); if (this.activeLayerId === id) { const first = this.layers.keys().next(); this.activeLayerId = first.done ? '' : first.value; } } getLayer(id: string): CADLayer | undefined { return this.layers.get(id); } getLayers(): CADLayer[] { return Array.from(this.layers.values()).sort((a, b) => a.sortOrder - b.sortOrder); } getVisibleLayers(): CADLayer[] { return this.getLayers().filter(l => l.visible && !l.locked); } setActiveLayer(id: string): void { if (this.layers.has(id)) this.activeLayerId = id; } getActiveLayer(): CADLayer | undefined { return this.layers.get(this.activeLayerId); } getActiveLayerId(): string { return this.activeLayerId; } toggleVisibility(id: string): void { const layer = this.layers.get(id); if (layer) layer.visible = !layer.visible; } toggleLock(id: string): void { const layer = this.layers.get(id); if (layer) layer.locked = !layer.locked; } clear(): void { this.layers.clear(); this.activeLayerId = ''; } /** * Rename a layer. */ renameLayer(id: string, name: string): void { const layer = this.layers.get(id); if (layer) layer.name = name; } /** * Update layer properties. */ updateLayer(id: string, props: Partial): void { const layer = this.layers.get(id); if (layer) { Object.assign(layer, props); } } /** * Set parent for a layer (tree structure). */ setParent(id: string, parentId: string | null): void { const layer = this.layers.get(id); if (!layer) return; // Prevent circular references if (parentId) { let current: string | null = parentId; while (current) { if (current === id) return; // Would create a cycle const parent = this.layers.get(current); if (!parent) break; current = parent.parentId; } } layer.parentId = parentId; } /** * Get child layers of a parent. */ getChildLayers(parentId: string | null): CADLayer[] { return this.getLayers().filter(l => l.parentId === parentId); } /** * Get layer tree structure. */ getLayerTree(): Array { const buildTree = (parentId: string | null): Array => { return this.getChildLayers(parentId).map(layer => ({ ...layer, children: buildTree(layer.id), })); }; return buildTree(null); } /** * Move layer to a new position in the sort order. */ moveLayer(id: string, newSortOrder: number): void { const layer = this.layers.get(id); if (!layer) return; layer.sortOrder = newSortOrder; } /** * Duplicate a layer with all its properties. */ duplicateLayer(id: string): CADLayer | null { const layer = this.layers.get(id); if (!layer) return null; const newId = `layer_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`; const copy: CADLayer = { ...layer, id: newId, name: `${layer.name} (Kopie)`, sortOrder: layer.sortOrder + 1, parentId: layer.parentId, }; this.layers.set(newId, copy); return copy; } /** * Filter layers by criteria. */ filterLayers(criteria: { visible?: boolean; locked?: boolean; color?: string; lineType?: string; nameContains?: string; }): CADLayer[] { return this.getLayers().filter(l => { if (criteria.visible !== undefined && l.visible !== criteria.visible) return false; if (criteria.locked !== undefined && l.locked !== criteria.locked) return false; if (criteria.color && l.color !== criteria.color) return false; if (criteria.lineType && l.lineType !== criteria.lineType) return false; if (criteria.nameContains && !l.name.toLowerCase().includes(criteria.nameContains.toLowerCase())) return false; return true; }); } /** * Get all descendant layer IDs (children, grandchildren, etc.). */ getDescendantIds(id: string): string[] { const result: string[] = []; const collect = (parentId: string) => { for (const layer of this.layers.values()) { if (layer.parentId === parentId) { result.push(layer.id); collect(layer.id); } } }; collect(id); return result; } /** * Check if a layer is locked. */ isLocked(id: string): boolean { const layer = this.layers.get(id); return layer ? layer.locked : false; } /** * Get layer color. */ getLayerColor(id: string): string | undefined { const layer = this.layers.get(id); return layer?.color; } }