/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
/*
Author: Christian Hubinger <chubinger@irrsinnig.org>, (C) 2001-2008
*/
#ifndef KMFUNDOENGINE_H
#define KMFUNDOENGINE_H


// qt includes
#include "qdict.h"
#include "qvaluelist.h"
#include "qptrlist.h"
#include "qstring.h"
#include "qobject.h"

// project includes
#include "kmftransaction.h"
#include "netfilterobject.h"
// #include "kmfnetwork.h"
#include "kmferror.h"

namespace KMF {
class KMyFirewallInterface;
class KMFTransaction;
class KMFNetwork;
/**
	@author Christian Hubinger <chubinger@irrsinnig.org>
*/

class KMFUndoEngine : public QObject {
	Q_OBJECT
	
	friend class KMFTransaction;
	friend class KMFNetwork;
	friend class KMFProtocol;
	friend class KMFProtocolCategory;
	friend class KMFProtocolLibrary;
//############# Beginn static stuff ##############	
public:
	/** return the one and only instance */
	static KMFUndoEngine* instance();
private:	
	static KMFUndoEngine* m_instance;
	
//############# End static stuff ##############
protected:
	uint MAX_UNDO;
public:
	~KMFUndoEngine();
	
	/** Set the numbers of undo/redo steps stored */
	void setMaxUndo( uint );
	
	/** Get the numbers of undo/redo steps stored */
	uint maxUndo() {
		return MAX_UNDO;
	};
	
	/** Start a transaction e.g. collection of changes that will
		be tracked to allow undo/redo */
	void startTransaction( NetfilterObject* /* highestAffectedObject */, const QString& name );
	
	/** Abort a started transaction */
	void abortTransaction();
	
	/** Hold list of available undo transaction objects */
	QValueList< KMFTransaction* >& undoTransactions();
	
	/** Hold list of available redo transaction objects */
	QValueList< KMFTransaction* >& redoTransactions();
	
	/** find the transaction with id in undo/redo lists */
	KMFTransaction * findTransction( const QUuid& id );
	
	/** End a transaction e.g. collection of changes that will
		be tracked to allow undo/redo */
	void endTransaction();
	
	/** Check if we are inside a transaction */
	bool inTransaction();
	
	/** store the provided id in the changes list. */
	void changed( const QUuid& id );
	
	/** Remove all stored transacation */
	void clearStacks();

	/** Check if the doc is saved */
	bool isSaved();
	void saved();

	/** Undo last transaction, return list of affected objects */
	QValueList< NetfilterObject* >& undo();
	
	/** Redo last undo-transaction, return list of affected objects */
	QValueList< NetfilterObject* >& redo();
	
	/** Set the ap instance */
	void setKMFInterface( KMyFirewallInterface *app );
	
	/** log message entry */
	void log( const QString&, int kmfErrorType /* = KMFError::NORMAL */, NetfilterObject*  /* obj = 0 */ );
	
// 	bool preserveObjectUuid() const {
// 		// return m_preserveObjectUuid;
// 		return true;
// 	}
	
protected:
	KMyFirewallInterface *m_app;
	
private:
//	QString m_transactionName;
	bool m_in_transaction;
	bool is_saved;
// 	bool m_preserveObjectUuid;
	
	QValueList< KMFTransaction* > m_undo_transactionObjects;
	QValueList< KMFTransaction* > m_redo_transactionObjects;
	
//	QValueList<int> m_changed_objects;	
// 	NetfilterObject *m_highestAffectedObject;
	KMFTransaction *m_currentTransaction;
	
private:
	KMFUndoEngine(); 
	KMFUndoEngine( QObject*, const char* );
	
	/** Make the loadXML in NEtfilterObject load the uuid from xml */
// 	void setPreserveObjectUuid( bool onOff );



	
signals:
	void sigStackChanged();	
	void sigLog( const QString& );
};
}
#endif
