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

void
nev_meshdata_fscanf_elt (struct MESH Mesh, struct MESHDATA* pMD,
                         char* type, char* argument, int elset)
{
  if (!strcmp (type, "col"))
  {
    (*pMD).ColDataType = ut_alloc_1d_char (100);

    if (!strcmp (argument, "from_nodes"))
    {
      strcpy ((*pMD).ColDataType, argument);
      return;
    }

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

    int i;
    char *value = ut_alloc_1d_char (1000);
    nev_data_typearg_args ("col", argument, (*pMD).ColDataType, value,
			   NULL);

    if (!strcmp ((*pMD).ColDataType, "id"))
    {
      (*pMD).ColData = ut_alloc_2d ((*pMD).EltQty + 1, 3);

      for (i = 1; i <= (*pMD).EltQty; i++)
      {
	if (elset == 0)
	  (*pMD).ColData[i][0] = i;
	else
	  (*pMD).ColData[i][0] = Mesh.ElsetId ? Mesh.ElsetId[i] : i;
      }
    }
    else if (!strcmp ((*pMD).ColDataType, "col"))
    {
      (*pMD).ColData = ut_alloc_2d ((*pMD).EltQty + 1, 3);
      ut_array_2d_fscanfn_wcard (value, (*pMD).ColData + 1,
				 (*pMD).EltQty, 3, "colour,size");
    }
    else if (!strncmp ((*pMD).ColDataType, "ori", 3))
    {
      (*pMD).ColData = ut_alloc_2d ((*pMD).EltQty + 1, 4);
      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;
      neut_meshdata_coldatatype_size (*pMD, &qty0);

      ut_file_nbwords_testwmessage (value, (*pMD).EltQty * qty0);

      for (i = 1; i <= (*pMD).EltQty; i++)
	if (!strcmp ((*pMD).ColDataType + 3, "e"))
	{
	  ol_e_fscanf (file, tmpd);
	  ol_e_q (tmpd, (*pMD).ColData[i]);
	}
	else if (!strcmp ((*pMD).ColDataType + 3, "ek"))
	{
	  ol_e_fscanf (file, tmpd);
	  ol_ek_e (tmpd, tmpd);
	  ol_e_q (tmpd, (*pMD).ColData[i]);
	}
	else if (!strcmp ((*pMD).ColDataType + 3, "er"))
	{
	  ol_e_fscanf (file, tmpd);
	  ol_er_e (tmpd, tmpd);
	  ol_e_q (tmpd, (*pMD).ColData[i]);
	}
	else if (!strcmp ((*pMD).ColDataType + 3, "q"))
	  ol_q_fscanf (file, (*pMD).ColData[i]);
	else if (!strcmp ((*pMD).ColDataType + 3, "R"))
	{
	  ol_R_fscanf (file, tmpd);
	  ol_R_q (tmpd, (*pMD).ColData[i]);
	}
	else if (!strcmp ((*pMD).ColDataType + 3, "m"))
	{
	  ol_m_fscanf (file, tmpi);
	  ol_m_q (tmpi, (*pMD).ColData[i]);
	}
	else if (!strcmp ((*pMD).ColDataType + 3, "g"))
	{
	  ol_g_fscanf (file, tmpdd);
	  ol_g_q (tmpdd, (*pMD).ColData[i]);
	}
	else
	  ut_error_reportbug ();

      ut_string_string ("oriq", &((*pMD).ColDataType));
    }
    else if (!strcmp ((*pMD).ColDataType, "scal"))
    {
      (*pMD).ColData = ut_alloc_2d ((*pMD).EltQty + 1, 1);
      ut_array_2d_fscanfn_wcard (value, (*pMD).ColData + 1,
				 (*pMD).EltQty, 1, "numeral,size");
    }
    else
      abort ();

    ut_free_2d_char (args, argqty);
    ut_free_1d_char (value);
  }
  else if (!strcmp (type, "rad"))
  {
    (*pMD).RadDataType = ut_alloc_1d_char (100);
    strcpy ((*pMD).RadDataType, type);

    (*pMD).RadData = ut_alloc_2d ((*pMD).EltQty + 1, 1);
    ut_array_2d_fscanfn_wcard (argument, (*pMD).RadData + 1,
				 (*pMD).EltQty, 1, "numeral,size");
  }
  else if (!strcmp (type, "colscheme"))
  {
    (*pMD).ColScheme = ut_alloc_1d_char (strlen (argument) + 1);
    strcpy ((*pMD).ColScheme, argument);
  }
  else if (!strcmp (type, "scale"))
  {
    (*pMD).Scale = ut_alloc_1d_char (strlen (argument) + 1);
    strcpy ((*pMD).Scale, argument);
  }
  else if (!strcmp (type, "scaletitle"))
  {
    (*pMD).ScaleTitle = ut_alloc_1d_char (strlen (argument) + 1);
    strcpy ((*pMD).ScaleTitle, argument);
  }
  else
    ut_error_reportbug ();

  return;
}

