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

#define MAXV 1000

#define VERTEX 0
#define ISOLINE 1
#define VORFACE 2

#ifndef _vor_bitmap_include
#define _vor_bitmap_include

class VoronoiDiagramBitmap;

class Pixel
{
 public:
   int _closest;
   double _d;
   char bit_flag;
  
  public:
    Pixel()
    {
      _closest = -1;
      _d = INFINITY;
      bit_flag = 0x0;
    }
    void set_closest(int c, double d)
    {
      if (d <= _d)
        {
            _closest = c;
            _d = d;
        }
    }
   
    bool get_flag(int f)
    {
	return (bit_flag & (1 << f)) != 0;
    }
      
    void set_flag(int f, bool v)
    {
         bit_flag |= (1 << f);
    }
};

struct Vertex
{
  double p[2];
  double a;
  int flag;
};

class VoronoiDiagramBitmap
{
    Background *_bg;
    
    Pixel *_parray;
    Vertex _v[MAXV];    
    int nv;
    
    int _init;
    int _end;
    int _range_max;
    
    int nx, ny;
    double min[2];
    double max[2];    
    double dl;

public:
    VoronoiDiagramBitmap(double *vx, int nb_vx, double epsilon, int maxsize, Background *bg);
    ~VoronoiDiagramBitmap();
    
    Vertex *get_vertex(int i)
    {
      return _v+i;
    }
    
    int get_nb_vertex()
    {
      return nv;
    }
    
    Pixel *get_pixel(int i, int j)
    {
      return _parray+(i+j*nx);
    }
            
    void get_coord(int i, int j, double *coord)
    {
      coord[0] = min[0]+i*dl;
      coord[1] = min[1]+j*dl;
    }
    
    void set_bounds(int init, int end)
    {
      _init = init;
      _end = end;
      _range_max = _end - _init;
    }
    
    double distance(double *ref, double angle, double *p);
    void descent(double *ref, double angle, double *p, double *dir);
    
    void generate();
    void generate_func(int v0, int v1, int v2);
    void lloyd();
    
    void add_points(int point_size);
    void add_vorface();
    void add_isolines(double dist_inc, double linewidth);

    void export_vor_ppma();
    void export_function_ppma();
};

class progress_bar
{

protected:
    int _max;
    int _inc;
    int _last;

public:

    progress_bar()
    {
        _max = 100;
        _inc = 1;
        _last = 0;
    }
    progress_bar(int max)
    {
        _max = max;
        _inc = 1;
        _last = 0;
        if (_max > 100)
            _inc = floor((double)max/100.0);
    }

    inline void progress(int i)
    {
        if (i >=_last)
        {
            _last += _inc;
            printf("\033[M\033[A\033[M");
            int percent = (int)((double)i/(double)_max*100.0);
            printf("%d %% : ", percent);
            for (int j = 0; j < percent; j++)
                printf("#");
            printf("\n");
        }
    }
    inline void start()
    {
        printf("\n");
    }
    inline void start(int max)
    {
        _max = max;
        _inc = 1;
        _last = 0;
        if (_max > 100)
            _inc = floor((double)max/100.0);
        printf("\n");
    }
    inline double end()
    {
        printf("\033[M\033[A\033[M");
    }
};

#endif
