
#ifndef __UNDOC_H__
#define __UNDOC_H__

// Forward declaration.
namespace Edit {
	class UndoC;
};

#include "DataBlockI.h"
#include "PajaTypes.h"
#include <vector>
#include <string>
#include "EditableI.h"

namespace Edit {

	//! Flags for add_discardable_data()
	enum DiscardableTypeE {
		DATA_REMOVED = 1,	//!< The discardable data has been removed.
		DATA_CREATED = 2,	//!< The discardable data has been created.
	};

	//! Undo object class
	/*!	Undo object class is used internally by the Demopaja system to hold the
		original data modified by the action the undo object relates. For example
		if the editor executes a move command all the position parameters of the
		selected objects are push into the undo object. Later if the commands the
		application do undo, the data stored in the undo object is copied to the
		original place.

		When the undo object is pushed out of the undo stack, the discardable data
		and the copies of the original date are finally deleted.

		This class is implemented by the system.
	*/
	class UndoC
	{
	public:

		//! Default constructor.
		/*!	Creates new undo object and gives it name spcified by the argument. */
		UndoC( const char* szName );

		//! Default desctructor.
		virtual ~UndoC();

		//! Undoes the undo object (used internally).
		virtual void			undo();

		//! Redoes the undo object (used internally).
		virtual void			redo();

		//! Adds restore data to the undo object.
		/*!	Adds cloned editable to the undo object which is later used to restore
			the original state of the editable. The data has to be created with
			the clone() method of the editable! Otherwise the pointer to the
			original data won't be available nad no data will be restored.

			Example usage:
			\code
			...
			pUndo->add_restore_data( clone() );		// push clone of editbale into the undo object.
			...
			\endcode
		*/
		virtual void			add_restore_data( EditableI* pBlock );

		//! Adds discardable data to the undo object.
		/*!	The flags indicades whether the action was to remove or create new data.
			For example if you create new block of data and an undo object
			is available you should push the new data block, so that it can be
			deleted when the create action is undone.
		*/
		virtual void			add_discardable_data( DataBlockI* pBlock, PajaTypes::uint32 ui32Flags );

		//! Returns the name of the action.
		virtual const char*		get_name();
		
		//! Returns true if redo can be done (the condition is that undo is called).
		virtual bool			can_redo();

	private:

		struct DiscardableS {
			DataBlockI*	m_pData;
			bool		m_bDiscard;
		};

		std::vector<EditableI*>		m_rUndoBlocks;
		std::vector<EditableI*>		m_rRedoBlocks;
		std::vector<DiscardableS>	m_rDiscardable;
		std::string					m_sName;
		bool						m_bUndoDone;
	};


};	// namespace Edit



#endif	//__UNDOC_H__