void
nev_meshdata_fscanf_eltb (struct MESHDATA* pMD,
                          char* type, char* argument)
{
  if (!strcmp (type, "col"))
  {
    (*pMD).BCol = ut_alloc_1d_int (3);
    ut_array_1d_int_fscanfn_wcard (argument, (*pMD).BCol, 3, "colour");
  }
  else if (!strcmp (type, "rad"))
    ut_array_1d_fscanfn_wcard (argument, &((*pMD).BRad), 1, "numeral");
  else
    ut_error_reportbug ();

  return;
}

void
nev_meshdata_elset2elt (struct MESH Mesh,
                        char* entity, char* type,
                        struct MESHDATA MeshDataSet,
			struct MESHDATA* pMD)
{
  int i, j, size;
  
  if (entity[strlen (entity) - 1] != 'b')
  {
    if (!strcmp (type, "col"))
    {
      (*pMD).ColDataType
	= ut_alloc_1d_char (strlen (MeshDataSet.ColDataType) + 1);
      strcpy ((*pMD).ColDataType, MeshDataSet.ColDataType);

      size = -1;
      if (!strcmp ((*pMD).ColDataType, "id"))
	size = 1;
      else if (!strcmp ((*pMD).ColDataType, "col")
            || !strncmp ((*pMD).ColDataType, "ori", 3))
	size = 4;
      else if (!strcmp ((*pMD).ColDataType, "rad"))
	size = 1;
      else if (!strcmp ((*pMD).ColDataType, "scal"))
	size = 1;
      else
	abort ();

      (*pMD).ColData = ut_alloc_2d ((*pMD).EltQty + 1, size);
      for (i = 1; i <= Mesh.ElsetQty; i++)
	for (j = 1; j <= Mesh.Elsets[i][0]; j++)
	  ut_array_1d_memcpy ((*pMD).ColData[Mesh.Elsets[i][j]],
			      size, MeshDataSet.ColData[i]);
    }
    else if (!strcmp (type, "rad"))
    {
      (*pMD).RadDataType
	= ut_alloc_1d_char (strlen (MeshDataSet.RadDataType + 1));
      strcpy ((*pMD).RadDataType, MeshDataSet.RadDataType);

      (*pMD).RadData = ut_alloc_2d ((*pMD).EltQty + 1, 1);
      for (i = 1; i <= Mesh.ElsetQty; i++)
	for (j = 1; j <= Mesh.Elsets[i][0]; j++)
	  (*pMD).RadData[Mesh.Elsets[i][j]] = MeshDataSet.ColData[i];
    }
    else if (!strcmp (type, "colscheme"))
    {
      (*pMD).ColScheme = ut_alloc_1d_char (strlen (MeshDataSet.ColScheme) + 1);
      strcpy ((*pMD).ColScheme, MeshDataSet.ColScheme);
    }
    else if (!strcmp (type, "scale"))
    {
      (*pMD).Scale
	= ut_alloc_1d_char (strlen (MeshDataSet.Scale) + 1);
      strcpy ((*pMD).Scale, MeshDataSet.Scale);
    }
    else if (!strcmp (type, "scaletitle"))
    {
      (*pMD).ScaleTitle
	= ut_alloc_1d_char (strlen (MeshDataSet.ScaleTitle) + 1);
      strcpy ((*pMD).ScaleTitle, MeshDataSet.ScaleTitle);
    }
    else
      ut_error_reportbug ();
  }
  else
  {
    if (!strcmp (type, "col"))
    {
      (*pMD).BCol = ut_alloc_1d_int (3);
      ut_array_1d_int_memcpy ((*pMD).BCol, 3, MeshDataSet.BCol);
    }
    else if (!strcmp (type, "rad"))
      (*pMD).BRad = MeshDataSet.BRad;
    else
      ut_error_reportbug ();
  }

  return;
}
