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

static void AddData(char *);
static char *my_strtok(char *, char c);

static unsigned short ToUC[0x10000+1];
static unsigned short ToLC[0x10000+1];
static unsigned uc, lc;

extern int BuildSpecial();

int main() {
	// Open UnicodeData.txt
	FILE *in;
	char Buf[512];
	fopen_s(&in, "UnicodeData.txt", "rt");
	fgets(Buf, sizeof(Buf), in);
	fgets(Buf, sizeof(Buf), in);
	while (!feof(in)) {
		char *jnk;
		strtok_s(Buf, "\r\n", &jnk);
		AddData(Buf);
		fgets(Buf, sizeof(Buf), in);
	}

	printf ("/***************************************************************/\n");
	printf ("/*  AUTO-GENERATED-CODE !!! DO NOT EDIT BELOW THIS POINT !!!!  */\n");
	printf ("/***************************************************************/\n");
	printf ("/* There are %d uc's and %d lc's                             */\n", uc, lc);
	printf ("/* These next 2 arrays, generated from the UnicodeData.txt file*/\n");
	printf ("/***************************************************************/\n");

	printf ("static unsigned arToUCDat[%d] = {\n", lc*2+2);
	int cnt = 0;
	for (unsigned i = 0; i < 0x10000; ++i) {
		if (ToUC[i]) {
			printf ("0x%X,0x%X, ", i, ToUC[i]);
			if (++cnt == 8) {
				cnt = 0;
				printf("\n");
			}
		}
	}
	printf (" 0, 0 };\n");

	printf ("static unsigned arToLCDat[%d] = {\n", uc*2+2);
	cnt = 0;
	for (unsigned i = 0; i < 0x10000; ++i) {
		if (ToLC[i]) {
			printf ("0x%X,0x%X, ", i, ToLC[i]);
			if (++cnt == 8) {
				cnt = 0;
				printf("\n");
			}
		}
	}
	printf (" 0, 0 };\n");

	return BuildSpecial();
}

static void AddData(char *Buf) {
	char *cp = my_strtok(Buf, ';');
	unsigned value;
	bool bCap=false;
	
	sscanf_s(cp, "%X", &value);
	if (value >= 0x10000)
		return;

	cp = my_strtok(NULL, ';');     // type
	cp = my_strtok(NULL, ';');     // Ll  Lu  (lower or upper)
	if (!strcmp(cp, "Lu")) {
		// we have a cap letter
		bCap=true;
	}
	else if (!strcmp(cp, "Ll")) {
		// we have a low case letter letter
	}
	else 
		return;
	cp = my_strtok(NULL, ';');
	cp = my_strtok(NULL, ';');     // Ll  Lu  (lower or upper)
	cp = my_strtok(NULL, ';');
	cp = my_strtok(NULL, ';');
	cp = my_strtok(NULL, ';');
	cp = my_strtok(NULL, ';');
	cp = my_strtok(NULL, ';');
	cp = my_strtok(NULL, ';');
	cp = my_strtok(NULL, ';');
	cp = my_strtok(NULL, ';');
	if (!bCap) {
		unsigned upCase, TitleCase;
		sscanf_s(cp, "%X", &upCase);
		cp = my_strtok(NULL, ';');
		cp = my_strtok(NULL, ';');
		if (!cp || *cp == 0) {
			printf ("");
			return;
		}
		sscanf_s(cp, "%X", &TitleCase);
		if (upCase != TitleCase) {
			printf ("");
			return;
		}
		ToUC[value] = upCase;

		++lc;
		return;
	}
	cp = my_strtok(NULL, ';');
	unsigned loCase;
	if (!cp || *cp == 0) {
		printf ("");
		return;
	}
	sscanf_s(cp, "%X", &loCase);
	ToLC[value] = loCase;
	++uc;
}

static char *my_strtok(char *in, char c) {
	static char *pBuf;
	if (in)
		pBuf = in;
	char *p = pBuf;
	if (!p || !p[0])
		return NULL;
	while (*pBuf && *pBuf != c)
		++pBuf;
	if (*pBuf)
		*pBuf++ = 0;
	return p;
}
