//
// C++ Interface: history
//
// Description: 
//
//
// Author: Benjamin Mesing <bensmail@gmx.net>, (C) 2004
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef __HISTORY_H_2004_04_18
#define __HISTORY_H_2004_04_18

#include <list>

using namespace std;

namespace NBrowser {

/** The history is characterized by a list of entries and a current position. In this it is similar to the
  * ADT table.
  * @invariant _entries.empty() -> _current.end()
  * @author Benjamin Mesing
  */
template <typename T>
class History
{
	typedef list<T> Entries;
	Entries _entries;
	typename list<T>::iterator _current;
public:
	History();
	/** @returns if forward is possible i.e. we are not at the end of the history. 
	  * @todo is --end() valid??*/
	bool forwardPossible() const	{ return !_entries.empty() && (_current != (--_entries.end())); };
	/** @returns if back is possible i.e. we are not at the start of the history. */
	bool backPossible() const 	{ return !_entries.empty() && (_current!=_entries.begin()); };
	/** Make the next recent entry the current one and returns it.
	  * @pre forward must be possible */
	const T& forward()	{ return *(++_current); };
	/** Make the last recent entry the current one and returns it.
	  * @pre back must be possible */
	const T& back()	{ return *(--_current); };
	/** @brief Returns the current entry which <b>must</b> exist. 
	  *
	  * @pre empty() != 0
	  */
	const T& current() const	{ return *_current; }
	/** @brief Returns if the history is empty. */
	bool empty() const	{ return _entries.empty(); }
	/** @brief Appends an entry after the current position. 
	  *
	  * If the current position is not the last one, all 
	  * following entries will be removed. The current entry will be the one appended. */
	void append(const T& t);
	/** Clears the history. */
	void clear();
};

template <typename T>
History<T>::History()
{
	_current = _entries.end();
}


template <typename T>
void History<T>::append(const T& t)
{
	if (_current != _entries.end())
	{	// delete all entries after the current one
		_entries.erase(++_current, _entries.end());
	}
	_current = _entries.insert(_entries.end(), t);
}

template <typename T>
void History<T>::clear()
{
	_entries.clear();
	_current=_entries.end();
}


};


#endif	//  __HISTORY_H_2004_04_18
