#include <stdio.h>

#define WORLD_X 256
#define WORLD_Y 128

enum { WaitingForHeader, InHeader, InMap, InTrailer, Done } state;

char buf[1024];   /* input buffer */
char x0buf[10];   /* buildup buffer for 1st x value */
char x1buf[10];   /* buildup buffer for 2nd x value */
char xnbuf[10];   /* buildup buffer for final x value */

main(argc,argv)
int argc;
char *argv[];
{
    FILE *fin;    /* input file */
    int x0,x1,xn; /* 1st, 2nd, and final x values */
    int y0,y1,yn; /* 1st, 2nd, and final y values */
    int line;	  /* line counter for parsing the X labels */
    int indent;   /* map indentation level */

    fin = stdin;
    if (argc>1) {
	if (!(fin = fopen(argv[1],"r"))) {
	    fprintf(stderr,"Can't open `%s'\n",argv[1]);
	    exit(1);
	}
    }

    state = WaitingForHeader;
    while (state!=Done && fgets(buf,1024,fin)) {

	switch (state) {

	case WaitingForHeader:
	    if (parseheader(buf,0,&indent)) {
		line = 1;
		state = InHeader;
	    }
	    break;

	case InHeader:
	    if (parseheader(buf,line,0)) {
		line++;
	    } else {
		x0buf[line] = '\0';  /* terminate the buildup buffers  */
		x1buf[line] = '\0';
		xnbuf[line] = '\0';
		x0 = atoi(x0buf);    /* convert 1st x value to binary  */
		x1 = atoi(x1buf);    /* convert 2nd x value to binary  */
		xn = atoi(xnbuf);    /* convert last x value to binary */
		y0 = atoi(buf);      /* convert 1st y value to binary  */
		y1 = yn = y0;        /* 2nd and last y same for now    */
		if (x0>x1) x0 = -x0; /* negate 1st x if necessary      */
		state = InMap;       /* switch state to InMap          */
		parsemapline(buf+indent,x0,xn,y0);
	    }
	    break;

	case InMap:
	    if (parseheader(buf,0,0)) {
		if (y0>y1) y0 = -y0;
		state = InTrailer;
	    } else {
		yn = atoi(buf);
		if (y0==y1) y1 = yn;
		parsemapline(buf+indent,x0,xn,yn);
	    }
	    break;

	case InTrailer:
	    if (!parseheader(buf,0,0)) 
		state = Done;
	    break;

	}
    }

    printf("final map range is %d:%d,%d:%d\n",x0,xn,y0,yn);
    if (fin!=stdin) fclose(fin);
}



parseheader(buf,line,indent)
char *buf;
int *indent;
int line;
{
    char *s;
    for (s=buf; *s && *s<=' '; s++); 	/* skip to first non-blank    */
    if (indent)				/* if we're asked to do so,   */
	*indent = (int)(s-buf);		/*   remember indentation     */
    x0buf[line] = s[0];			/* remember first char        */
    x1buf[line] = s[1];			/* remember second char       */
    while (isdigit(*s) || *s=='-') s++; /* skip over digits/dashes    */
    xnbuf[line] = s[-1];		/* remember last char         */
    while (*s && *s<=' ') s++;          /* skip to next non-blank     */
    return (*s == '\0');		/* return TRUE if real header */
}



parsemapline(buf,x,xn,y)
char *buf;
int x,xn,y;
{
    char *s;
    int x1,y1;

    if (xn<x) xn += WORLD_X;                    /* insure x < xn        */
    for (s=buf; x<=xn; x++, s++) {              /* for each x in range: */
	x1 = (x+WORLD_X) % WORLD_X;             /*   normalize X        */
	y1 = (y+WORLD_Y) % WORLD_Y;             /*   normalize Y        */
	if ( !((x1^y1) & 1) ) {                 /*   skip bad coords    */
	    printf("  %4d,%-4d `%c'\n",x,y,*s); /*   do whatever        */
	}
    }
    printf("\n");
}
