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

void
nev_tessdata_init (struct TESS Tess, struct TESSDATA *pTessData)
{
  int dim, qty;
  double size, Rad1, Rad0, Rad4;

  neut_tess_size (Tess, &size);
  Rad1 = pow (size, 1./3) * 0.01414 / pow (Tess.CellQty, 0.25);
  Rad0 = pow (size, 1./3) * 0.02000 / pow (Tess.CellQty, 0.25);
  Rad4 = pow (size, 1./3) * 0.04000 / pow (Tess.CellQty, 0.25);

  for (dim = 0; dim <= 4; dim++)
  {
    neut_tessdata_dim_qty (*pTessData, dim, &qty);
    (*pTessData).Col[dim] = ut_alloc_2d_int (qty + 1, 3);
    (*pTessData).trs[dim] = ut_alloc_1d (qty + 1);
    (*pTessData).Rad[dim] = ut_alloc_1d (qty + 1);

    if (dim == 0)
    {
      ut_array_2d_int_set ((*pTessData).Col[dim] + 1, qty, 3, 0);
      ut_array_1d_set ((*pTessData).trs[dim] + 1, qty, 0);
      ut_array_1d_set ((*pTessData).Rad[dim] + 1, qty, Rad0);
    }
    else if (dim == 1)
    {
      ut_array_2d_int_set ((*pTessData).Col[dim] + 1, qty, 3, 0);
      ut_array_1d_set ((*pTessData).trs[dim] + 1, qty, 0);
      ut_array_1d_set ((*pTessData).Rad[dim] + 1, qty, Rad1);
    }
    else if (dim == 2 || dim == 3)
    {
      ut_array_2d_int_set ((*pTessData).Col[dim] + 1, qty, 3, 255);
      ut_array_1d_set ((*pTessData).trs[dim] + 1, qty, 0);
    }
    else if (dim == 4)
    {
      ut_array_2d_int_set ((*pTessData).Col[dim] + 1, qty, 3, 128);
      ut_array_1d_set ((*pTessData).trs[dim] + 1, qty, 0);
      ut_array_1d_set ((*pTessData).Rad[dim] + 1, qty, Rad4);
    }

    if ((*pTessData).ColData[dim])
    {
      if (!strcmp ((*pTessData).ColDataType[dim], "id"))
	nev_data_id_colour ((*pTessData).ColData[dim], qty,
			    (*pTessData).Col[dim]);
      else if (!strcmp ((*pTessData).ColDataType[dim], "col"))
	nev_data_col_colour ((*pTessData).ColData[dim], qty,
			     (*pTessData).Col[dim]);
      else if (!strncmp ((*pTessData).ColDataType[dim], "ori", 3))
	nev_data_ori_colour ((*pTessData).ColData[dim], qty,
			     "R", (*pTessData).Col[dim]);
      else if (!strcmp ((*pTessData).ColDataType[dim], "scal"))
	nev_data_scal_colour ((*pTessData).ColData[dim], qty,
			      (*pTessData).Scale[dim],
			      "blue,cyan,yellow,red",
			      (*pTessData).Col[dim],
			      &((*pTessData).Scale[dim]));
      else
	ut_error_reportbug ();
    }

    if ((*pTessData).trsdata[dim])
      nev_data_tr_tr ((*pTessData).trsdata[dim], qty,
	              (*pTessData).trs[dim]);

    if ((*pTessData).RadData[dim])
      nev_data_rad_radius ((*pTessData).RadData[dim], qty,
			   (*pTessData).Rad[dim]);
  }

  return;
}

