// SonicForge Studio - DAW Command Dispatcher // Command Pattern & Undo/Redo Engine (28_AI_PANEL.md §1 & §2) const DAWCommandDispatcher = (function() { const MAX_HISTORY = 50; const history = []; let historyIndex = -1; function pushHistory(entry) { history.push(entry); if (history.length > MAX_HISTORY) history.shift(); historyIndex = history.length - 1; } function undo() { if (historyIndex < 0) return null; const entry = history[historyIndex]; historyIndex--; return entry; } function redo() { if (historyIndex >= history.length - 1) return null; historyIndex++; const entry = history[historyIndex]; return entry; } function canUndo() { return historyIndex >= 0; } function canRedo() { return historyIndex < history.length - 1; } const registry = {}; function register(name, handler) { registry[name] = handler; } function execute(name, args) { if (!registry[name]) { return { success: false, error: `Unknown command: ${name}` }; } const result = registry[name](args); pushHistory({ name, args, result, timestamp: Date.now() }); return result; } function getHistory() { return history; } function getHistoryIndex() { return historyIndex; } function registerDAWCommands(api) { register('CREATE_TRACK', (args) => api.createTrack(args)); register('DELETE_TRACK', (args) => api.deleteTrack(args)); register('ADD_CLIP', (args) => api.addClip(args)); register('REMOVE_CLIP', (args) => api.removeClip(args)); register('SET_TRACK_VOLUME', (args) => api.setTrackVolume(args)); register('SET_TRACK_PAN', (args) => api.setTrackPan(args)); register('TOGGLE_MUTE', (args) => api.toggleMute(args)); register('TOGGLE_SOLO', (args) => api.toggleSolo(args)); register('PROCESS_AUDIO_DSP', (args) => api.processAudioDsp(args)); register('RENAME_TRACK', (args) => api.renameTrack(args)); register('SCAN_TRACK', (args) => api.scanTrack(args)); register('FADE_IN', (args) => api.fadeIn(args)); register('FADE_OUT', (args) => api.fadeOut(args)); register('CUT_AUDIO', (args) => api.cutAudio(args)); register('SET_SELECTION', (args) => api.setSelection(args)); register('EXPORT_AUDIO', (args) => api.exportAudio(args)); register('SET_BPM', (args) => api.setBpm(args)); register('SET_PLAYHEAD', (args) => api.setPlayhead(args)); register('SELECT_ITEM', (args) => api.selectItem(args)); register('ADD_MARKER', (args) => api.addMarker(args)); register('CREATE_MIDI_ITEM', (args) => AIGateway.createMidiItem(args)); register('MODIFY_MIDI_NOTES', (args) => AIGateway.modifyMidiNotes(args)); register('PROCESS_AI_DSP', (args) => AIGateway.processAIDSP(args)); register('GENERATE_MULTITRACK_MIDI', (args) => api.generateMultitrackMidi(args)); } return { register, execute, undo, redo, canUndo, canRedo, pushHistory, getHistory, getHistoryIndex, registerDAWCommands }; })(); window.DAWCommandDispatcher = DAWCommandDispatcher;