#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include "geom.h"
#include "tri.h"
#include "background.h"
#include <vector>
#include <map>
#include <iterator>

#ifndef _vor_include
#define _vor_include

class VoronoiDiagram;
class VoronoiCell;

class VoronoiCell
{
 public:
   Vertex *_center;
   Vertex *_centroid;
  std::vector<int> _vlist;
  double _inertia_moment;
  
  public:
    VoronoiCell(Vertex *c)
    {
      _center = c;
      _centroid = new Vertex;
      _centroid->p[0] = 0.0;
      _centroid->p[1] = 0.0;
      _inertia_moment = 0.0;
    }
    void add_vertex(int v)
    {
      _vlist.push_back(v);
    }
};

class VoronoiDiagram
{
    std::vector<Vertex *> _vertices;
    std::vector<VoronoiCell *> _cells;
//     std::map<Vertex *, int> _vertex_index;
    std::map<Vertex*, int>::iterator _itvi;
    std::map<Triangle *, Vertex*> _voronoi_vertices;
    std::map<Triangle *, Vertex*>::iterator _itvv;
    std::map<std::pair<int, int>, std::pair<Vertex*, Vertex*> > _edge_map;
    std::map<std::pair<int, int>, std::pair<Vertex*, Vertex*> >::iterator _item;
    double _angle;
    Triangulation *_tri;
    Background *_bg;

public:
    VoronoiDiagram(Triangulation *tri, Background *bg);
    ~VoronoiDiagram();
    int add_vertex(Vertex *v)
    {
//         _vertex_index.insert(std::pair<Vertex *, int>(v, _vertices.size()));
	v->flag = _vertices.size();
        _vertices.push_back(v);
	return _vertices.size()-1;
    }
    Vertex *get_vertex(int i)
    {
	assert(i < _vertices.size());
        return _vertices[i];
    }
    int add_cell(VoronoiCell *vc)
    {
      _cells.push_back(vc);
    }
    VoronoiCell *get_cell(int i)
    {
        assert(i < _cells.size());
        return _cells[i];
    }
    void set_angle(double angle)
    {
        _angle = angle;
    }
    double get_angle()
    {
        return _angle;
    }
    int get_voronoi_vertex(Triangle *t)
    {
//         return _vertex_index.find(_voronoi_vertices.find(t)->second)->second;
	  return _voronoi_vertices.find(t)->second->flag;
    }
    int add_voronoi_vertex(Triangle *t);
    int add_edge(int ev0, int ev1, Vertex *pv0, Vertex *pv1, int *v0, int *v1);
    int get_edge(Triangulation* tri, Triangle *t0, int adj, int *vi0, int *vi1);
    void build_face(Triangulation* tri, Triangle *t0, int adj, int *v0, int *v1);
    void compute_centroid();
    void print();
    void export_vtk();
};

#endif