void
nev_tessdata_fscanf (struct TESS Tess, char *entity, char *type,
		     char *argument, struct TESSDATA *pTessData)
{
  int id, i, qty;
  char* entity2 = ut_alloc_1d_char (10);

  strcpy (entity2, entity);
  if (!strcmp (entity, "cell"))
  {
    if ((*pTessData).PolyQty > 0)
      ut_string_string ("poly", &entity2);
    else if ((*pTessData).FaceQty > 0)
      ut_string_string ("face", &entity2);
    else if ((*pTessData).EdgeQty > 0)
      ut_string_string ("edge", &entity2);
    else
      ut_error_reportbug ();
  }

  ut_print_message (0, 1, "Reading data (%s, %s)...\n", entity2, type);

  neut_tessdata_entity_dim (entity2, &id);
  neut_tessdata_entity_qty (*pTessData, entity2, &qty);

  if (id < 0 || qty < 0)
    abort ();

  char **args = NULL;
  int argqty;
  ut_string_separate (argument, NEUT_SEP_DEP, &args, &argqty);

  if (!strcmp (type, "col"))
  {
    (*pTessData).ColDataType[id] = ut_alloc_1d_char (100);
    char *value = ut_alloc_1d_char (1000);

    nev_data_typearg_args ("col", argument, (*pTessData).ColDataType[id], value, NULL);

    if (!strcmp ((*pTessData).ColDataType[id], "col"))
    {
      (*pTessData).ColData[id] = ut_alloc_2d (qty + 1, 3);
      ut_array_2d_fscanfn_wcard (value, (*pTessData).ColData[id] + 1,
				 qty, 3, "colour,size");
    }
    else if (!strcmp ((*pTessData).ColDataType[id], "id"))
    {
      (*pTessData).ColData[id] = ut_alloc_2d (qty + 1, 1);
      for (i = 1; i <= qty; i++)
	(*pTessData).ColData[id][i][0] = Tess.CellId ? Tess.CellId[i] : i;
    }
    else if (!strncmp ((*pTessData).ColDataType[id], "ori", 3))
    {
      (*pTessData).ColData[id] = ut_alloc_2d (qty + 1, 4);

      if (strlen (value) == 0)
      {
	if (!Tess.CellOri)
	  ut_print_message (2, 3, "No orientation data available.\n");
	else
	{
	  ut_string_string ("oriq", &((*pTessData).ColDataType[id]));
	  ut_array_2d_memcpy ((*pTessData).ColData[id] + 1,
	      Tess.CellQty, 4,
			      Tess.CellOri + 1);
	}
      }
      else
      {
	int i;
	double *tmpd = ut_alloc_1d (4);
	int *tmpi = ut_alloc_1d_int (6);
	double **tmpdd = ut_alloc_2d (3, 3);
	FILE *file = ut_file_open (value, "r");

	int qty0;
	if (!strcmp ((*pTessData).ColDataType[id] + 3, "e")
	    || !strcmp ((*pTessData).ColDataType[id] + 3, "ek")
	    || !strcmp ((*pTessData).ColDataType[id] + 3, "er")
	    || !strcmp ((*pTessData).ColDataType[id] + 3, "R"))
	  qty0 = 3;
	else if (!strcmp ((*pTessData).ColDataType[id] + 3, "q"))
	  qty0 = 4;
	else if (!strcmp ((*pTessData).ColDataType[id] + 3, "m"))
	  qty0 = 6;
	else if (!strcmp ((*pTessData).ColDataType[id] + 3, "g"))
	  qty0 = 9;
	else
	{
	  printf ("(*pTessData).ColDataType[id] = %s\n",
		  (*pTessData).ColDataType[id]);
	  ut_error_reportbug ();
	  abort ();
	}

	ut_file_nbwords_testwmessage (value, qty * qty0);

	for (i = 1; i <= Tess.CellQty; i++)
	  if (!strcmp ((*pTessData).ColDataType[id] + 3, "e"))
	  {
	    ol_e_fscanf (file, tmpd);
	    ol_e_q (tmpd, (*pTessData).ColData[id][i]);
	  }
	  else if (!strcmp ((*pTessData).ColDataType[id] + 3, "ek"))
	  {
	    ol_e_fscanf (file, tmpd);
	    ol_ek_e (tmpd, tmpd);
	    ol_e_q (tmpd, (*pTessData).ColData[id][i]);
	  }
	  else if (!strcmp ((*pTessData).ColDataType[id] + 3, "er"))
	  {
	    ol_e_fscanf (file, tmpd);
	    ol_er_e (tmpd, tmpd);
	    ol_e_q (tmpd, (*pTessData).ColData[id][i]);
	  }
	  else if (!strcmp ((*pTessData).ColDataType[id] + 3, "q"))
	    ol_q_fscanf (file, (*pTessData).ColData[id][i]);
	  else if (!strcmp ((*pTessData).ColDataType[id] + 3, "R"))
	  {
	    ol_R_fscanf (file, tmpd);
	    ol_R_q (tmpd, (*pTessData).ColData[id][i]);
	  }
	  else if (!strcmp ((*pTessData).ColDataType[id] + 3, "m"))
	  {
	    ol_m_fscanf (file, tmpi);
	    ol_m_q (tmpi, (*pTessData).ColData[id][i]);
	  }
	  else if (!strcmp ((*pTessData).ColDataType[id] + 3, "g"))
	  {
	    ol_g_fscanf (file, tmpdd);
	    ol_g_q (tmpdd, (*pTessData).ColData[id][i]);
	  }
	  else
	    ut_error_reportbug ();
      }
    }
    else if (!strcmp ((*pTessData).ColDataType[id], "scal"))
    {
      (*pTessData).ColData[id] = ut_alloc_2d (qty + 1, 1);
      ut_array_2d_fscanfn_wcard (value, (*pTessData).ColData[id] + 1,
				 qty, 1, "numeral,size");
    }
    else
      abort ();

    ut_free_1d_char (value);
  }
  else if (!strcmp (type, "trs"))
  {
    (*pTessData).trsdatatype[id] = ut_alloc_1d_char (100);

    if (argqty == 1)
      strcpy ((*pTessData).trsdatatype[id], type);
    else
      strcpy ((*pTessData).trsdatatype[id], args[0]);

    if (!strcmp ((*pTessData).trsdatatype[id], "trs"))
    {
      (*pTessData).trsdata[id] = ut_alloc_2d (qty + 1, 3);
      ut_array_2d_fscanfn_wcard (args[0], (*pTessData).trsdata[id] + 1,
				 qty, 1, "numeral,size");
    }
    else if (!strcmp ((*pTessData).trsdatatype[id], "scal"))
    {
      (*pTessData).trsdata[id] = ut_alloc_2d (qty + 1, 3);
      ut_array_2d_fscanfn_wcard (args[0] + 5, (*pTessData).trsdata[id] + 1,
				 qty, 1, "numeral,size");
    }
    else
      abort ();
  }
  else if (!strcmp (type, "rad"))
  {
    (*pTessData).RadDataType[id] = ut_alloc_1d_char (100);

    if (argqty == 1)
      strcpy ((*pTessData).RadDataType[id], type);
    else
      strcpy ((*pTessData).RadDataType[id], args[0]);

    if (!strcmp ((*pTessData).RadDataType[id], "rad"))
    {
      (*pTessData).RadData[id] = ut_alloc_2d (qty + 1, 3);
      ut_array_2d_fscanfn_wcard (args[0], (*pTessData).RadData[id] + 1,
				 qty, 1, "numeral,size");
    }
    else
      abort ();
  }
  else if (!strcmp (type, "colscheme"))
  {
    (*pTessData).ColScheme[id] = ut_alloc_1d_char (100);
    strcpy ((*pTessData).ColScheme[id], argument);
  }
  else if (!strcmp (type, "scale"))
  {
    (*pTessData).Scale[id] = ut_alloc_1d_char (100);
    strcpy ((*pTessData).Scale[id], argument);
  }
  else if (!strcmp (type, "scaletitle"))
  {
    (*pTessData).ScaleTitle[id] = ut_alloc_1d_char (100);
    strcpy ((*pTessData).ScaleTitle[id], argument);
  }
  else
    ut_error_reportbug ();

  ut_free_2d_char (args, argqty);
  ut_free_1d_char (entity2);

  return;
}
