/*--------------------------------------------------------------------------*/
/* ALBERTA:  an Adaptive multi Level finite element toolbox using           */
/*           Bisectioning refinement and Error control by Residual          */
/*           Techniques for scientific Applications                         */
/*--------------------------------------------------------------------------*/
/*                                                                          */
/* file: write_mesh_fig.c                                                   */
/*                                                                          */
/*                                                                          */
/* description: This program converts ALBERTA meshes                        */
/*              into the fig format, version 3.2                            */
/*--------------------------------------------------------------------------*/
/*                                                                          */
/*  authors:   Daniel Koester                                               */
/*             Institut fuer Mathematik                                     */
/*             Universitaet Augsburg                                        */
/*             Universitaetsstr. 14                                         */
/*             D-86159 Augsburg, Germany                                    */
/*                                                                          */
/*  http://www.alberta-fem.de                                               */
/*                                                                          */
/*  (c) by D. Koester (2006)                                                */
/*--------------------------------------------------------------------------*/

#include "alberta.h"

/***************************************************************************/
/* User interface                                                          */
/***************************************************************************/

/***************************************************************************/
/* write_mesh_fig():                                                       */
/* Write 2d meshes (parametric or standard) as Xfig objects.               */
/*                                                                         */
/* Return value is 0 for OK and 1 for ERROR.                               */
/***************************************************************************/

int write_mesh_fig(MESH *mesh, const char *file_name)
{
  FUNCNAME("write_mesh_fig");
  FILE             *file = NULL;
  TRAVERSE_STACK   *stack;
  const EL_INFO    *el_info;
  const PARAMETRIC *parametric;
  int               is_parametric, i, n;
  const double      factor = 1000.0;

  if(!mesh) {
    ERROR("no mesh - no file created!\n");
    return(1);
  }

  TEST_EXIT(mesh->dim == 2, "Only for 2d!\n");
  TEST_EXIT(DIM_OF_WORLD == 2, "Only for DIM_OF_WORLD==2!\n");

  file = fopen(file_name, "w");

  if(!file) {
    ERROR("cannot open file %s\n",file_name);
    return(1);
  }

  /* Write file header. */

  fprintf(file, "#FIG 3.2\n");
  fprintf(file, "Portrait\n");
  fprintf(file, "Center\n");
  fprintf(file, "Metric\n");
  fprintf(file, "A4\n");
  fprintf(file, "100.00\n");
  fprintf(file, "Single\n");
  fprintf(file, "-2\n");
  fprintf(file, "# Created with ALBERTA using write_mesh_fig().\n");
  fprintf(file, "1200 2\n");

  /* Define user defined color number 32 to be a nice gray. */
  fprintf(file, "0 32 #a0a0a0\n");

  /* Now dump the elements as polylines. */
  
  parametric = mesh->parametric;

  stack = get_traverse_stack();
  for(el_info = traverse_first(stack, mesh, -1, FILL_COORDS|CALL_LEAF_EL);
      el_info;
      el_info = traverse_next(stack, el_info)) {
     
    if(parametric) {
      REAL_D coords[6];
      const REAL_B lambdas[6] = {INIT_BARY_2D(1.0, 0.0, 0.0),
				 INIT_BARY_2D(0.5, 0.5, 0.0),
				 INIT_BARY_2D(0.0, 1.0, 0.0),
				 INIT_BARY_2D(0.0, 0.5, 0.5),
				 INIT_BARY_2D(0.0, 0.0, 1.0),
				 INIT_BARY_2D(0.5, 0.0, 0.5)};

      is_parametric = parametric->init_element(el_info, parametric);
      parametric->coord_to_world(el_info, NULL, 6, lambdas, coords);

      if(is_parametric) {
	/* Write a filled X-spline */
	fprintf(file, "3 5 0 1 -1 32 50 -1 20 0.000 0 0  0 7\n\t");

	for(i = 0; i < 6; i++)
	  for(n = 0; n < DIM_OF_WORLD; n++)
	    fprintf(file, "%d ", (int)(coords[i][n] * factor));
	for(n = 0; n < DIM_OF_WORLD; n++)
	  fprintf(file, "%d ", (int)(coords[0][n] * factor));

	fprintf(file, "\n");
	fprintf(file, "\t0 -1 0 -1 0 -1 0\n");
      }
      else {
      /* Write an unfilled polygon */
	fprintf(file, "2 3 0 1 -1 0 50 -1 -1 0.000 0 0 -1 0 0 4\n\t");
	
	for(i = 0; i < 3; i++)
	  for(n = 0; n < DIM_OF_WORLD; n++)
	    fprintf(file, "%d ", (int)(coords[i*2][n] * factor));
	for(n = 0; n < DIM_OF_WORLD; n++)
	  fprintf(file, "%d ", (int)(coords[0][n] * factor));
	
	fprintf(file, "\n");
      }
    }
    else {
      /* Write an unfilled polygon */
      fprintf(file, "2 3 0 1 -1 0 50 -1 -1 0.000 0 0 -1 0 0 4\n\t");

      for(i = 0; i < 3; i++)
	for(n = 0; n < DIM_OF_WORLD; n++)
	  fprintf(file, "%d ", (int)(el_info->coord[i][n] * factor));
      for(n = 0; n < DIM_OF_WORLD; n++)
	fprintf(file, "%d ", (int)(el_info->coord[0][n] * factor));
      
      fprintf(file, "\n");
    }
  }
  free_traverse_stack(stack);

  fclose(file);

  return(0);
}
