/*
 * Copyright (C) 2017 FAUmachine Team <info@faumachine.org>.
 * This program is free software. You can redistribute it and/or modify it
 * under the terms of the GNU General Public License, either version 2 of
 * the License, or (at your option) any later version. See COPYING.
 */

#include <assert.h>
#include <stdio.h>
#include <string.h>

static int width;
static int height;
static int max;
static struct {
	int r, g, b;
} image[4024][4024];
static int glyph[32][32];
static int list[1024][32][32];
static int count = 0;

static int
getnum(FILE *fp)
{
	int num;
	int c;

	num = 0;
	c = fgetc(fp);
	while (c == '\t'
	    || c == '\n'
	    || c == ' ') {
		c = fgetc(fp);
	}
	while ('0' <= c && c <= '9') {
		num *= 10;
		num += c - '0';
		c = fgetc(fp);
	}
	ungetc(c, fp);

	return num;
}

static void
load_screenshot(const char *filename)
{
	FILE *fp;
	int c;
	int x, y;

	fp = fopen(filename, "r");
	assert(fp);

	/* Skip "P3" */
	c = fgetc(fp);
	assert(c == 'P');
	c = fgetc(fp);
	assert(c == '3');
	c = fgetc(fp);
	assert(c == '\n');

	/* Skip comment line. */
	c = fgetc(fp);
	if (c == '#') {
		do {
			c = fgetc(fp);
		} while (c != '\n');
	} else {
		ungetc(c, fp);
	}

	width = getnum(fp);
	height = getnum(fp);
	max = getnum(fp);

	for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
			image[y][x].r = getnum(fp);
			image[y][x].g = getnum(fp);
			image[y][x].b = getnum(fp);
		}
	}

	(void) fclose(fp);
}

static void
add_glyph(int h, int w)
{
	int n;

	for (n = 0; ; n++) {
		if (n == count) {
			/* Not found. */
			memcpy(list[n], glyph, sizeof(glyph));
			count++;
			break;
		}
		if (memcmp(list[n], glyph, sizeof(glyph)) == 0) {
			break;
		}
	}
}

static void
glyph_print(int h, int w)
{
	int n;
	int x, y;

	for (n = 0; n < count; n++) {
		printf("unknown_%dx%d '?'\n", w, h);
		for (y = 0; y < h; y++) {
			for (x = 0; x < w; x++) {
				printf("%c", list[n][y][x] ? '@' : '.');
			}
			printf("\n");
		}
		printf("\n");
	}
}

static void
split(int h, int w)
{
	int cx, cy;
	int x, y;
	int r0, g0, b0;
	int r1, g1, b1;
	int col;

	for (cy = 0; cy < height / h; cy++) {
		for (cx = 0; cx < width / w; cx++) {
			r0 = image[cy * h][cx * w].r;
			g0 = image[cy * h][cx * w].g;
			b0 = image[cy * h][cx * w].b;

			memset(glyph, 0, sizeof(glyph));
			for (y = 0; y < h; y++) {
				for (x = 0; x < w; x++) {
					r1 = image[cy * h + y][cx * w + x].r;
					g1 = image[cy * h + y][cx * w + x].g;
					b1 = image[cy * h + y][cx * w + x].b;

					col = r0 == r1 && g0 == g1 && b0 == b1;
					col = ! col;
					glyph[y][x] = col;
				}
			}

			add_glyph(h, w);
		}
	}
}

int
main(int argc, char **argv)
{
	argc--;
	argv++;

	while (argc != 0) {
		load_screenshot(*argv);
		fprintf(stderr, "Size: %d %d\n", width, height);
		split(16, 8);

		argc--;
		argv++;
	}

	glyph_print(16, 8);

	return 0;
}
