/****************************************************************************
** UndoBuffer and UndoObject code
** Created: Thursday Jan 2'nd 2003
** Varol Okan
****************************************************************************/
#include "undobuffer.h"

UndoBuffer::UndoBuffer(uint iDepth)
{
	// All objects belong to the UndoBuffer.
	// We handle the deletion manually !
	//	setAutoDelete(TRUE);
	if (iDepth < 1)
		iDepth = 1;
	m_iDepth = iDepth;
	m_bFromOutsidePush = true;
}

UndoBuffer::~UndoBuffer()
{
	uint t;
	// Here we remove all Objects stored in the Undo- and Redo-Buffers
	for (t=0;t<count();t++)
		delete at(t);
	for (t=0;t<m_redoBuffer.count();t++)
		delete m_redoBuffer.at(t);
}

// PUBLIC : Get the last Undo Object.
UndoObject *
UndoBuffer::pop ()
{
	// This function is called, to retrieve the last change
	// First check if the Undo Buffer is empty.
	if (count () < 1)
		return 0;
	// Now retrieve the UndoObject
	UndoObject *pUndoObject = last();
	removeLast();
	// and store it on the Redo - stack.
	m_redoBuffer.append (pUndoObject);
	return pUndoObject;
}

// PUBLIC : Get the last redo Object
UndoObject *
UndoBuffer::popRedo ()
{
	// Check if the redo buffer is empty.
	if (m_redoBuffer.count() < 1)
		return 0;
	UndoObject *pUndoObject = m_redoBuffer.last ();
	m_redoBuffer.removeLast();
	// Redo means that we will increase the undo buffer again.
	m_bFromOutsidePush = false;

	append (pUndoObject);
	return pUndoObject;
}

// PUBLIC : Store the UndoObject
void
UndoBuffer::push (UndoObject *pUndoObject)
{
	uint t;
	if (m_bFromOutsidePush)	{
		// Here we check if push was called from this class itself,
		// then we're going to delete the redo Buffer
		for (t=0;t<m_redoBuffer.count();t++)
			delete m_redoBuffer.at(t);
		m_redoBuffer.clear();
	}
	m_bFromOutsidePush = true;
	if (count() > m_iDepth)	{
		// here we check and see if the maximal depth of the Undo Buffer has been reached.
		// If so, we delete the first entry before we add another one.
		UndoObject *pUndoObject = first ();
		removeFirst ();
		delete pUndoObject;
	}
	// Finally we can store the UndoObject onto the stack.
	append (pUndoObject);
}

// Misc functions not yet used, thus currently only protected.
uint
UndoBuffer::countRedo ()
{
	return m_redoBuffer.count();
}

UndoObject *
UndoBuffer::atRedo (uint iPosition)
{
	return m_redoBuffer.at(iPosition);
}

void
UndoBuffer::pushRedo (UndoObject *pUndoObject)
{
	m_redoBuffer.append(pUndoObject);
}

//////////////////////////////////////////////////////////////////////
//
// UndoObject class starts here
// This class holds the information for the undo function to take effect.
//
//////////////////////////////////////////////////////////////////////
UndoObject::UndoObject()
{
}

UndoObject::~UndoObject()
{
}

int
UndoObject::getType ()
{
	return m_enUndoType;
}
