/*************************************************************************
 * This file is part of Graphic des EDitor project
 *
 * Project created in conformity with the requirements for the Degree of
 * Master of Engineering in Software Engineering, Computing and Software
 * Department, McMaster University 2004 - 2008
 *
 * Author:	Xiao Ma
 * Supervisor: Dr. Ryan Leduc
*************************************************************************/

/*
 NAME
   GedDesState.h - Ged DES scene class.
 FUNCTION
   The class provides definition of DES scene.
 NOTES
 MODIFIED
   xma	    04/01/07 - CREATION
*/


#ifndef GedDesScene_H
#define GedDesScene_H

#include <QGraphicsScene>
#include "GedDesState.h"
#include "GedDesTrans.h"
//#include "GedDesWorkspace.h"
#include "GedTextItem.h"
#include "Des.h"
#include "GedDesHelper.h"

//class GedDesWorkspace;
class QGraphicsSceneMouseEvent;
class QMenu;
class QPointF;
class QGraphicsLineItem;
class QFont;
class QGraphicsTextItem;
class QColor;


namespace DESpot
{

class GedDesEditor;
class GedDesWorkspace;

class GedDesScene : public QGraphicsScene
{
    Q_OBJECT

public:
    enum Mode { InsertState, InsertTrans, InsertTransCurve, ChangeTrans, InsertText, MoveItem };
	enum editMode {Interactive, AutoGenerate};
	#define NOTEXIST QPointF(-1,-1)

    GedDesScene(GedDesWorkspace *workspace,QMenu *stateMenu, QMenu *transMenu, Des *des = 0, QObject *parent = 0);
	~GedDesScene();

	//Utility functions for auto graphic generation
	GedDesState* insertState(const DesState &state, QPointF pos, QPointF labelPos=QPointF(5,5));
	//	GedDesState* insertState(const DesState &state, QPointF pos, QPointF labelPos=QPointF(20,20));
	void insertTrans(const DesTransition *trans, bool isCurve = DEFAULT_TRANS_IS_CURVE);

	void save();
	void open();

	//Utility functions for save/open
	GedDesWorkspace* workspace() const
	  { return desWorkspace;}
	const GedDesState* gedState(const DesState *state) const;
	QPointF statePos(const DesState &state);
	QPointF stateLabelPos(const DesState &state);
	QList<QPointF> transPos(const DesTransition &trans);
	QPointF transLabelPos(const DesTransition &trans);
	qreal selfloopPos(const DesTransition &trans);

	GedDesTrans* gedTrans(GedDesState *startState,
						 GedDesState *endState);
	GedDesTrans* gedTrans(GedDesState *startState, const DesEvent* ev,
						 GedDesState *endState);
	GedDesTrans* gedTrans(const DesTransition *desTrans);

	QGraphicsRectItem* getStartRect()
		{return startRect;}
	bool isModified()
		{return modified;}
	void setModified(bool modify)
		{modified = modify;}
signals:
    void stateInserted(GedDesState *item);
    void transInserted(GedDesTrans *item);
	void textInserted(QGraphicsTextItem *item);
    void itemSelected(QGraphicsItem *item);

public slots:
    void setMode(Mode mode);
    void setCompType(GedDesState::GedStateType type);
    void editorLostFocus(DiagramTextItem *item);

	void toggleInitState(bool);
	void toggleMarkedState(bool);

	void editItem();
	void deleteItem();
	void deleteAllItems();
	void restoreTransShape();
	void toggleCurvature();

	void editState(GedDesState *state);
	void editTransition(GedDesTrans *trans);
	void deleteState(GedDesState *state);
	void deleteTransition(GedDesTrans *trans);
	void showMessage(bool visible);

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
    void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent);
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent);

private:
	// Des related utiliy functions
	bool isStateValid(std::wstring text);
	//bool checkGraphConsistency(bool silent);
    bool isItemChange(int type);
    // Initializes graphical elements on new GedDesState
    void initGedState(GedDesState* pState);
    void initGedTrans(GedDesTrans* pTrans);

    GedDesState::GedStateType gedStateType;
	GedDesWorkspace *desWorkspace;
	GedDesEditor *desEditor;
	Des *des;
	Des::GedInfo* stateMap;
	//QMap<const DesState*, const GedDesState*> stateMap;
	GedDesHelper m_desHelper;

	QMenu *stateContextMenu;
	QMenu *transContextMenu;

    Mode sceneMode;
	bool modified;
    bool leftButtonDown;
    QPointF startPoint;
    QGraphicsLineItem *line;
	QGraphicsRectItem *startRect;
    DiagramTextItem *textItem;
    QGraphicsSimpleTextItem* m_pMsg;
};
}
#endif
