#include <includes.h>
#include <config.h>

/* Usage: xpmtopix (outputfile).  The output files will have .1, .2, etc
 * appended to the name to denote the part
 * This program does assume that only 1 character per color is needed
 * for the xpm files, and assumes that the final output file will work
 * in the same space
 */

/* Most colors that will be supported for output */
#define MAX_COLORS	91
#define START_COLOR	35	/* What ascii code to start new colors at */

/* image_number we are on for this output file */
int image_number = 0,file_number=1, image_y=0, image_x=0;

/* This contains the color strings from the xpm files, to match
 * up with.
 */
int num_color_match=0;
char color_match[MAX_COLORS][80];
char xpm_buf[XPM_MONTAGE_Y*24][XPM_MONTAGE_X*24 + 1];

void load_xpm(char *filename)
{
    FILE *fin;
    int  colors=0, dummy, num_color_trans=0;
    char buf[256], color_translate[MAX_COLORS][2], *cp;

    if ((fin=fopen(filename, "r"))==NULL) {
	fprintf(stderr, "Could not open %s\n", filename);
	exit(8);
    }
    /* Discard top of file comments */
    while ((fgets(buf, 256, fin)!=NULL) && (strncmp(buf, "static", 6)));

    fgets(buf, 256,fin);
    while (buf[0]=='/') {
	    fgets(buf, 256,fin);
    }
    sscanf(buf,"\"%d %d %d", &dummy, &dummy, &colors);

    /* Start reading in colors */
    dummy = 0;
    while (dummy<colors) {
	int color_char_match = -1, count;

	if (getc(fin)=='/') {
		fgets(buf, 256,fin);	/* read in rest of line */
		if (dummy!=0 || strncmp(buf,"* colors",8))
			fprintf(stderr,"File %s, Unexpected comment: %s\n", filename, buf);
		continue;
	}
	fgets(buf, 256, fin);
	buf[strlen(buf)-3] ='\0'; /* removing newline, comma, and quote */

	/* Turn all the tabs into spaces. */
	for (cp=buf+1; *cp!='\0'; cp++) 
	    if (*cp=='\t') *cp=' ';

	/* Try to find a match string.  Start at position 1
	 * to we skip the color id for the string.
	 * If the id for the color matches, set that so we know
	 * it isn't free.
	 */
	for (count=0; count<num_color_match; count++) {
	    if (!strcasecmp(color_match[count]+1, buf+1)) break;
	    if (color_match[count][0] == buf[0])
		color_char_match = count;
	}
	if (buf[0]=='\t') 
	    fprintf(stderr,"File %s using a tab for the color index?\n",filename);
	/* Didn't find the color - lets add it in. */
	if (count==num_color_match) {
	    /* If the character for that color is already used,
	     * then increase the last one in the array by one and
	     * use that.  Always sort after each new color is
	     * added.
	     */
	    if (color_char_match!=-1 || (buf[0]>(START_COLOR + num_color_match))) {
		/* color_translate[0] contains the color in the xpm file.
		 * color_translate[1] contains what it should become.
		 */
		color_translate[num_color_trans][0] = buf[0];
		buf[0] = START_COLOR + num_color_match;
		color_translate[num_color_trans][1] = buf[0];
		num_color_trans++;
	    }
	    strcpy(color_match[num_color_match], buf);
	    num_color_match++;
	    if (num_color_match>MAX_COLORS) {
		fprintf(stderr,"Overflow on color space: %s (%d)\n",
			filename, image_number);
		for (dummy=0; dummy<num_color_match; dummy++)
			fprintf(stderr,"%s\n", color_match[dummy]);
		exit(16);
	    }
	}
	/* We already have that color in our database.  Just set up
	 * the translation table.
	 */
	else if (color_match[count][0]!=buf[0]) {
	    color_translate[num_color_trans][0] = buf[0];
	    color_translate[num_color_trans][1] = color_match[count][0];
	    num_color_trans ++;
	}
	dummy++;
    }

    /* now we start reading the pixels in */
    dummy = 0;
    while (dummy<24) {
	int i,j;

	if (getc(fin)=='/') {
		fgets(buf, 256, fin);
		if (dummy!=0 || strncmp(buf,"* pixels", 8))
			fprintf(stderr,"File %s, Unexpected pixel comment: %s\n", filename, buf);
		continue;
	}
	fgets(buf, 256, fin);
	buf[24] = '\0';
	for (i=0; i<24; i++)
	    for (j=0; j<num_color_trans; j++)
		if (buf[i] == color_translate[j][0]) {
		    buf[i] = color_translate[j][1];
		    break;
		}
	if (image_x==0)
		strcpy(xpm_buf[image_y*24 + dummy], buf);
	else
		strcat(xpm_buf[image_y*24 + dummy], buf);
	dummy++;
    }
    fclose(fin);
    image_x ++;
    if (image_x==XPM_MONTAGE_X) {
	image_x= 0;
	image_y ++;
    }
}

