/*

    FILE:  extract.c
    USAGE:  extract [ < infile > < outfile >
		    < minimum longitude > to < maximum longtiude >
		    < minimum latitude  > to < maximum latitude  > ]

    Main program for reading in an existing map file and extracting
    the specified subset to a new file.  The map file contains
    longitude-latitude coordinates, with the coordinates
    -9999.00 -9999.00 used to signal boundarues between land areas
    and the coordinates -8888.00 -8888.00 used to signal 
    boundaries between land and enclosed bodies of water.

*/
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "map.h"

/* Below is a Q&D way around changes to the connect() routine so it
   will continue to be usable with extract; around 01/95, connect()
   and the rest of the vector plotting code was modified to do all
   output in paper inches, rather than degrees; this does not work
   for the extract program which must continue to work in degrees.
   JR - 95/05/02 */

#ifdef LonToIn
#undef LonToIn
#endif
#define LonToIn(xx) (xx)

#ifdef LatToIn
#undef LatToIn
#endif
#define LatToIn(xx) (xx)

#include "mapsub.c"

#define ALLOWANCE 1.0

#if PROTOTYPE_ALLOWED
void main(int argc, char *argv[])
#else
void main(argc, argv)
int     argc;
char    *argv[];
#endif
{
   RANGE_TYPE lon_range, lat_range;
   LONLAT_TYPE current, previous, *last_in;
   char    mapfile[80], outfile[80];
   FILE    *fpmap,*fpout;

   if (argc != 9)
   {
      printf("\n Please specify the source map => ");
      scanf(" %s", mapfile);
      printf("\n Please specify the destination map => ");
      scanf(" %s", outfile);
      printf("\n Minimum longitude => ");
      scanf(" %lf", &(lon_range.min));
      printf("\n Maximum longitude => ");
      scanf(" %lf", &(lon_range.max));
      printf("\n Minimum latitude  => ");
      scanf(" %lf", &(lat_range.min));
      printf("\n Maximum latitude  => ");
      scanf(" %lf", &(lat_range.max));
   }
   else
   {
      strcpy(mapfile, argv[1]);
      strcpy(outfile, argv[2]);
      lon_range.min = atof(argv[3]);
      lon_range.max = atof(argv[5]);
      lat_range.min = atof(argv[6]);
      lat_range.max = atof(argv[8]);
   }

   if (lon_range.min < 0.0) lon_range.min += 360.0;
   if (lon_range.max < 0.0) lon_range.max += 360.0;

   /* Extend user-specified boundaries by one degree so land outlines
      meet axis.  The clippath defined above will take care of the excess. */

   lon_range.min -= ALLOWANCE;
   lat_range.min -= ALLOWANCE;
   lon_range.max += ALLOWANCE;
   lat_range.max += ALLOWANCE;

   if ( (fpmap = fopen(mapfile, "r")) == NULL)
   {
      fprintf(stderr, "\n ERROR: Unable to open map file %s.\n", mapfile);
      return;
   }

   if ( (fpout = fopen(outfile, "w")) == NULL)
   {
      fprintf(stderr, "\n ERROR: Unable to open output file %s.\n", outfile);
      return;
   }

   current.lon = current.lat = LAND_BOUNDARY;

   while (!feof(fpmap))
   {
      previous.lon = current.lon;
      previous.lat = current.lat;

      if (fscanf(fpmap, " %lf %lf", &current.lon, &current.lat) != 2) break;

      if (in_range(current))
      {
         if (in_range(previous))
            fprintf(fpout, "%12.6f %12.6f\n", current.lon, current.lat);
         else /* either start new path or resume existing one */ 
         {
            if (equal(previous.lon, LAND_BOUNDARY) ||
                equal(previous.lon, WATER_BOUNDARY) ||
               (last_in = pop()) == NULL) /* must be new path */
            {
               fprintf(fpout, "%12.6f %12.6f\n", current.lon, current.lat);
               if (push(current)) return; /* remember first point in */
            }
            else /* reentering range */
               connect(fpout, *last_in, current, lon_range, lat_range, ' ');
         }
      }
      else /* either boundary or out-of-range */
      {
         if (equal(current.lon, LAND_BOUNDARY) ||
             equal(current.lon, WATER_BOUNDARY))
         {
            if (in_range(previous)) /* close preceding path properly */
            {
               connect(fpout, previous, *pop(), lon_range, lat_range, ' ');
               fprintf(fpout, "%12.6f %12.6f\n", current.lon, current.lat);
            }
            else
            {
               if ((last_in = pop()) != NULL) /* close preceding path */
               {
                  connect(fpout, *last_in, *pop(), lon_range, lat_range, ' ');
                  fprintf(fpout, "%12.6f %12.6f\n", current.lon, current.lat);
               }
            }
         }
         else
         {
            if (in_range(previous)) /* exiting range */
            if (push(previous)) return; /* remember last point in */
         }
      }
   } /* end while !feof */

   fclose(fpmap);
   fclose(fpout);
}

