/*
  cc -O  ppm2terrain_xml.c -lm -o  ppm2terrain_xml
*/

#include <stdio.h>

#define MaxStr 2048


void nextword( char *line, char *word, char *delim )
{
 int i=0, j=0, m=0, flag=1;

 /* Eat away preceding garbage */
 while ((line[i]!='\0') && (flag))
  {
   j = 0;
   while ((delim[j]!='\0') && (line[i]!=delim[j])) j = j + 1;
   if (line[i]!=delim[j]) flag = 0; else { i++; }
  }
 /* Copy the word until the next delimiter. */
 while ((line[i]!='\0') && (!flag))
  {
   word[m++] = line[i++];
   if (line[i]!='\0')
    {
     j = 0;
     while ((delim[j]!='\0') && (line[i]!=delim[j])) j = j + 1;
     if (line[i]==delim[j]) flag = 1;
    }
  }
 /* Shorten line. */
 j = 0;
 while (line[i]!='\0') line[j++] = line[i++];
 /* Terminate the char-strings. */
 line[j] = '\0';
 word[m] = '\0';
}



int main( int argc, char *argv[] )
{
 char infname[MaxStr], outfname[MaxStr], word[MaxStr], line[MaxStr];
 int j=1, k=0, m=0, col, row, ncols, nrows;
 FILE *infile=0, *outfile;
 float north, south, east, west, maxalt=-10000, hscale, value, maxvalue=0.0;
 unsigned int ch;

 while (argc>j)
  { /*argument*/
   if (strcmp(argv[j], "-dim") == 0)
    {
     j++;
     if (j == argc) {printf("missing value(s) after -dim\n"); exit(1);}
     if (sscanf(argv[j],"%f",&north) != 1) { printf("Error: Bad float on north border coordinate.\n");  exit(1); }
     j++;
     if (j == argc) {printf("missing value(s) after -dim\n"); exit(1);}
     if (sscanf(argv[j],"%f", &east) != 1) { printf("Error: Bad float on east border coordinate.\n");  exit(1); }
     j++;
     if (j == argc) {printf("missing value(s) after -dim\n"); exit(1);}
     if (sscanf(argv[j],"%f", &south) != 1) { printf("Error: Bad float on southborder coordinate.\n");  exit(1); }
     j++;
     if (j == argc) {printf("missing value(s) after -dim\n"); exit(1);}
     if (sscanf(argv[j],"%f", &west) != 1) { printf("Error: Bad float on west border coordinate.\n");  exit(1); }
     j++;
     if (j == argc) {printf("missing value(s) after -dim\n"); exit(1);}
     if (sscanf(argv[j],"%f", &maxalt ) != 1) { printf("Error: Bad float maximum height .\n");  exit(1); }
    }
   else
    {
     if (k != 0)
      { printf("Error: Too many arguments on command line.\n");  exit(1); }
     strcpy( infname, argv[j] );
     if ((strstr(infname, ".pgm") == 0) && (strstr(infname, ".ppm") == 0))
      { printf("Error: Input File '%s' does not have '.ppm' suffix.\n", infname );  exit(1); } 
     infile = fopen( infname, "rb" );    
     if (infile==0)
      { printf("Error: Cannot open input file '%s'.\n", infname );  exit(1); } 
     k++;
    }
   j = j + 1;
  } /*argument*/

 if (infile==0) {printf("Error: No input file.\n");  exit(1);} 
 fscanf(infile, "%s", word);
 if (strcmp(word,"P5") != 0)
  { printf("Error: Does not look like Gray-Scale raw-binary PGM file. Exiting!\n");  exit(1); }
 do
  fgets( line, MaxStr, infile );
 while ((line[0] == '\n') || (line[0] == '#'));
 nextword( line, word, " \t\n\r" );
 if (sscanf(word, "%d", &ncols) != 1)
  { printf("Error: Bad number of columns, '%s', in PPM file.\n", word);  exit(1); }
 nextword( line, word, " \t\n\r" );
 if (sscanf(word, "%d", &nrows) != 1)
  { printf("Error: Bad number of rows, '%s', in PPM file.\n", word);  exit(1); }
 fgets( line, MaxStr, infile );

 if (maxalt < -1000)
  {
   printf("What are the coordinates of the North, East, South, and West borders ? ");
   if (scanf("%f", &north) != 1) { printf("Error: Bad float on north border coordinate.\n");  exit(1); }
   if (scanf("%f", &east) != 1) { printf("Error: Bad float on east border coordinate.\n");  exit(1); }
   if (scanf("%f", &south) != 1) { printf("Error: Bad float on southborder coordinate.\n");  exit(1); }
   if (scanf("%f", &west) != 1) { printf("Error: Bad float on west border coordinate.\n");  exit(1); }
   printf("What is the maximum height ? ");
   if (scanf("%f", &maxalt ) != 1) { printf("Error: Bad float maximum height .\n");  exit(1); }
  }

 hscale = maxalt / 256.0;

 /* Find final '.' or position to end of name */
 strcpy( outfname, infname );
 j = strlen( outfname ) - 1;
 while ((outfname[j]!='.') && (j>0)) j = j - 1;
 if (outfname[j]!='.') j = strlen(outfname);
 outfname[j] = '\0'; 
 strcat( outfname, ".xml" );

 printf("\n Writing (%d rows x %d columns = %d points) to file %s\n", nrows, ncols, nrows * ncols, outfname);
 outfile = fopen( outfname, "w" );
 fprintf(outfile,"<elevation_surface name=\"landmass\" north=\"%g\" east=\"%g\" south=\"%g\" west=\"%g\" ncols=\"%d\" nrows=\"%d\" >\n", 
		north, east, south, west, ncols, nrows );
 for (row = 0; row < nrows; row++)
  {
   fprintf(outfile," <row>");
   for (col = 0;  col < ncols;  col++)
    {
     if (feof(infile)) {printf("ERROR: Premature EOF on (%d,%d).\n", row, col );  exit(1);}
     ch = (unsigned int)getc(infile);	m++;
     value = hscale * (float)ch;
     if (value > maxvalue) maxvalue = value;
     // fprintf(outfile," %d", (int)(hscale * (float)ch + 0.5) );
     fprintf(outfile," %2.1f", hscale * (float)ch );
    }
   fprintf(outfile," </row>\n");
  }
 fprintf(outfile,"</elevation_surface>\n");
 fclose( outfile );
 printf("Maximum value = %g\n", maxvalue );
 printf("%d points written. (%d x %d = %d)\n", m, nrows, ncols, nrows * ncols );
}
