import { create } from 'zustand'; import { immer } from 'zustand/middleware/immer'; interface AssetsStore { assets: Assets; // Asset CRUD operations addAsset: (asset: Asset) => void; removeAsset: (modelUuid: string) => void; updateAsset: (modelUuid: string, updates: Partial) => void; clearAssets: () => void; setAssets: (assets: Assets) => void; // Asset properties setName: (modelUuid: string, newName: string) => void; setPosition: (modelUuid: string, position: [number, number, number]) => void; setRotation: (modelUuid: string, rotation: [number, number, number]) => void; setLock: (modelUuid: string, isLocked: boolean) => void; setCollision: (modelUuid: string, isCollidable: boolean) => void; setVisibility: (modelUuid: string, isVisible: boolean) => void; setOpacity: (modelUuid: string, opacity: number) => void; // Animation controls setAnimation: (modelUuid: string, animation: string) => void; setCurrentAnimation: (modelUuid: string, current: string, isPlaying: boolean) => void; addAnimation: (modelUuid: string, animation: string) => void; removeAnimation: (modelUuid: string, animation: string) => void; // Event data operations addEventData: (modelUuid: string, eventData: Asset['eventData']) => void; updateEventData: (modelUuid: string, updates: Partial) => void; removeEventData: (modelUuid: string) => void; // Helper functions getAssetById: (modelUuid: string) => Asset | undefined; getAssetByPointUuid: (pointUuid: string) => Asset | undefined; hasAsset: (modelUuid: string) => boolean; } export const createAssetStore = () => { return create()( immer((set, get) => ({ assets: [], // Asset CRUD operations addAsset: (asset) => { set((state) => { if (!state.assets.some(a => a.modelUuid === asset.modelUuid)) { state.assets.push(asset); } }); }, removeAsset: (modelUuid) => { set((state) => { state.assets = state.assets.filter(a => a.modelUuid !== modelUuid); }); }, updateAsset: (modelUuid, updates) => { set((state) => { const asset = state.assets.find(a => a.modelUuid === modelUuid); if (asset) { Object.assign(asset, updates); } }); }, clearAssets: () => { set((state) => { state.assets = []; }); }, setAssets: (assets) => { set((state) => { state.assets = assets; }); }, // Asset properties setName: (modelUuid, newName) => { set((state) => { const asset = state.assets.find(a => a.modelUuid === modelUuid); if (asset) { asset.modelName = newName; } }); }, setPosition: (modelUuid, position) => { set((state) => { const asset = state.assets.find(a => a.modelUuid === modelUuid); if (asset) { asset.position = position; } }); }, setRotation: (modelUuid, rotation) => { set((state) => { const asset = state.assets.find(a => a.modelUuid === modelUuid); if (asset) { asset.rotation = rotation; } }); }, setLock: (modelUuid, isLocked) => { set((state) => { const asset = state.assets.find(a => a.modelUuid === modelUuid); if (asset) { asset.isLocked = isLocked; } }); }, setCollision: (modelUuid, isCollidable) => { set((state) => { const asset = state.assets.find(a => a.modelUuid === modelUuid); if (asset) { asset.isCollidable = isCollidable; } }); }, setVisibility: (modelUuid, isVisible) => { set((state) => { const asset = state.assets.find(a => a.modelUuid === modelUuid); if (asset) { asset.isVisible = isVisible; } }); }, setOpacity: (modelUuid, opacity) => { set((state) => { const asset = state.assets.find(a => a.modelUuid === modelUuid); if (asset) { asset.opacity = opacity; } }); }, // Animation controls setAnimation: (modelUuid, animation) => { set((state) => { const asset = state.assets.find(a => a.modelUuid === modelUuid); if (asset) { if (!asset.animationState) { asset.animationState = { current: animation, playing: false }; } else { asset.animationState.current = animation; } } }); }, setCurrentAnimation: (modelUuid, current, isPlaying) => { set((state) => { const asset = state.assets.find(a => a.modelUuid === modelUuid); if (asset?.animationState) { asset.animationState.current = current; asset.animationState.playing = isPlaying; } }); }, addAnimation: (modelUuid, animation) => { set((state) => { const asset = state.assets.find(a => a.modelUuid === modelUuid); if (asset) { if (!asset.animations) { asset.animations = [animation]; } else if (!asset.animations.includes(animation)) { asset.animations.push(animation); } } }); }, removeAnimation: (modelUuid, animation) => { set((state) => { const asset = state.assets.find(a => a.modelUuid === modelUuid); if (asset?.animations) { asset.animations = asset.animations.filter(a => a !== animation); if (asset.animationState?.current === animation) { asset.animationState.playing = false; asset.animationState.current = ''; } } }); }, // Event data operations addEventData: (modelUuid, eventData) => { set((state) => { const asset = state.assets.find(a => a.modelUuid === modelUuid); if (asset) { asset.eventData = eventData; } }); }, updateEventData: (modelUuid, updates) => { set((state) => { const asset = state.assets.find(a => a.modelUuid === modelUuid); if (asset?.eventData) { asset.eventData = { ...asset.eventData, ...updates }; } }); }, removeEventData: (modelUuid) => { set((state) => { const asset = state.assets.find(a => a.modelUuid === modelUuid); if (asset) { delete asset.eventData; } }); }, // Helper functions getAssetById: (modelUuid) => { return get().assets.find(a => a.modelUuid === modelUuid); }, getAssetByPointUuid: (pointUuid) => { return get().assets.find(asset => asset.eventData?.point?.uuid === pointUuid || asset.eventData?.points?.some(p => p.uuid === pointUuid) ); }, hasAsset: (modelUuid) => { return get().assets.some(a => a.modelUuid === modelUuid); } })) ) } export type AssetStoreType = ReturnType;