using TraceCad.Core.Model;
using TraceCad.Core.Geometry;

namespace TraceCad.Core.Commands;

public sealed class CommandManager
{
    private readonly Stack<IDocumentCommand> _undo = new();
    private readonly Stack<IDocumentCommand> _redo = new();

    public bool CanUndo => _undo.Count > 0;

    public bool CanRedo => _redo.Count > 0;

    public void Execute(SketchDocument document, IDocumentCommand command)
    {
        command.Apply(document);
        SketchConstraintSolver.Solve(document);
        _undo.Push(command);
        _redo.Clear();
    }

    public void Undo(SketchDocument document)
    {
        if (!CanUndo)
        {
            return;
        }

        var command = _undo.Pop();
        command.Revert(document);
        SketchConstraintSolver.Solve(document);
        _redo.Push(command);
    }

    public void Redo(SketchDocument document)
    {
        if (!CanRedo)
        {
            return;
        }

        var command = _redo.Pop();
        command.Apply(document);
        SketchConstraintSolver.Solve(document);
        _undo.Push(command);
    }

    public void Clear()
    {
        _undo.Clear();
        _redo.Clear();
    }
}
