/********************************************************************/
/* Copyright (c) 2019 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/********************************************************************/
// IAction.h: Declaration for interface IAction.
#pragma once

struct IActionTarget;

/// @class IAction IAction.h "Undo/IAction.h"
///
/// Actions are undoable operations. This class abstracts that notion
/// by defining the following interface:
///
/// void Do();
///     carry out the operation; generally called only once;
///     usually, the action must save the existing state before
///     performing its operation
///
/// void Undo();
///     called to undo what was done in Do(); usually must
///     save the new state, as created by Do(), before reverting
///     to the previous state before Do()
///
/// void Redo();
///     called to redo an undone action; generally this is
///     different from Do() because all states have already
///     been saved explicitly by Do() or Undo(); occasionally,
///     a state may be more difficult to store than to compute,
///     so then this routine may just call Do()
///
/// Each derived class should call its base class's implementation of
/// these routines.
struct IAction
{
	enum ACTION_TYPE
	{
		ACTION_DO = 1,
		ACTION_UNDO,
		ACTION_REDO
	};

	virtual ~IAction(){}

	virtual void Do() = 0;
	virtual void Redo() = 0;
	virtual void Undo() = 0;

	virtual IActionTarget* GetActionTarget() const = 0;
	virtual void SetActionTarget(IActionTarget* pTarget) = 0;

	virtual bool IsAutoNotify() const = 0;
	virtual void SetAutoNotify(bool bAuto) = 0;

	/// is the action done or undone?
	virtual bool IsUndone() const = 0;

	/// Ask if this is in redo stack (if so, return true).
	virtual bool in_redo_stack() const = 0;
	/// Ask if this is in undo stack (if so, return true).
	virtual bool in_undo_stack() const = 0;

	/// Set stack kind.
	virtual void set_as_undo_stack() = 0;
	virtual void set_as_redo_stack() = 0;
};
