/* 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_seed_lag_.h"
#include<gsl/gsl_rng.h>

/* IniSeedCoo initializes the variable: SeedCoo */
void
net_seed_lag_coo (int dim, char *morpho, int N, int Random,
		  double **size, struct TESS Domain, double *SeedWeight,
		  double **SeedCoo)
{
  int i, j, id, iter, status;
  gsl_rng *r;
  int *seq = ut_alloc_1d_int (N + 1);

  ut_array_1d_sort_des_index (SeedWeight + 1, N, seq + 1);
  ut_array_1d_int_addval (seq + 1, N, 1, seq + 1);

  /* random number generator initialization */
  r = gsl_rng_alloc (gsl_rng_ranlxd2);
  gsl_rng_set (r, Random);

  // distributing seeds by descending weights (bigger is sonner).
  iter = 0;
  for (i = 1; i <= N; i++)
    do
    {
      id = seq[i];
      // don't change the below loop so as to keep 3 gsl_rng_uniform
      // calls per centre whatever the dimension is.
      for (j = 0; j < 3; j++)
	SeedCoo[id][j] =
	  size[j][0] + gsl_rng_uniform (r) * (size[j][1] - size[j][0]);

      // correcting the coordinates if needed --------------------------

      // morphology
      if (strcmp (morpho, "equiaxed") != 0 && strcmp (morpho, "poisson") != 0)
      {
	if (!strcmp (morpho, "columnar(x)"))
	  SeedCoo[id][0] = (size[0][0] + size[0][1]) / 2;
	else if (!strcmp (morpho, "columnar(y)"))
	  SeedCoo[id][1] = (size[1][0] + size[1][1]) / 2;
	else if (!strcmp (morpho, "columnar(z)"))
	  SeedCoo[id][2] = (size[2][0] + size[2][1]) / 2;
	else if (!strcmp (morpho, "bamboo(x)"))
	{
	  SeedCoo[id][1] = (size[1][0] + size[1][1]) / 2;
	  SeedCoo[id][2] = (size[2][0] + size[2][1]) / 2;
	}
	else if (!strcmp (morpho, "bamboo(y)"))
	{
	  SeedCoo[id][2] = (size[2][0] + size[2][1]) / 2;
	  SeedCoo[id][0] = (size[0][0] + size[0][1]) / 2;
	}
	else if (!strcmp (morpho, "bamboo(z)"))
	{
	  SeedCoo[id][0] = (size[0][0] + size[0][1]) / 2;
	  SeedCoo[id][1] = (size[1][0] + size[1][1]) / 2;
	}
      }

      // dimension 
      for (j = dim; j < 3; j++)
	SeedCoo[id][j] = 1e-6 * size[j][1];

      status = 0;
      // checking that the point is in the domain
      if (neut_tess_point_incell (Domain, SeedCoo[id], 1) != 1)
	status = -1;

      if (status == 0)
	for (j = 1; j < i; j++)
	  if (ut_space_dist (SeedCoo[id], SeedCoo[seq[j]])
	      < SeedWeight[id] + SeedWeight[seq[j]])
	  {
	    status = -1;
	    break;
	  }

      if (++iter > 10000)
	ut_print_message (2, 4,
			  "Cannot find positions compatible with the weights... (stopping at %d/%d seeds)\n",
			  i, N);

      if (status == 0)
	iter = 0;
    }
    while (status != 0);

  gsl_rng_free (r);
  ut_free_1d_int (seq);

  return;
}
