//-*-c++-*-
#ifndef GLYPH_H
#define GLYPH_H

#include <tulip/Plugin.h>
#include <tulip/WithParameter.h>
#include <tulip/Size.h>
#include <tulip/Coord.h>
#include <tulip/Color.h>
#include "GlGraph.h"

class SuperGraph;
struct node;
//class GlGraph;

class GlyphContext
{
public:
  SuperGraph **superGraph;
  GlGraph *glGraph;
  int LOF, LOD;
  ///
  GlyphContext(SuperGraph **s=NULL, GlGraph *glGraph=NULL, int LOF=5, int LOD=5): superGraph(s), glGraph(glGraph),
									     LOF(LOF), LOD(LOD){}
  ///
  ~GlyphContext(){};
};

class Glyph : public WithParameter
{
protected:
  SuperGraph **superGraph;
  GlGraph *glGraph;
  int LOF; //Level Of Filter
  int LOD; //Level Of Detail
  void setMaterial(const Color &c);
  
public:
  Glyph(GlyphContext *);
  ///
  virtual ~Glyph();
  ///
  virtual std::string getName()=0;
  virtual void draw(node)=0;

  /*
   * return a point where an edge coming from "from" can be attached
   * by default, the point will be on the surface of the largest sphere contained
   * inside the unit cube (before scaling).
   */
  Coord getAnchor(const Coord &nodeCenter, const Coord &from, const Size &scale) const;
  
  void setLOF(int);
  int getLOF();

  virtual void setLOD(int);
  int getLOD();
  
private:
  /*
   * called by public method getAnchor to actually compute the anchor point
   * vector is coordinate of the point to anchor to, relative to nodecenter
   * glyph size is (1,1,1)
   * this is the method to redefine for each glyph where the default 'getAnchor' method
   * is inapropriated
   * Returned value is a vector to be applied to 'nodeCenter' in the public method
   */
  virtual Coord getAnchor(const Coord &vector) const;
};

class GlyphFactory: public Plugin
{
public:
  virtual ~GlyphFactory() {}
  ///
  virtual Glyph *createObject(GlyphContext *gc)=0;
};

#define PLUGINFACTORY(T,C,N,A,D,I,V,R)           \
class C##T##Factory:public T##Factory            \
{                                                \
public:                                          \
C##T##Factory(){}                                \
~C##T##Factory(){}                               \
string getName() const { return string(N);}      \
string getAuthor() const {return string(A);}     \
string getDate() const {return string(D);}       \
string getInfo() const {return string(I);}       \
string getRelease() const {return string(R);}    \
string getVersion() const {return string(V);}    \
T * createObject(GlyphContext *gc)               \
{                                                \
  C *tmp = new C(gc);                              \
  return ((T *) tmp);                            \
}                                                \
};                                               \
extern "C" {                                     \
  T##Factory* _creator()                         \
    {                                            \
      C##T##Factory *tmp = new C##T##Factory();  \
      return ((T##Factory *) tmp);               \
    }                                            \
};                                               \

#define GLYPHPLUGIN(C,N,A,D,I,V,R) PLUGINFACTORY(Glyph,C,N,A,D,I,V,R)

#endif //GLYPH_H
