/*
 * Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
 */

#pragma once

#include <ox/event/signal.hpp>
#include <ox/std/error.hpp>
#include <ox/std/memory.hpp>
#include <ox/std/vector.hpp>

#include "undocommand.hpp"

namespace studio {

class UndoStack {
	private:
		ox::Vector<ox::UPtr<UndoCommand>> m_stack;
		std::size_t m_stackIdx = 0;

	public:
		ox::Error push(ox::UPtr<UndoCommand> &&cmd) noexcept;

		ox::Error redo() noexcept;

		ox::Error undo() noexcept;

		[[nodiscard]]
		constexpr bool canRedo() const noexcept {
			return m_stackIdx < m_stack.size();
		}

		[[nodiscard]]
		constexpr bool canUndo() const noexcept {
			return m_stackIdx;
		}

		ox::Signal<ox::Error(studio::UndoCommand const*)> redoTriggered;
		ox::Signal<ox::Error(studio::UndoCommand const*)> undoTriggered;
		ox::Signal<ox::Error(studio::UndoCommand const*)> changeTriggered;
};

}
