/***************************************************************************
 *   Copyright (C) 2005 Thomas Nagy                                        *
 *   tnagy2^8@yahoo.fr                                                     *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License version 2        *
 *   as published by the Free Software Foundation (see COPYING)            *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 ***************************************************************************/

#ifndef _DDELTA_H
#define _DDELTA_H

#include <qptrlist.h>
#include <qpixmap.h>
#include <qcolor.h>
#include <qvaluelist.h>

#include "DDataItem.h"

class DDataControl;

/**
 * This class handles the actions to undo
 * or redo the changes on the data
 *
 * @short Undo/Redo handler
 * @author Thomas Nagy <tnagy2^8@yahoo.fr>
 */

class DDelta
{
	public:
		DDelta(DDataControl* ctrl) { m_ctrl=ctrl; m_type=e_deltaerror; }
		virtual ~DDelta() {}

		enum changetype
		{
			e_deltacreate,
			e_deltamove,
			e_deltalink,
			e_deltacolor,
			e_deltaflag,
			e_deltaerror=-1
		};

		virtual void applyUndo()=0;
		virtual void applyRedo()=0;
		inline int Type() const { return m_type; }

	protected:
		int m_type;
		DDataControl* m_ctrl;
};

/**
 * Add or remove an object
 */
class DDeltaCreate : public DDelta
{
	public:
		DDeltaCreate(DDataControl*, int id, bool remove=false);
		virtual ~DDeltaCreate() {}

		void applyUndo();
		void applyRedo();

		void copyFromItem();
		void copyToItem();
		
	private:
		int m_itemid;
		bool m_remove;

		QFont m_defaultFont;
		QString m_text;
		QString m_summary;
		QString m_comment;
		QPixmap m_pix;
		QPixmap m_pixtb;
		QString m_piccaption;
		QString m_picurl;
		QString m_picfilename;

		int m_colorscheme;
		QColor m_fillcolor;
		// TODO: the following two colors are not settable
		//QColor m_outlinecolor;
		//QColor m_textcolor;

		QValueList<URLObject> m_urllist;
		QValueList<int> m_flags;

		int m_lastchild;
		DDataItem::Coord m_x, m_y;
};

/**
 * Move an object
 */
class DDeltaMove : public DDelta
{
	public:
		DDeltaMove(DDataControl* ctrl, int id, DDataItem::Coord oldx, DDataItem::Coord oldy, DDataItem::Coord newx, DDataItem::Coord newy);
		virtual ~DDeltaMove() {}

		void applyUndo();
		void applyRedo();
	private:
		int m_id;
                DDataItem::Coord m_oldx, m_oldy, m_newx, m_newy;
};

/**
 * Link an object
 */
class DDeltaLink : public DDelta
{
	public:
		DDeltaLink(DDataControl* ctrl, int id, int parentid, bool remove=false, bool isref=false);
		virtual ~DDeltaLink() {}

		void applyUndo();
		void applyRedo();
	private:
		int m_id, m_parentid, m_remove, m_isref;
};

/**
 * Change the object color
 */
class DDeltaColor : public DDelta
{
	public:
		DDeltaColor(DDataControl* ctrl, int id, int oldc, int newc, QColor mncust, QColor mocust);
		virtual ~DDeltaColor() {}

		void applyUndo();
		void applyRedo();
	private:
		int m_id, m_oldcolor, m_newcolor;
		QColor m_new_customcolor, m_old_customcolor;
};

/**
 * Change the object flag
 */
class DDeltaFlag : public DDelta
{
	public:
		DDeltaFlag(DDataControl* ctrl, int id, int flag, bool add=true);
		virtual ~DDeltaFlag() {}

		void applyUndo();
		void applyRedo();
	private:
		int m_id, m_flag;
		bool m_add;
};

/**
 * DDeltaList holds a list of deltas
 * to switch between mindmap states
 *
 *
 * The creation of a mindmap object is made of
 * a DDeltaCreate and a DDeltaMove
 *
 * The removal of several mindmap objects is made of
 * several DDeltaDelete (and some DDeltaChange to notify the parents ?)
 *
 * The application of a color or a flag is made of
 * several DDeltaChange
 */
class DDeltaList
{
	public:
		DDeltaList() { m_deltalist.setAutoDelete(true); }
		~DDeltaList() {}

		void applyUndo();
		void applyRedo();

		inline unsigned int count() const {return m_deltalist.count();}
		
		void insertDelta( DDelta* );
		
	private:
		QPtrList<DDelta> m_deltalist;
};

#endif // _DDELTA_H
