/**
 * @file DagStructure.hpp
 *
 * Created on 2010/05/25 by Anthony Nemoff
 * Last update 2010/07/27 by Anthony Nemoff
 *
 */

#ifndef DAGSTRUCTURE_HPP
#define DAGSTRUCTURE_HPP

#include "../Common.hpp"

#define DDV_GVFONT "Monospace" // declare system dependent fonts or default fonts in a file

/**
 * Class representing the graph structure using Graphviz containers.
 */
class DagStructure {

public:

  /* The libgraph API function calls requires "char *" parameters when only
   * "const char *" are needed, resulting in compilation warnings. To avoid
   * this we create some wrappers methods.
   *
   *  See : http://mupuf.org/blog/article/34/
   */

  /** The agopen method for opening a graph */
  static inline Agraph_t* _agopen(QString graphName, int graphKind) {
      return agopen(const_cast<char *>(qPrintable(graphName)), graphKind);
  }

  /** Add an alternative value parameter to the method for getting an object's attribute */
  static inline QString _agget(void *object, QString attr, QString alt = QString()) {
      QString str = agget(object, const_cast<char *>(qPrintable(attr)));

      if(str == QString())
          return alt;
      else
          return str;
  }

  /** Directly use agsafeset which always works, contrarily to agset */
  static inline int _agset(void *object, QString attrName, QString attrValue) {
      return agsafeset(object, const_cast<char *>(qPrintable(attrName)),
                       const_cast<char *>(qPrintable(attrValue)),
                       const_cast<char *>(qPrintable(attrValue)));
  }


  // Default constructor : does nothing.
  DagStructure();

  // Constructor
  DagStructure(QString graphName, int numberOfNodes, int numberOfEdges, GVC_t *gvContext);

  //Destructor
  ~DagStructure();


  // Getters & setters

  QString getGraphName() const;

  void setGraphName(QString _name);

  int getNumberOfNodes() const;

  void setNumberOfNodes(int _nodes);

  int getNumberOfEdges() const;

  void setNumberOfEdges(int _edges);

  void setLength(int length);

  int getLength() const;

  Agraph_t* getGraph();

  Agnode_t* getGVNodeAt(int i);

  Agedge_t* getGVEdgeAt(int i);


  // Methods

  void addNode(int nodeIndex, QString nodeName);

  void addEdge(int startNodeIndex, int endNodeIndex, int edgeIndex);

  void calculateLayout(QString layoutAlgorithm);

  void freeGraphLayout();

  void renderTofile(QString format, QString fileName);


private:

  // Members

  Agraph_t *_graph; /**< Graphviz graph structure */
  GVC_t *_graphvizContext; /**< Graphviz context */

  QList<Agnode_t*> _nodeList; /**< Nodes list */
  QList<Agedge_t*> _edgeList; /**< Edges list */

  QString _graphName; /**< Graph name as a string */
  int _numberOfNodes; /**< Number of nodes */
  int _numberOfEdges; /**< Number of edges */
  int _length; /**< Max length of the graph */

  bool _layoutDone; /**< Tells wether the graph has been layout or not */
  // TODO store current layout and compare if layout is called again
  // TODO vecteurs des format de sortie supportés
  // TODO vecteurs des layouts supportés + label "parlant"


};

#endif // DAGSTRUCTURE_HPP
