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

void
neut_point_set_zero (struct POINT *pPoint)
{
  (*pPoint).Dim = 0;
  (*pPoint).PointQty = 0;
  (*pPoint).PointCoo = NULL;

  return;
}

void
neut_point_free (struct POINT *pPoint)
{
  if ((*pPoint).PointCoo)
    ut_free_2d ((*pPoint).PointCoo, (*pPoint).PointQty + 1);
  (*pPoint).PointCoo = NULL;

  (*pPoint).PointQty = 0;
  (*pPoint).Dim = 0;

  return;
}

void
neut_point_centre (struct POINT Point, double* centre)
{
  int i;

  ut_array_1d_zero (centre, 3);

  for (i = 1; i <= Point.PointQty; i++)
    ut_array_1d_add (centre, Point.PointCoo[i], 3, centre);

  ut_array_1d_scale (centre, 3, 1. / Point.PointQty);

  return;
}

void
neut_point_var_list (char ***pvar, int *pvarqty)
{
  int id = 0;

  (*pvarqty) = 6;
  (*pvar) = ut_alloc_2d_char (*pvarqty, 20);
  strcpy ((*pvar)[id++], "id");
  strcpy ((*pvar)[id++], "x");
  strcpy ((*pvar)[id++], "y");
  strcpy ((*pvar)[id++], "z");
  strcpy ((*pvar)[id++], "poly");
  strcpy ((*pvar)[id++], "cell");

  return;
}

void
neut_point_var_list_mesh (char ***pvar, int *pvarqty)
{
  int id = 0;

  (*pvarqty) = 10;
  (*pvar) = ut_alloc_2d_char (*pvarqty, 20);
  strcpy ((*pvar)[id++], "id");
  strcpy ((*pvar)[id++], "x");
  strcpy ((*pvar)[id++], "y");
  strcpy ((*pvar)[id++], "z");
  strcpy ((*pvar)[id++], "elt3d");
  strcpy ((*pvar)[id++], "elset3d");
  strcpy ((*pvar)[id++], "2dmeshp");
  strcpy ((*pvar)[id++], "2dmeshd");
  strcpy ((*pvar)[id++], "2dmeshv");
  strcpy ((*pvar)[id++], "2dmeshn");

  return;
}

int
neut_point_var_val (struct POINT Point, int id, struct TESS Tess,
		    struct NODES Nodes, struct MESH Mesh,
		    char *var, double *pval, char **ptype)
{
  int i, status, tmp;

  (*ptype) = ut_alloc_1d_char (10);

  status = 0;
  if (!strcmp (var, "id"))
  {
    (*pval) = id;
    strcpy (*ptype, "%d");
  }
  else if (!strcmp (var, "x"))
  {
    (*pval) = Point.PointCoo[id][0];
    strcpy (*ptype, "%f");
  }
  else if (!strcmp (var, "y"))
  {
    (*pval) = Point.PointCoo[id][1];
    strcpy (*ptype, "%f");
  }
  else if (!strcmp (var, "z"))
  {
    (*pval) = Point.PointCoo[id][2];
    strcpy (*ptype, "%f");
  }
  else if (!strcmp (var, "poly") || !strcmp (var, "cell"))
  {
    (*pval) = -1;
    for (i = 1; i <= Tess.PolyQty; i++)
      if (neut_tess_point_inpoly (Tess, Point.PointCoo[id], i) == 1)
      {
	(*pval) = i;
	break;
      }
    strcpy (*ptype, "%d");
  }
  else if (!strcmp (var, "elt3d"))
  {
    neut_mesh_point_elt (Mesh, Nodes, Point.PointCoo[id], &tmp);
    (*pval) = tmp;
    strcpy (*ptype, "%d");
  }
  else if (!strcmp (var, "elset3d"))
  {
    neut_mesh_point_elset (Mesh, Nodes, Point.PointCoo[id], &tmp);
    (*pval) = tmp;
    strcpy (*ptype, "%d");
  }
  else
    status = -1;

  return status;
}