int main(int argc, char *argv[])
{
    FILE *fout, *bmaps;
    char buf[256];
    int i,j;

    if (argc!=2) {
	fprintf(stderr,"Usage: xpmtopix (filename)\n");
	exit(1);
    }
    if ((bmaps = fopen("bmaps.paths", "r"))==NULL) {
	fprintf(stderr,"Can not open bmaps.paths file\n");
	exit(2);
    }
    sprintf(buf,"%s.%d", argv[1], file_number);
    if ((fout=fopen(buf,"w"))==NULL) {
	fprintf(stderr, "Can not open %s for writing\n", buf);
	fclose(bmaps);
	exit(4);
    }
    while (fgets(buf, 256, bmaps)!=NULL) {
	if (buf[0]!='\\') continue;
	buf[strlen(buf)-1] = '\0';
	strcat(buf,".xpm");
	load_xpm(strchr(buf,'.'));
	image_number ++;
	if (image_number == XPM_MONTAGE_X * XPM_MONTAGE_Y) {

	    fprintf(fout,"/* XPM */\n");
	    fprintf(fout, "static char *file[] = {\n");
	    fprintf(fout,"\"%d %d %d 1\",\n", XPM_MONTAGE_X*24, XPM_MONTAGE_Y*24,
		num_color_match);
	    for (i=0; i<num_color_match; i++)
		fprintf(fout,"\"%s\",\n", color_match[i]);
	    for (i=0; i<XPM_MONTAGE_Y*24-1; i++)
		fprintf(fout,"\"%s\",\n", xpm_buf[i]);
	    fprintf(fout,"\"%s\"};\n", xpm_buf[XPM_MONTAGE_Y*24-1]);
	    fclose(fout);
	    image_number = 0;
	    num_color_match = 0;
	    image_x = 0;
	    image_y = 0;
	    file_number++;
	    sprintf(buf,"%s.%d", argv[1], file_number);
	    if ((fout=fopen(buf,"w"))==NULL) {
		fprintf(stderr, "Can not open %s for writing\n", buf);
		fclose(bmaps);
		exit(4);
	    }
	}
    }
    /* Write out the xpm file it was working on.  This will likely not
     * have the full Y dimension */
    fprintf(fout,"/* XPM */\n");
    fprintf(fout, "static char *file[] = {\n");
    fprintf(fout,"\"%d %d %d 1\",\n", XPM_MONTAGE_X*24, 
	(image_x==0? image_y : image_y+1) * 24,
	num_color_match);
    for (i=0; i<num_color_match; i++)
	fprintf(fout,"\"%s\",\n", color_match[i]);
    if (image_x!=0) {
	for (i=image_y*24; i<(image_y+1)*24; i++) {
	    for (j=image_x*24; j<XPM_MONTAGE_X*24; j++)
		xpm_buf[i][j]=color_match[0][0];
	    xpm_buf[i][j] = '\0';
	}
    }
    for (i=0; i<((image_x==0? image_y : image_y+1) * 24) -1; i++)
	fprintf(fout,"\"%s\",\n", xpm_buf[i]);
    fprintf(fout,"\"%s\"};\n", xpm_buf[i]);
    fclose(fout);
    exit(0);
}


#if defined(SVR4) && !defined(__sun__) && !defined(sgi)
int strcasecmp(char *s1, char *s2)
{
  register int c1, c2;

  while (*s1 && *s2) {
    c1 = tolower(*s1);
    c2 = tolower(*s2);
    if (c1 != c2)
      return (c1 - c2);
    s1++;
    s2++;
  }
  return (int) (*s1 - *s2);
}
#endif
