import { Command } from './Command';

/**
 * CommandManager manages the execution and history of commands
 * Provides undo/redo functionality
 */
export class CommandManager {
    private history: Command[] = [];
    private currentIndex = -1;
    private maxHistorySize: number;

    constructor(maxHistorySize: number = 50) {
        this.maxHistorySize = maxHistorySize;
    }

    /**
     * Execute a command and add it to history
     */
    execute(command: Command): void {
        command.execute();
        
        // Remove any commands after current index (redo history)
        this.history = this.history.slice(0, this.currentIndex + 1);
        
        // Add new command
        this.history.push(command);
        this.currentIndex++;
        
        // Limit history size
        if (this.history.length > this.maxHistorySize) {
            this.history.shift();
            this.currentIndex--;
        }
    }

    /**
     * Undo the last command
     */
    undo(): boolean {
        if (!this.canUndo()) {
            return false;
        }
        
        const command = this.history[this.currentIndex];
        command.undo();
        this.currentIndex--;
        
        return true;
    }

    /**
     * Redo the next command
     */
    redo(): boolean {
        if (!this.canRedo()) {
            return false;
        }
        
        this.currentIndex++;
        const command = this.history[this.currentIndex];
        command.execute();
        
        return true;
    }

    /**
     * Check if undo is available
     */
    canUndo(): boolean {
        return this.currentIndex >= 0;
    }

    /**
     * Check if redo is available
     */
    canRedo(): boolean {
        return this.currentIndex < this.history.length - 1;
    }

    /**
     * Clear all history
     */
    clear(): void {
        this.history = [];
        this.currentIndex = -1;
    }

    /**
     * Get the current history size
     */
    getHistorySize(): number {
        return this.history.length;
    }

    /**
     * Get the current index in history
     */
    getCurrentIndex(): number {
        return this.currentIndex;
    }
}
