#include <clip.h>

#define APPNAME		"gifwin"
#define SIZE_MAX	2048

//	#define FNAME		"EDGE1.gif"
//	#define FNAME		"EDGE2.gif"
//	#define FNAME		"EDGE3.gif"
//	#define FNAME		"EDGE4.gif"
//	#define FNAME		"op/doton1op.gif"
//	#define FNAME		"op/doton2op.gif"
//	#define FNAME		"op/doton3op.gif"
//	#define FNAME		"op/doton4op.gif"
//	#define FNAME		"op/doton5op.gif"
//	#define FNAME		"op/doton6op.gif"
//	#define FNAME		"op/doton7op.gif"
//	#define FNAME		"op/doton8op.gif"
//	#define FNAME		"oi/doton1oi.gif"
//	#define FNAME		"oi/doton2oi.gif"
//	#define FNAME		"oi/doton3oi.gif"
//	#define FNAME		"oi/doton4oi.gif"
//	#define FNAME		"oi/doton5oi.gif"
//	#define FNAME		"oi/doton6oi.gif"
//	#define FNAME		"oi/doton7oi.gif"
//	#define FNAME		"oi/doton8oi.gif"
//	#define FNAME		"tp/doton1tp.gif"
//	#define FNAME		"tp/doton2tp.gif"
//	#define FNAME		"tp/doton3tp.gif"
//	#define FNAME		"tp/doton4tp.gif"
//	#define FNAME		"tp/doton5tp.gif"
//	#define FNAME		"tp/doton6tp.gif"
//	#define FNAME		"tp/doton7tp.gif"
//	#define FNAME		"tp/doton8tp.gif"
//	#define FNAME		"ti/doton1ti.gif"
//	#define FNAME		"ti/doton2ti.gif"
//	#define FNAME		"ti/doton3ti.gif"
	#define FNAME		"ti/doton4ti.gif"
//	#define FNAME		"ti/doton5ti.gif"
//	#define FNAME		"ti/doton6ti.gif"
//	#define FNAME		"ti/doton7ti.gif"
//	#define FNAME		"ti/doton8ti.gif"

int win_scale;
int file_size;
unsigned char* file_data;

int img_w;
int img_h;
unsigned char img[SIZE_MAX][SIZE_MAX][3];

BITMAPINFOHEADER bi;
unsigned char* dib;

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

static void my_size_proc(int w, int h, void* user_data) {
	int x, y;
	for(y = 0; y < h; y++) {
		for(x = 0; x < w; x++) {
			if(((x / 16) ^ (y / 16)) & 1) {
				img[y][x][0] = 85;
				img[y][x][1] = 85;
				img[y][x][2] = 85;
			} else {
				img[y][x][0] = 170;
				img[y][x][1] = 170;
				img[y][x][2] = 170;
			}
		}
	}
	img_w = w;
	img_h = h;
}

static void my_draw_proc(int i, int x, int y, int c, const unsigned char (*p)[3], void* user_data) {
	if(x < 0 || x > img_w - 1 || y < 0 || y > img_h - 1 || (c & ~255)) {
		DIE();
	}
	if(i == 0) {
		img[y][x][0] = p[c][2];
		img[y][x][1] = p[c][1];
		img[y][x][2] = p[c][0];
	}
}

int main(int argc, char* argv[]) {
	const char* fname;
	FILE* fp;
	int pitch;
	int i;
	int x;
	int y;
	HINSTANCE hInst;
	HWND hWnd;
	MSG msg;
	WNDCLASS wc;
	RECT rcWin;
	RECT rcCli;
	int ncW;
	int ncH;

	DEBUG_INIT();

	fname = (argc >= 1 + 1) ? argv[1] : FNAME;
	win_scale = (argc >= 1 + 2) ? atoi(argv[2]) : 1;
	if(win_scale < 1) win_scale = 1;

	fp = fopen(fname, "rb");
	if(!fp) {
		DIE();
	}
	fseek(fp, 0, SEEK_END);
	file_size = ftell(fp);
	rewind(fp);
	file_data = malloc(file_size);
	if(!file_data) {
		DIE();
	}
	fread(file_data, 1, file_size, fp);
	fclose(fp);
	gif_decode(file_data, my_size_proc, my_draw_proc, NULL);
	bi.biSize = sizeof(BITMAPINFOHEADER);
	bi.biWidth = img_w;
	bi.biHeight = img_h;
	bi.biPlanes = 1;
	bi.biBitCount = 24;
	pitch = ((img_w * 3) + 3) & ~3;
	dib = malloc(pitch * img_h);
	if(!dib) {
		DIE();
	}
	for(y = 0; y < img_h; y++) {
		for(x = 0; x < img_w; x++) {
			for(i = 0; i < 3; i++) {
				dib[y * pitch + x * 3 + i] = img[img_h - 1 - y][x][i];
			}
		}
	}

	hInst = GetModuleHandle(NULL);
	memset(&wc, 0, sizeof wc);
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = WndProc;
	wc.hInstance = hInst;
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.lpszClassName = APPNAME;
	RegisterClass(&wc);
	hWnd = CreateWindow(APPNAME, APPNAME,
		WS_OVERLAPPED | WS_SYSMENU,
		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
		NULL, NULL, hInst, NULL);
	GetWindowRect(hWnd, &rcWin);
	GetClientRect(hWnd, &rcCli);
	ncW = (rcWin.right - rcWin.left) - (rcCli.right - rcCli.left);
	ncH = (rcWin.bottom - rcWin.top) - (rcCli.bottom - rcCli.top);
	MoveWindow(hWnd, 0, 0, ncW + img_w * win_scale, ncH + img_h * win_scale, FALSE);
	ShowWindow(hWnd, SW_SHOW);
	UpdateWindow(hWnd);

	while(GetMessage(&msg, NULL, 0, 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	free(file_data);
	free(dib);

	return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
	HDC hDC;
	PAINTSTRUCT ps;

	switch(msg) {
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	case WM_KEYDOWN:
		if(wParam == VK_ESCAPE) {
			SendMessage(hWnd, WM_CLOSE, 0, 0);
			return 0;
		}
		return 0;
	case WM_PAINT:
		hDC = BeginPaint(hWnd, &ps);
		StretchDIBits(hDC,
			0, 0, bi.biWidth * win_scale, bi.biHeight * win_scale,
			0, 0, bi.biWidth, bi.biHeight,
			dib, (BITMAPINFO*)&bi, DIB_RGB_COLORS, SRCCOPY);
		EndPaint(hWnd, &ps);
		return 0;
	}
	return DefWindowProc(hWnd, msg, wParam, lParam);
}

