/* 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_.h"

void
net_seed (struct IN In, int level, struct TESS Tess, int poly, struct SEEDSET *pGSet)
{
  struct TESS Cell;

  neut_tess_set_zero (&Cell);
  if (Tess.Dim == 3)
    neut_tess_poly_tess (Tess, poly, &Cell);
  else if (Tess.Dim == 1)
    neut_tess_tess (Tess, &Cell);

  // Initializing variables --------------------------------------------

  neut_seedset_free (pGSet);

  // Testing out input data --------------------------------------------

  // Regular distributions are only available for a cubic domain
  if ((!strcmp (In.morpho[Tess.Level + 1], "tocta")
       || !strcmp (In.morpho[Tess.Level + 1], "cube")
       || !strcmp (In.morpho[Tess.Level + 1], "dodeca"))
      && strncmp (In.domain, "cube", 4) != 0)
    ut_print_message
      (2, 0,
       "This morphology (%s) cannot be used with a non-cube domain (%s)\n",
       In.morpho[Tess.Level + 1], In.domain);

  if ((!strcmp (In.morpho[Tess.Level + 1], "square"))
      && (strncmp (In.domain, "cube", 4) != 0
       && strncmp (In.domain, "square", 6) != 0))
    ut_print_message
      (2, 0,
       "This morphology (%s) cannot be used with a non-cube domain (%s)\n",
       In.morpho[Tess.Level + 1], In.domain);

  // Setting up properties of the seedset (number of seeds, etc.) ------

  net_seed_prop (In, Tess, poly, pGSet);

  // Distributing seeds ------------------------------------------------

  if (!strcmp ((*pGSet).morpho, "lamella"))
    net_seed_seed (Tess.Level, poly, In.n[Tess.Level + 1] + 2, pGSet);
  else
    net_seed_seed (Tess.Level, poly, NULL, pGSet);

  // weights
  if (strcmp ((*pGSet).weight, "none") != 0)
    ut_print_message (0, 3, "Computing weights...\n");

  if (!strcmp ((*pGSet).weight, "none"))
    (*pGSet).SeedWeight = ut_alloc_1d ((*pGSet).N + 1);
  else if ((*pGSet).weight[0] == '@')
    net_seed_weight_custom ((*pGSet).weight + 1, pGSet);
  else
    net_seed_weight_rand (pGSet);

  if (strcmp ((*pGSet).weight, "none") != 0)
    ut_print_message (0, 3, "Computing positions...\n");

  // positions
  if (!strcmp ((*pGSet).morpho, "tocta") || !strcmp ((*pGSet).morpho, "cube")
   || !strcmp ((*pGSet).morpho, "square"))
    net_seed_reg (Cell, pGSet);
  else if ((*pGSet).morpho[0] == '@')
    net_seed_custom ((*pGSet).morpho + 1, In.dim, Cell, pGSet);
  else if (!strcmp ((*pGSet).morpho, "lamella"))
    net_seed_lam (In.n[Tess.Level + 1] + 2, Cell, pGSet);
  else
  {
    if (!strcmp ((*pGSet).weight, "none"))
      net_seed_rand (In, level, Cell, pGSet);
    else
      net_seed_lag (In, Cell, pGSet);
  }

  if (!(*pGSet).SeedWeight)
    (*pGSet).SeedWeight = ut_alloc_1d ((*pGSet).N + 1);

  // Distributing seeds outside the domain, if needed
  if (!strcmp (In.ttype, "periodic") || !strcmp (In.ttype, "subdomain"))
    net_seed_neigh (In, pGSet);

  // Randomize seed distribution ---------------------------------------

  if (In.randomizestring)
    net_seed_randomize (In, pGSet, Cell);

  // Computing orientations --------------------------------------------

  net_seed_ori (In, pGSet);

  // Free'ing memory ---------------------------------------------------

  neut_tess_free (&Cell);

  return;
}
