import { Object3D, Vector3 } from 'three'; import { create } from 'zustand'; import { immer } from 'zustand/middleware/immer'; interface BuilderState { // Point & Line Interaction hoveredPoint: Point | null; snappedPoint: Point | null; snappedPosition: [number, number, number] | null; hoveredLine: [Point, Point] | null; // Wall Asset selectedWallAsset: Object3D | null; deletableWallAsset: Object3D | null; // Floor Asset selectedFloorAsset: Object3D | null; loopAnimation: boolean; // Wall Settings selectedWall: Object3D | null; wallThickness: number; wallHeight: number; outsideMaterial: string; insideMaterial: string; // Floor Settings selectedFloor: Object3D | null; floorDepth: number; isBeveled: boolean; bevelStrength: number; sideMaterial: string; topMaterial: string; // Zone Settings selectedZone: Object3D | null; zoneHeight: number; zoneColor: string; // Decal Settings selectedDecal: { decalMesh: Object3D | null, decalData: Decal } | null; deletableDecal: Object3D | null; decalDragState: { isDragging: boolean, draggingDecalUuid: string | null, dragOffset: Vector3 | null, }, // Aisle General selectedAisle: Object3D | null; aisleType: AisleTypes; aisleWidth: number; aisleColor: AisleColors; // Aisle Specific Styles dashLength: number; gapLength: number; dotRadius: number; aisleLength: number; isFlipped: boolean; // Setters - Point/Line setHoveredPoint: (point: Point | null) => void; setSnappedPoint: (point: Point | null) => void; setSnappedPosition: (position: [number, number, number] | null) => void; setHoveredLine: (line: [Point, Point] | null) => void; // Setters - Wall Asset setSelectedWallAsset: (asset: Object3D | null) => void; setDeletableWallAsset: (asset: Object3D | null) => void; // Setters - Floor Asset setSelectedFloorAsset: (asset: Object3D | null) => void; setLoopAnimation: (loop: boolean) => void; // Setters - Wall setSelectedWall: (wall: Object3D | null) => void; setWallThickness: (thickness: number) => void; setWallHeight: (height: number) => void; setWallMaterial: (material: string, side: 'inside' | 'outside') => void; // Setters - Floor setSelectedFloor: (floor: Object3D | null) => void; setFloorDepth: (depth: number) => void; setIsBeveled: (isBeveled: boolean) => void; setBevelStrength: (strength: number) => void; setFloorMaterial: (material: string, side: 'side' | 'top') => void; // Setters - Zone setSelectedZone: (zone: Object3D | null) => void; setZoneHeight: (height: number) => void; setZoneColor: (color: string) => void; // Setters - Decal setSelectedDecal: (decal: { decalMesh: Object3D | null, decalData: Decal } | null) => void; setDeletableDecal: (decal: Object3D | null) => void; setDecalDragState: (isDragging: boolean, draggingDecalUuid: string | null, dragOffset: Vector3 | null) => void; // Setters - Aisle General setSelectedAisle: (aisle: Object3D | null) => void; setAisleType: (type: AisleTypes) => void; setAisleWidth: (width: number) => void; setAisleColor: (color: AisleColors) => void; // Setters - Aisle Specific setDashLength: (length: number) => void; setGapLength: (length: number) => void; setDotRadius: (radius: number) => void; setAisleLength: (length: number) => void; setIsFlipped: (isFlipped: boolean) => void; // Batch Setters setDashedAisleProperties: (width: number, dashLength: number, gapLength: number) => void; setDottedAisleProperties: (width: number, dotRadius: number, gapLength: number) => void; setArrowsAisleProperties: (width: number, aisleLength: number, gapLength: number) => void; setAisleProperties: (type: AisleTypes, width: number, color: AisleColors) => void; } export const useBuilderStore = create()( immer((set) => ({ // === Defaults === hoveredPoint: null, snappedPoint: null, snappedPosition: null, hoveredLine: null, selectedWallAsset: null, deletableWallAsset: null, selectedFloorAsset: null, loopAnimation: true, selectedWall: null, wallThickness: 0.5, wallHeight: 7, outsideMaterial: 'Default Material', insideMaterial: 'Material 1', selectedFloor: null, floorDepth: 0.1, isBeveled: false, bevelStrength: 5, sideMaterial: 'Material 1', topMaterial: 'Default Material', selectedZone: null, zoneHeight: 7, zoneColor: 'blue', selectedDecal: null, deletableDecal: null, decalDragState: { isDragging: false, draggingDecalUuid: null, dragOffset: null, }, selectedAisle: null, aisleType: 'solid-aisle', aisleWidth: 0.1, aisleColor: 'yellow', dashLength: 0.5, gapLength: 0.3, dotRadius: 0.1, aisleLength: 0.6, isFlipped: false, // === Setters: Point/Line === setHoveredPoint: (point: Point | null) => { set((state) => { state.hoveredPoint = point; }); }, setSnappedPoint: (point: Point | null) => { set((state) => { state.snappedPoint = point; }); }, setSnappedPosition: (position: [number, number, number] | null) => { set((state) => { state.snappedPosition = position; }); }, setHoveredLine: (line: [Point, Point] | null) => { set((state) => { state.hoveredLine = line; }) }, // === Setters: Wall Asset === setSelectedWallAsset(asset: Object3D | null) { set((state) => { state.selectedWallAsset = asset; }); }, setDeletableWallAsset(asset: Object3D | null) { set((state) => { state.deletableWallAsset = asset; }); }, // === Setters: Floor Asset === setSelectedFloorAsset(asset: Object3D | null) { set((state) => { state.selectedFloorAsset = asset; }); }, setLoopAnimation(loopAnimation: boolean) { set((state) => { state.loopAnimation = loopAnimation; }); }, // === Setters: Wall === setSelectedWall: (wall: Object3D | null) => { set((state) => { state.selectedWall = wall; }) }, setWallThickness: (thickness: number) => { set((state) => { state.wallThickness = thickness; }) }, setWallHeight: (height: number) => { set((state) => { state.wallHeight = height; }) }, setWallMaterial: (material: string, side: 'inside' | 'outside') => { set((state) => { if (side === 'outside') state.outsideMaterial = material; else state.insideMaterial = material; }); }, // === Setters: Floor === setSelectedFloor: (floor: Object3D | null) => { set((state) => { state.selectedFloor = floor; }); }, setFloorDepth: (depth: number) => { set((state) => { state.floorDepth = depth; }); }, setIsBeveled: (isBeveled: boolean) => { set((state) => { state.isBeveled = isBeveled; }); }, setBevelStrength: (strength: number) => { set((state) => { state.bevelStrength = strength; }); }, setFloorMaterial: (material: string, side: 'side' | 'top') => { set((state) => { if (side === 'side') state.sideMaterial = material; else state.topMaterial = material; }); }, // === Setters: Zone === setSelectedZone: (zone: Object3D | null) => { set((state) => { state.selectedZone = zone; }); }, setZoneHeight: (height: number) => { set((state) => { state.zoneHeight = height; }); }, setZoneColor: (color: string) => { set((state) => { state.zoneColor = color; }); }, // === Setters: Decal === setSelectedDecal: (decal: { decalMesh: Object3D | null, decalData: Decal } | null) => { set((state) => { state.selectedDecal = decal; }) }, setDeletableDecal: (decal: Object3D | null) => { set((state) => { state.deletableDecal = decal; }) }, setDecalDragState: (isDragging: boolean, draggingDecalUuid: string | null, dragOffset: Vector3 | null) => { set((state) => { state.decalDragState = { isDragging, draggingDecalUuid, dragOffset, } }) }, // === Setters: Aisle General === setSelectedAisle: (aisle: Object3D | null) => { set((state) => { state.selectedAisle = aisle; }); }, setAisleType: (type) => { set((state) => { state.aisleType = type; }); }, setAisleWidth: (width) => { set((state) => { state.aisleWidth = width; }); }, setAisleColor: (color) => { set((state) => { state.aisleColor = color; }); }, // === Setters: Aisle Specific === setDashLength: (length) => { set((state) => { state.dashLength = length; }); }, setGapLength: (length) => { set((state) => { state.gapLength = length; }); }, setDotRadius: (radius) => { set((state) => { state.dotRadius = radius; }); }, setAisleLength: (length) => { set((state) => { state.aisleLength = length; }); }, setIsFlipped: (isFlipped) => { set((state) => { state.isFlipped = isFlipped; }); }, // === Batch Setters === setDashedAisleProperties: (width, dashLength, gapLength) => set((state) => { state.aisleType = 'dashed-aisle'; state.aisleWidth = width; state.dashLength = dashLength; state.gapLength = gapLength; }), setDottedAisleProperties: (width, dotRadius, gapLength) => set((state) => { state.aisleType = 'dotted-aisle'; state.aisleWidth = width; state.dotRadius = dotRadius; state.gapLength = gapLength; }), setArrowsAisleProperties: (width, aisleLength, gapLength) => set((state) => { state.aisleType = 'arrows-aisle'; state.aisleWidth = width; state.aisleLength = aisleLength; state.gapLength = gapLength; }), setAisleProperties: (type, width, color) => set((state) => { state.aisleType = type; state.aisleWidth = width; state.aisleColor = color; }) })) );