#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <unistd.h>

int main ()
{
  int fd;
  int num_vectors;
  int limits[4];
  double MAP_PIXEL_WIDTH = 1000;

  typedef struct
  {
    int id;
    int code;
    int limits[4];
    int num_points;
    int offset;
  } vector_info;

  vector_info *vector;
  int i;

  fd = open ("WorldTZ.mfd", O_RDONLY);

  if (fd == -1)
  {
    perror ("open");
    abort ();
  }

  read (fd, &num_vectors, 4);
  read (fd, limits, sizeof (limits));
  
  vector = calloc (num_vectors, sizeof (vector_info));
  
  read (fd, vector, sizeof (vector_info) * num_vectors);
  
#if 0
  for (i = 0; i < num_vectors; i++)
  {
    printf ("list%d %d %d %d %d %d %d %d %d\n",
      i,
      vector[i].id,
      vector[i].code,
      vector[i].limits[0],
      vector[i].limits[2],
      vector[i].limits[3],
      vector[i].limits[4],
      vector[i].num_points,
      vector[i].offset);                
  }
#endif

  for (i = 0; i < num_vectors; i++)
  {
    typedef struct
    {
      int lon;
      int lat;
    } point_type;
    
    int j;
    
    point_type *point = NULL;

    point = realloc (point, vector[i].num_points * sizeof (point_type));
    read (fd, point, vector[i].num_points * sizeof (point_type));

    /* Map the points onto an 800x400 pixel area */

    for (j = 0; j < vector[i].num_points; j++)
    {
      if (point[j].lon > -2000000)
      {
      point[j].lon = lrint (point[j].lon * MAP_PIXEL_WIDTH / 3600000);
      point[j].lat = lrint (point[j].lat * MAP_PIXEL_WIDTH / 3600000);
      }
    }

    /* Remove consecutive points that are now the same. */
    
    for (j = 0; j < vector[i].num_points - 1; j++)
    {
      if ((point[j].lon == point[j+1].lon) &&
          (point[j].lat == point[j+1].lat))
      {
        for (int k = j + 1; k < vector[i].num_points - 1; k++)
        {
          point[k].lat = point[k+1].lat;
          point[k].lon = point[k+1].lon;
        }
        
        vector[i].num_points--;
        j--;
      }
    }

    // Lop off any small corners one style at a time 
    //(so that aligning borders match) to make them diagonals.

    for (int lop = 0; lop < 8; lop++)
    {
      int dx1c[8] = {-1, 1,-1, 1, 0, 0, 0, 0,};
      int dx2c[8] = { 0, 0, 0, 0,-1, 1,-1, 1,};
      int dy1c[8] = { 0, 0, 0, 0,-1,-1, 1, 1,};
      int dy2c[8] = {-1,-1, 1, 1, 0, 0, 0, 0,};

      for (j = 0; j < vector[i].num_points - 2; j++)
      {
        int dx1,dx2,dy1,dy2;
        dx1 = point[j+0].lon - point[j+1].lon;
        dx2 = point[j+1].lon - point[j+2].lon;
        dy1 = point[j+0].lat - point[j+1].lat;
        dy2 = point[j+1].lat - point[j+2].lat;

        if ((dx1 == dx1c[lop]) && (dy1 == dy1c[lop]) &&
            (dx2 == dx2c[lop]) && (dy2 == dy2c[lop]))
        {
          for (int k = j + 1; k < vector[i].num_points - 1; k++)
          {
            point[k].lat = point[k+1].lat;
            point[k].lon = point[k+1].lon;
          }
        
          vector[i].num_points--;
          j--;
        }
      }
    } 

    /* Now weed out points where there are a number of points on the same line. */
    
    for (j = 0; j < vector[i].num_points - 2; j++)
    {
      int dx1,dx2,dy1,dy2;
      int same_dir = 0;
      dx1 = point[j+0].lon - point[j+1].lon;
      dx2 = point[j+1].lon - point[j+2].lon;
      dy1 = point[j+0].lat - point[j+1].lat;
      dy2 = point[j+1].lat - point[j+2].lat;

      if ((dx1 == 0) && (dx2 == 0) && (dy1 * dy2 >= 0))
        same_dir = 1;
      if ((dy1 == 0) && (dy2 == 0) && (dx1 * dx2 >= 0))
        same_dir = 1;

      if ((dx1 != 0) && (dx2 != 0))
      {
        if ((dy1 * dx2) == (dy2 * dx1) && ((dx1 * dx2) > 0))
        same_dir = 1;
      }
        
      if (same_dir)
      {
        for (int k = j + 1; k < vector[i].num_points - 1; k++)
        {
          point[k].lat = point[k+1].lat;
          point[k].lon = point[k+1].lon;
        }
        
        vector[i].num_points--;
        j--;
      }
    }
    
    for (j = 0; j < vector[i].num_points; j++)
    {
      if (point[j].lon == -2147483648)
      {
        printf ("%d,\n", vector[i].id);
      }
      else
      {
        printf ("%d,%d,%d,%.2lf,%.2lf\n",
          vector[i].id, vector[i].code, j, 
          point[j].lon * 360.0 / MAP_PIXEL_WIDTH, 
          point[j].lat * 360.0 / MAP_PIXEL_WIDTH);
      }
    }

    printf ("%d,\n", vector[i].id);
  }
}