#ifndef _HISTORY_H
#define _HISTORY_H

#include "URL.h"
#include "Resource.h"

namespace Wagner {

class FrameSet;

class History {
public:
	struct FramePath {
		FramePath(int32 max = 0);
		~FramePath();
		FramePath &operator=(const FramePath &src);

		int32 *indices;
		int32 depth;
		int32 maxDepth;
	};

	History();
	virtual ~History();

	void SetFrameData(const FramePath &framePath, const BMessage &frameData);
	bool FrameExists(const FramePath &framePath) const;

	void RemoveCurrentEntry();
	void Checkpoint();
	void Goto(const FramePath &framePath, const URL &url, GroupID zone);

	void GoBack(BMessage *msg);
	void GoForward(BMessage *msg);
	void GoOffset(BMessage *msg, int32 offset, bool retrieve_info_only = false);
	bool CanGoBack() const;
	bool CanGoForward() const;
	bool CanGoOffset(int32 offset) const;
	void BackFrameDelta(FramePath *framePath) const;
	void ForwardFrameDelta(FramePath *framePath) const;
	void OffsetFrameDelta(FramePath *framePath, int32 offset) const;
	
	int32 CountItems() const;
	
	void Dump();
	bool WasRestored() const;
	
private:
	struct HistoryEntry {
		FramePath framePath;
		FrameSet *frameSet;
		HistoryEntry *next, *prev;
	};

	static void DeleteSet(FrameSet *set);
	static void CopySet(FrameSet *dest, FrameSet *src);
	FrameSet *WalkPath(const FramePath &framePath, bool extend);
	void DoCheckpoint(bool full);
	
	bool fCheckpoint;
	HistoryEntry fDummyHead;
	HistoryEntry *fCurrentEntry;
	int32 fNumEntries;

	// Driver for restoring history after crashes
	void DriverOpen();
	void DriverForward();
	void DriverBackward();
	void DriverOffset(int32 offset);
	void DriverPush(const BMessage*);
	void DriverWrite(const BMessage *);
	int fDriverFD;
	bool fRestored;
};

}

#endif
