// UndoManager.h: interface for the UndoManager class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_UNDOMANAGER_H__8D4EFECB_204F_4BE0_8952_13AB4341E301__INCLUDED_)
#define AFX_UNDOMANAGER_H__8D4EFECB_204F_4BE0_8952_13AB4341E301__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <Compost\FeatureGrid.hpp>
class CImageGrinderDoc;
using namespace Compost;


#define COMMAND_MAX 256

class UndoCommand
{
protected:
	FeatureInstance *Object;
	UndoCommand *Next;
public:
	virtual void ExecuteUndo(UndoCommand **revcom);
	virtual void Discard() { }
	void Attach(UndoCommand *cmd);
	UndoCommand(FeatureInstance *obj) {Verify(obj); Object=obj; Next=NULL; }
	virtual ~UndoCommand() {}
};
/*
class RenameCommand:public UndoCommand
{
protected:
	CString OldName;
public:
	void ExecuteUndo(UndoCommand **revcom);
	RenameCommand(FeatureInstance *obj):UndoCommand(obj) 
		{OldName=obj->GetName(); } 
	virtual ~RenameCommand() {}
};
*/
class MoveCommand:public UndoCommand
{
protected:
	CImageGrinderDoc *Parent;
	int xpos,zpos;
public:
	void ExecuteUndo(UndoCommand **revcom);
	MoveCommand(FeatureInstance *obj,CImageGrinderDoc *par):UndoCommand(obj) 
		{  Parent=par; xpos=obj->feature_x_pos; zpos=obj->feature_z_pos;} 
	virtual ~MoveCommand() {}
};


class AddCommand:public UndoCommand
{
protected:
	CImageGrinderDoc *Parent;
public:
	void ExecuteUndo(UndoCommand **revcom);
	AddCommand(FeatureInstance *obj,CImageGrinderDoc *par):UndoCommand(obj) 
		{ Parent=par; Verify(Parent);} 
	virtual ~AddCommand() {  }
};


class DeleteCommand:public UndoCommand
{
protected:
	CImageGrinderDoc *Parent;
	Compost::Feature *Fet;
	int XPos,ZPos;
public:
	void ExecuteUndo(UndoCommand **revcom);
	void Discard() {}
	DeleteCommand(FeatureInstance *obj,CImageGrinderDoc *par):UndoCommand(obj) 
		{Parent=par; Fet=obj->feature; XPos=obj->feature_x_pos; ZPos=obj->feature_z_pos; Verify(Parent); } 
	virtual ~DeleteCommand() {  }
};
/*
class GroupCommand:public UndoCommand
{
protected:
	GUIObjectList *Parent;
public:
	void ExecuteUndo(UndoCommand **revcom);
	GroupCommand(FeatureInstance *obj):UndoCommand(obj) 
		{Parent=obj->GetParent(); Verify(Parent);} 
	virtual ~GroupCommand() {  }
};
*/
class CommandStack
{
protected:
UndoCommand *Commands[COMMAND_MAX];
int CommandMax;
int CommandCount;
	
	void RemoveBottomCommand();
public:
	int Depth() {return CommandCount;}
	void PushCommand(UndoCommand *cmd);
	UndoCommand *Pop();
	UndoCommand *PopAndExecute();
	void Clear(); 
	CommandStack();
	virtual ~CommandStack() { Clear();}

};

class UndoManager  
{
protected:
CommandStack UndoStack,RedoStack;
public:
	void Clear() {UndoStack.Clear(); RedoStack.Clear();} 
	void AddCommand(UndoCommand *cmd);
	bool CanUndo() {return (UndoStack.Depth()>0);}
	bool CanRedo() {return (RedoStack.Depth()>0);}
	void Undo();
	void Redo();	
	UndoManager() {}
	virtual ~UndoManager();
	
};

#endif // !defined(AFX_UNDOMANAGER_H__8D4EFECB_204F_4BE0_8952_13AB4341E301__INCLUDED_)
