#ifndef __COMMAND_H
#define __COMMAND_H

#include "graphic_components.h"


class GridDesigner;


class Command {
public:
	Command() { _executed = false; }

	virtual void execute() = 0;
	virtual void undo() = 0;

	void setExecuted(bool executed) { _executed = executed; }

	bool executed() { return _executed; }

private:
	bool _executed;
};

class NewGridNode : public Command {
public:
	NewGridNode(GridDesigner* designer, double x, double y, int compId, const QString& name);
	~NewGridNode();

	virtual void execute();
	virtual void undo();

private:
	GridDesigner* _designer;
	GridNode* _component;
	double _x, _y;
	int _compId;
	QString _name;
};

class NewLink : public Command {
public:
	NewLink(GridDesigner* designer, double x, double y, int compId, const QString& name);
	~NewLink();
	
	virtual void execute();
	virtual void undo();
	
private:
	GridDesigner* _designer;
	Link* _component;
	double _x, _y;
	int _compId;
	QString _name;
};

class NewConnection : public Command {
public:
	NewConnection(GridDesigner* designer, DesignerComponent* src, DesignerComponent* dest, int compId);
	~NewConnection();

	virtual void execute();
	virtual void undo();
	
private:
	GridDesigner* _designer;
	Connection* _component;
	DesignerComponent *_src, *_dest;
	int _compId;
};

class MoveItems : public Command {
public:
	MoveItems(GridDesigner* designer, DesignerItemMap items, QPointF offset);
	~MoveItems();
	
	virtual void execute();
	virtual void undo();
	
private:
	GridDesigner* _designer;
	DesignerItemMap _items;
	QPointF _offset;
	ConnectionPointMap _movPoints;
	ConnectionPointMap _selPoints;
};

class DeleteItems : public Command {
public:
	DeleteItems(GridDesigner* designer, DesignerItemMap items);
	~DeleteItems();
	
	virtual void execute();
	virtual void undo();
	
private:
	GridDesigner* _designer;
	DesignerItemMap _items;
	DesignerItemMap _originalItems;
};

class AddConnectionPoint : public Command {
public:
	/**
	Add a new connection point.<br>
	cutPoint: the point near one of the lines in the Connection where the connection is cut to create the new point.<br>
	newPoint: the new point. If this parameter is null the new point is the cutPoint.
	*/
	AddConnectionPoint(GridDesigner* designer, Connection* conn, QPointF cutPoint, QPointF newPoint = QPointF());
	~AddConnectionPoint();
	
	virtual void execute();
	virtual void undo();
	
private:
	GridDesigner* _designer;
	Connection* _conn;
	QPointF _cutPoint;
	QPointF _newPoint;
};

class RemoveConnectionPoint : public Command {
public:
	RemoveConnectionPoint(GridDesigner* designer, Connection* conn, QPointF delPoint);
	~RemoveConnectionPoint();
	
	virtual void execute();
	virtual void undo();
	
private:
	GridDesigner* _designer;
	Connection* _conn;
	QPointF _delPoint;
	QPointF _removedPoint;
};

class ChangeLinkProperties : public Command {
public:
	ChangeLinkProperties(GridDesigner* designer, Link* link, const QString& name, uint band, double lat);
	~ChangeLinkProperties();
	
	virtual void execute();
	virtual void undo();
	
private:
	Link* _link;
	QString _name, _oldName;
	double _band, _oldBand;
	double _lat, _oldLat;
};

class ChangeNodeProperties : public Command {
public:
	ChangeNodeProperties(GridDesigner* designer, GridNode* node, const QString& name, uint pow);
	~ChangeNodeProperties();
	
	virtual void execute();
	virtual void undo();
	
private:
	GridNode* _node;
	QString _name, _oldName;
	double _pow, _oldPow;
};

#endif // __COMMAND_H
