/*
 * read_plot3d_xy.c: read and visualize a PLOT3D two-dimensional mesh
 *
 * version: 0.2
 *
 * This geomview module reads a two-dimensional, unformatted, multi-block
 * PLOT3D grid file and visualizes it.
 *
 *
 * Copyright (c) 2009  Francesco Poli <frx@firenze.linux.it>
 *
 * This work is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, version 2,
 * as published by the Free Software Foundation.
 *     
 * This work is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *             
 * You should have received a copy of the GNU General Public License
 * along with this work; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 *
 */

#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>

int
main(int argc, char *argv[])
{
    FILE *xyzfile;     /* grid file */
    int mark;          /* record marker */
    int nblocks;       /* number of grid blocks */
    int *dims;         /* grid dimensions */
    int blk;           /* grid block index */
    int ni, nj;        /* grid dimensions for i and j indices */
    int idx;           /* grid node unique index */
    float *x, *y;      /* grid node coordinates */

    if (argc != 2)
      {
        fprintf(stderr, "Plot3D_xy: wrong number of arguments\n");
        fprintf(stderr, "usage:  geomview -start Plot3D_xy file.xyz\n");
        exit(1);
      }

    if ( (xyzfile = fopen(argv[1], "rb")) == NULL )
      {
        fprintf(stderr, "Plot3D_xy: cannot open file %s\n", argv[1]);
        exit(2);
      }

    /* read grid file header (while skipping start/end record markers) */
    fread(&mark   , sizeof(int), 1, xyzfile);
    fread(&nblocks, sizeof(int), 1, xyzfile);
    fread(&mark   , sizeof(int), 1, xyzfile);
    if (nblocks <= 0)
      {
        fprintf(stderr, "Plot3D_xy: %s: non-positive number of blocks!\n",
                argv[1]);
        fclose(xyzfile);
        exit(11);
      }

    /* read grid block dimensions */
    if ( (dims = (int *)malloc((size_t)2*nblocks*sizeof(int))) == NULL )
      {
        fprintf(stderr, "Plot3D_xy: cannot allocate memory!\n");
        fclose(xyzfile);
        exit(12);
      }
    fread(&mark, sizeof(int), 1        , xyzfile);
    fread(dims , sizeof(int), 2*nblocks, xyzfile);
    fread(&mark, sizeof(int), 1        , xyzfile);

    /* send setup commands to Geomview */
    printf("(new-geometry \"[g1]\"\n  {\n    appearance { +edge -face }\n");
    printf("    LIST\n");

    /* for each grid block ... */
    for (blk = 0; blk < nblocks; ++blk)
      {
        /* write and check dimensions */
        ni = dims[2*blk  ];
        nj = dims[2*blk+1];
        fprintf(stderr, "Plot3D_xy: block #%d dimensions:  %dx%d\n",
                blk, ni, nj);

        if (ni <= 0 || nj <= 0)
          {
            fprintf(stderr, "Plot3D_xy: %s: found non-positive dimension!\n",
                    argv[1]);
            free(dims);
            fclose(xyzfile);
            exit(13);
          }

        /* read grid node two-dimensional coordinates */
        if ( (x = (float *)malloc((size_t)ni*nj*sizeof(float))) == NULL )
          {
            fprintf(stderr, "Plot3D_xy: cannot allocate memory!\n");
            free(dims);
            fclose(xyzfile);
            exit(14);
          }
        if ( (y = (float *)malloc((size_t)ni*nj*sizeof(float))) == NULL )
          {
            fprintf(stderr, "Plot3D_xy: cannot allocate memory!\n");
            free(x);
            free(dims);
            fclose(xyzfile);
            exit(15);
          }
        fread(&mark, sizeof(int)  , 1    , xyzfile);
        fread(x    , sizeof(float), ni*nj, xyzfile);
        fread(y    , sizeof(float), ni*nj, xyzfile);
        fread(&mark, sizeof(int)  , 1    , xyzfile);
        
        /* send commands to Geomview for the current grid block */
        printf("    {\n      MESH %d %d\n", ni, nj);
        for (idx = 0; idx < ni*nj; ++idx)
          {
            printf("      %g %g %g\n", x[idx], y[idx], 0.0);
          }
        printf("    }\n");

        free(x);
        free(y);
      }

    /* send commands to Geomview for final settings */
    printf("  }\n)\n");
    printf("(bbox-draw \"[g1]\" off)\n");
    printf("(name-object \"[g1]\" \"%s\")\n", argv[1]);
    /* TODO: what if argv[1] includes quotes?!? */
    printf("(backcolor \"Camera\" 1.0 1.0 1.0)\n");
    printf("(ui-target \"World\")\n");
    printf("(event-mode \"[t] Translate\")\n");

    free(dims);
    fclose(xyzfile);
    return 0;
}

