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

#include"nev_camera_.h"

void
nev_camera_tess_alpha (struct TESS Tess, double *palpha)
{
  int i;
  double **bbox = ut_alloc_2d (3, 2);

  neut_tess_bbox (Tess, bbox);

  (*palpha) = -DBL_MAX;
  for (i = 0; i < 3; i++)
    (*palpha) = ut_num_max (*palpha, bbox[i][1] - bbox[i][0]);

  ut_free_2d (bbox, 3);

  return;
}

void
nev_camera_tesr_alpha (struct TESR Tesr, double *palpha)
{
  int i;
  double **bbox = ut_alloc_2d (3, 2);

  neut_tesr_bbox (Tesr, bbox);

  (*palpha) = -DBL_MAX;
  for (i = 0; i < 3; i++)
    (*palpha) = ut_num_max (*palpha, bbox[i][1] - bbox[i][0]);

  ut_free_2d (bbox, 3);

  return;
}

void
nev_camera_mesh_alpha (struct NODES Nodes, double *palpha)
{
  int i;
  double **bbox = ut_alloc_2d (3, 2);

  neut_nodes_bbox (Nodes, bbox);

  (*palpha) = -DBL_MAX;
  for (i = 0; i < 3; i++)
    (*palpha) = ut_num_max (*palpha, bbox[i][1] - bbox[i][0]);

  ut_free_2d (bbox, 3);

  return;
}

void
nev_camera_point_alpha (struct POINT Point, double *palpha)
{
  int i;
  double **bbox = ut_alloc_2d (3, 2);

  neut_point_bbox (Point, bbox);

  (*palpha) = -DBL_MAX;
  for (i = 0; i < 3; i++)
    (*palpha) = ut_num_max (*palpha, bbox[i][1] - bbox[i][0]);

  ut_free_2d (bbox, 3);

  return;
}

void
nev_camera_v (int dim, double *v)
{
  if (dim >= 0 && dim <= 2)
  {
    v[0] = 0;
    v[1] = 0;
    v[2] = 8;
  }

  else if (dim == 3)
  {
    v[0] = 3.462;
    v[1] = -5.770;
    v[2] = 4.327;
  }

  else
    ut_error_reportbug ();

  return;
}

void
nev_camera_expr_coo (double *X, double alpha, double *v, char *expr, double *coo)
{
  char **expr2 = NULL;
  char **def = ut_alloc_2d_char (4, 100);
  int i, status, var_qty, qty;
  ut_string_separate (expr, NEUT_SEP_DEP, &expr2, &qty);
  if (qty != 3)
    ut_print_message (2, 2, "Expression `%s' could not be processed.\n",
		      expr);

  var_qty = 3;
  char **vars = ut_alloc_2d_char (var_qty, 15);
  double *vals = ut_alloc_1d (var_qty);

  for (i = 0; i < 3; i++)
  {
    sprintf (vars[0], "%c", 'x' + i);
    sprintf (vars[1], "alpha");
    sprintf (vars[2], "v%c", 'x' + i);

    vals[0] = X[i];
    vals[1] = alpha;
    vals[2] = v[i];

    sprintf (def[0], "%s", vars[0]);
    sprintf (def[1], "%s", vars[2]);
    sprintf (def[2], "%s+%s", vars[0], vars[2]);
    sprintf (def[3], "%s+%s*%s", vars[0], vars[1], vars[2]);

    if (!strcmp (expr2[i], def[0]))
      coo[i] = vals[0];
    else if (!strcmp (expr2[i], def[1]))
      coo[i] = vals[2];
    else if (!strcmp (expr2[i], def[2]))
      coo[i] = vals[0] + vals[2];
    else if (!strcmp (expr2[i], def[3]))
      coo[i] = vals[0] + vals[1] * vals[2];
    else
    {
      status = ut_math_eval (expr2[i], var_qty, vars, vals, &(coo[i]));
      if (status == -1)
	abort ();
    }
  }

  ut_free_2d_char (vars, var_qty);
  ut_free_1d (vals);
  ut_free_2d_char (def, 3);

  return;
}
