// Vorosweep - Copyright (C) 2010-2014 T. Mouton
//
// See the LICENSE.txt file for license information. Please report all
// bugs and problems to <thibaud.mouton@gmail.com>.

#include "domain2d.h"

using namespace vorosweep;

Domain::Domain ( const char *filename )
{
  int error = 0;
  FILE *fp = fopen ( filename, "r" );
  if ( !fp )
  {
    printf ( "ERROR --> missing domain file %s\n", filename );
    exit ( 1 );
  }

  if ( fscanf ( fp, "%d", &nbpt ) != 1 )
    error++;

  nbseg = nbpt;

  p = new Point*[nbpt];

  for ( int i = 0; i < nbpt; i++ )
  {
    p[i] = new Point;
    double x, y;
    if ( fscanf ( fp, "%lf %lf", &x, &y ) != 2 )
      error++;
//     printf ( "--> %lf %lf\n", x, y );
    p[i]->set ( x, y, 0.0 );
  }
  fclose ( fp );

  bo = new Border*[nbseg];

  for ( int i = 0; i < nbseg; i++ )
    bo[i] = new Border ( p[i], p[ ( i+1 ) %nbseg] );

  for ( int i = 0; i < nbseg; i++ )
    bo[i]->set_adjs ( bo[ ( i+1 ) %nbseg], bo[ ( i+nbseg-1 ) %nbseg] );

//   for ( int i = 0; i < nbseg; i++ )
//     bo[i]->print();

  export_vtk();
}

Domain::~Domain()
{
  getchar();
  for ( int i = 0; i < nbpt; i++ )
    delete p[i];
  delete p;
}

// Shimrat's algorithm to know if a point is in the polygon of the domain
// Maybe too simple not to be buggy !!
bool Domain::point_in_domain ( double *pt )
{
  double infbound[2];
  infbound[0] = 1000.0;
  infbound[1] = pt[1];
  int nbinter = 0;
  
//   printf("pt --> %lf %lf\n", pt[0], pt[1]);

  for ( int i = 0; i < nbseg; i++ )
  {
    Border *bo = get_border ( i );
    double inter[2];
//     printf ( "border --> %lf %lf -- %lf %lf\n", bo->get_point ( 0 )->p[0], bo->get_point ( 0 )->p[1], bo->get_point ( 1 )->p[0], bo->get_point ( 1 )->p[1] );
    if ( geom::segments2d_intersection ( bo->get_point ( 0 )->p, bo->get_point ( 1 )->p, pt, infbound, 1e-16, inter )
      && geom::point_inside_segment2d ( bo->get_point ( 0 )->p, bo->get_point ( 1 )->p, 1e-16, inter )
      && geom::point_inside_segment2d ( pt, infbound, 1e-16, inter ) )
    {
//       dbgprintf ( 4, "inter --> %lf %lf\n", inter[0], inter[1] );
//       printf ( "inter --> %lf %lf\n", inter[0], inter[1] );
      nbinter++;
    }
  }
//   dbgprintf ( 4, "nb inter --> %d\n", nbinter );
//   printf ( "nb inter --> %d\n", nbinter );
  if ( nbinter % 2 == 1 )
    return true;
  return false;
}

void Domain::export_vtk ()
{
  char filename[100];
  sprintf ( filename, "domain.vtk" );
  dbgprintf ( 1, " write file --> %s\n", filename );

  FILE *fp_rw = fopen ( filename, "w" );

  fprintf ( fp_rw, "# vtk DataFile Version 2.0\n" );
  fprintf ( fp_rw, "Really cool data\n" );
  fprintf ( fp_rw, "ASCII\n" );
  fprintf ( fp_rw, "DATASET POLYDATA\n" );
  fprintf ( fp_rw, "POINTS %d float\n", nbpt );

  for ( int i = 0; i < nbpt; i++ )
    fprintf ( fp_rw, "%lf %lf %lf\n", p[i]->p[0], p[i]->p[1], 0.0 );

  fprintf ( fp_rw, "VERTICES %d %d\n", nbpt, nbpt+1 );
  fprintf ( fp_rw, "%d", nbpt );
  for ( int i = 0; i < nbpt; i++ )
    fprintf ( fp_rw, " %d", i );
  fprintf ( fp_rw, "\n" );

  fprintf ( fp_rw, "LINES %d %d\n", nbpt, 3*nbpt );
  for ( int i = 0; i < nbpt; i++ )
    fprintf ( fp_rw, "2 %d %d\n", i, ( i+1 ) %nbpt );

//   fprintf ( fp_rw, "POINT_DATA %d\n", nPts );
//   fprintf ( fp_rw, "SCALARS angle float 1\n" );
//   fprintf ( fp_rw, "LOOKUP_TABLE default\n" );
//   for ( int i = 0; i < nPts; i++ )
//     fprintf ( fp_rw, "%f\n", dataPts[i][2] );
  fclose ( fp_rw );
}

