#include <allegro.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

/* Generate a grayscale palette */
void generate_palette(PALETTE pal)
{
	int i;
	for (i = 0; i < 256; i++)
		pal[i].r = pal[i].g = pal[i].b = 63 - i / 4;
}

/* Load a font and return a map */
int* load_font(char* filename)
{
	FILE* ffile = fopen(filename, "rb");
	int i, j, y, x, c, v, e;
	int min = -1, max = -1;
	int* font_count = malloc(sizeof(int) * 256);
	int* font_map = malloc(sizeof(int) * 256);

	/* Count number of set pixels in each glyph */
	for (i = 0; i < 256; i++) {
		font_count[i] = 0;
		for (y = 0; y < 16; y++) {
			c = fgetc(ffile);
			for (x = 0; x < 8; x++)
				if (c & (1 << x)) font_count[i]++;
		}
		if (!isprint(i)) {font_count[i] = -1; continue;}
		if (min == -1 || min > font_count[i]) min = font_count[i];
		if (max == -1 || max < font_count[i]) max = font_count[i];
	}
	
	/* Map values 0 - 255 to glyphs */
	for (i = 0; i < 256; i++) {
		/* Detarmine target value */
		v = (max - min) * i / 255 + min;

		/* Find nearest match to target value */
		e = -1;
		for (j = 0; j < 256; j++) {
			if (font_count[j] < 0) continue;
			if (e == -1 || abs(font_count[j] - v) < e) {
				e = abs(font_count[j] - v);
				font_map[i] = j;
			}
		}
	}

	free(font_count);
	fclose(ffile);

	return font_map;
}

/* Load named file as a paper-sized grayscale bitmap */
BITMAP* load_image(char* filename)
{
	BITMAP* img;
	BITMAP* img2;
	PALETTE pal;

	/* Prepare a grayscale palette */
	generate_palette(pal);
	select_palette(pal);
	
	/* Load bitmap and scale to correct size */
	set_color_depth(32);
	img = load_bitmap(filename, NULL);
	img2 = create_bitmap(80, 60);
	stretch_blit(img, img2, 0, 0, img->w, img->h, 0, 0, img2->w, img2->h);
	destroy_bitmap(img);

	/* Dither to 8bpp grayscale */
	set_color_depth(8);
	img = create_bitmap(img2->w, img2->h);
	set_color_conversion(COLORCONV_32_TO_8); // | COLORCONV_DITHER);
	blit(img2, img, 0, 0, 0, 0, img->w, img->h);
	destroy_bitmap(img2);

	return img;
}

void dump_image(int* font, BITMAP* img)
{
	int y, x, v;
	for (y = 0; y < img->h; y++) {
		for (x = 0; x < img->w; x++)
			putchar(font[getpixel(img, x, y)]);
		putchar('\n');
		fflush(stdout);
	}
}

int main(int argc, char** argv)
{
	int* font;
	BITMAP* img;

	if (argc != 3) return EXIT_FAILURE;

	install_allegro(SYSTEM_NONE, &errno, atexit);

	font = load_font(argv[1]);
	img = load_image(argv[2]);
	dump_image(font, img);
	
	free(font);
	destroy_bitmap(img);

	return EXIT_SUCCESS;
}
END_OF_MAIN();

