#ifndef BERGMAN_H_INCLUDED
#define BERGMAN_H_INCLUDED

#include "polynomial.h"
#include "printer.h"
#include "symmetry.h"
#include "polyhedralfan.h"

class BergmanFan
{
  bool simplicial;
 public:
  SymmetryGroup symmetryGroup;
  class CodimensionOneCone
    {
    public:
      list<int> incidenceList;
      IntegerVectorList incidencePermutationList;
      PolynomialSet idealGroebnerBasis;
      CodimensionOneCone(PolynomialSet const &idealGroebnerBasis_):
	idealGroebnerBasis(idealGroebnerBasis_)
	{
	}
    };
  class MaximalCone
  {
  public:
    int label;
    int numberOfFacets;
    PolynomialSet coneGroebnerBasis;
    PolynomialSet idealGroebnerBasis;
    MaximalCone(PolynomialSet const &coneGroebnerBasis_, PolynomialSet const &idealGroebnerBasis_, int label_, int numberOfFacets_=-1):
      coneGroebnerBasis(coneGroebnerBasis_),
      idealGroebnerBasis(idealGroebnerBasis_),
      label(label_),
      numberOfFacets(numberOfFacets_)
      {
      }
  };
  void print(Printer &p);
  bool contains(PolynomialSet const &g);
  typedef list<MaximalCone> MaximalConeList;
  typedef list<CodimensionOneCone> CodimensionOneConeList;

  BergmanFan():
    symmetryGroup(0),
    simplicial(false)
    {
    }
  MaximalConeList cones;
  CodimensionOneConeList codimensionOneCones;
  void setSymmetryGroup(SymmetryGroup const &s);
  PolyhedralFan toPolyhedralFan()const;
  int numberOfMaximalCones()const;
  void setSimplicial(bool b);
  bool isSimplicial()const;
};

BergmanFan bergmanRay(PolynomialSet const &idealGroebnerBasis);
BergmanFan bergman(PolynomialSet const &coneGroebnerBasis, PolynomialSet const &idealGroebnerBasis, SymmetryGroup const *symmetryGroup=0);

#endif
