/* This file is part of the Neper software package. */
/* Copyright (C) 2003-2014, Romain Quey. */
/* See the COPYING file in the top-level directory. */

#include "net_tess_.h"

int
net_tess_standard (int dim, struct TESS PTess, int cell, struct SEEDSET
		   SeedSet, int TessId, struct TESS *pTess)
{
  if (dim == 1)
    net_tess1d (PTess, cell, SeedSet, TessId, pTess);
  else if (dim == 2)
    net_tess2d (PTess, cell, SeedSet, TessId, pTess, SeedSet.N >= 3000);
  else if (dim == 3)
    net_tess3d (PTess, cell, SeedSet, TessId, pTess, SeedSet.N >= 3000);
  else
    ut_error_reportbug ();

  return 0;
}

int
net_tess_centroid (int dim, struct IN In, struct TESS PTess, int cell,
		   struct SEEDSET *pSeedSet, int TessId,
		   struct TESS *pTess)
{
  int status, iter;
  double rdistmax = -1;
  char *prevmessage = ut_alloc_1d_char (1000);
  char *message = ut_alloc_1d_char (1000);
  double** coo = ut_alloc_2d ((*pSeedSet).N + 1, 3);

  status = -1;
  for (iter = 1; status != 0 && iter <= In.centroiditermax; iter++)
  {
    // updating seed coos
    if (iter > 1)
      net_tess_centroid_seedupdate (*pTess, coo, In.centroidfact, pSeedSet);

    if (dim == 1)
      net_tess1d (PTess, cell, *pSeedSet, TessId, pTess);
    else if (dim == 2)
      net_tess2d (PTess, cell, *pSeedSet, TessId, pTess, 0);
    else if (dim == 3)
      net_tess3d (PTess, cell, *pSeedSet, TessId, pTess, 0);

    net_tess_centroid_coo (*pTess, coo);

    status = net_tess_centroid_test ((*pSeedSet).Dim, *pTess, coo, In.centroidconv, &rdistmax);

    sprintf (message, "iter=%d, dist=%.3g", iter, rdistmax);
    ut_print_progress (stdout, 0, 1, message, prevmessage);
  }

  ut_free_2d (coo, (*pSeedSet).N + 1);
  ut_free_1d_char (prevmessage);
  ut_free_1d_char (message);

  return 0;
}

int
net_tess_cells (struct SEEDSET GSet, struct TESS *pTess)
{
  if (!strcmp (GSet.morpho, "square")
   || !strcmp (GSet.morpho, "cube")
   || !strcmp (GSet.morpho, "tocta"))
  {
    int i;
    double* randval = ut_alloc_1d (GSet.N + 1);
    gsl_rng *r;

    r = gsl_rng_alloc (gsl_rng_ranlxd2);
    gsl_rng_set (r, GSet.Random);

    randval = ut_alloc_1d (GSet.N);
    for (i = 0; i < GSet.N; i++)
      randval[i] = gsl_rng_uniform (r);

    (*pTess).CellId = ut_alloc_1d_int (GSet.N + 1);
    ut_array_1d_sort_index (randval, GSet.N, (*pTess).CellId + 1);
    ut_array_1d_int_addval ((*pTess).CellId + 1, GSet.N, 1, (*pTess).CellId + 1);

    ut_free_1d (randval);
    gsl_rng_free (r);
  }

  (*pTess).CellOri = ut_alloc_2d ((*pTess).CellQty + 1, 4);
  ut_array_2d_memcpy ((*pTess).CellOri + 1, (*pTess).CellQty, 4,
		      GSet.q + 1);

  return 0;
}
