#if 0
// Listen, this is still prototype, it's not code-merged with other stuff...
// Once I prototype out more stuff, this will use chad.h and hl.h...
// So, this file can run on its' own when compiled, gonna rewrite later.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>

#define UNUSED(x) ((void) (x))

#define ALLOCATION_CHUNK (1024UL)

enum {
	NORMAL,     BOLD,       DARKNESS,   ITALIC,
	UNDERLINE,  BLINK,      DUNNO_6,    REVERSE,
	INVISIBLE
};

enum {
	GREY,       RED,        GREEN,      YELLOW,
	BLUE,       PINK,       CYAN,       WHITE,
	CANCEL
};

static char * buffer      = NULL;
static size_t buffer_size = 0;

static int  match_count         = 0;
static char match_character[80] = "";
static int  match_colour[80]    = { 0 };
static int  match_effect[80]    = { 0 };

static int  range_count      = 0;
static char range_begin[80]  = "";
static char range_end[80]    = "";
static char range_except[80] = "";
static int  range_colour[80] = { 0 };
static int  range_effect[80] = { 0 };

static int  drange_count        = 0;
static char **drange_begin = NULL;
static char **drange_end   = NULL;
static int  drange_colour[80]   = { 0 };
static int  drange_effect[80]   = { 0 };

static void render_character(char * character) {
	write(STDOUT_FILENO, character, sizeof (*character));
}

static void render_string(char * string) {
	write(STDOUT_FILENO, string, strlen(string));
}

static void render_colour(int colour,
                          int effect) {
	char format[8] = "\033[ ;3 m";

	format[2] = (char) (effect % 9) + '0';
	format[5] = (char) (colour % 8) + '0';

	render_string(format);
}

static void render_cancel(void) {
	render_string("\033[0m");
}

static int is_separator(char character) {
	if (( isascii(character))
	&&  (!isalnum(character))
	&&  (character != '_')) {
		return 1;
	} else {
		return 0;
	}
}

static int compare_characters(char         character,
                              const char * characters,
                              const int    count) {
	int i = 0;

	do {
		if (character == characters[i]) {
			return i;
		}
	} while (++i != count);

	return -1;
}

static int compare_strings(char   * string,
                           char * * strings,
                           int      count) {
	int i = 0;
		//~if ((match = compare_strings(&buffer[i], drange_begin, drange_count)) != -1) {
	do {
		if (!strncmp(string, strings[i], strlen(strings[i]))) {
			return i;
		}
	} while (++i != count);

	return -1;
}

static void syntax_character(char character,
                             int  colour,
                             int  effect) {
	match_character[match_count] = character;
	match_colour[match_count]    = colour;
	match_effect[match_count]    = effect;

	++match_count;
}

static void syntax_simple_range(char begin,
                                char end,
                                char except,
                                int  colour,
                                int  effect) {
	range_begin[range_count]  = begin;
	range_end[range_count]    = end;
	range_except[range_count] = except;
	range_colour[range_count] = colour;
	range_effect[range_count] = effect;

	++range_count;
}

static void syntax_double_range(char * begin,
                                char * end,
                                int    colour,
                                int    effect) {
	if ((strlen(begin) > 3) && (strlen(end) > 3)) {
		exit(3);
	}
	strcpy(&drange_begin[drange_count][0], begin);
	strcpy(&drange_end[drange_count][0], end);

	drange_colour[drange_count] = colour;
	drange_effect[drange_count] = effect;

	++drange_count;
}

static void syntax_character_array(char * string,
                                   int    colour,
                                   int    effect) {
	for (size_t i = 0; i != strlen(string); ++i) {
		syntax_character(string[i], colour, effect);
	}
}

static void render_buffer(void) {
	int i = 0;

	render_colour(WHITE, BOLD);

	do {
		int match = -1;
		if ((match = compare_strings(&buffer[i], drange_begin, drange_count)) != -1) {
			render_colour(drange_colour[match], drange_effect[match]);
			do {
				render_character(&buffer[i]);
				++i;
			} while ((buffer[i])
			      && (strncmp(&buffer[i - 1], drange_end[match], strlen(drange_end[match]))));
			      //~&& (buffer[i] != drange_end[match][0]));
			render_character(&buffer[i]);
			++i;
			render_colour(WHITE, BOLD);
		} else if ((match = compare_characters(buffer[i], range_begin, range_count)) != -1) {
			render_colour(range_colour[match], range_effect[match]);
			do {
				if (buffer[i] == range_except[match]) {
					render_character(&buffer[i]);
					++i;
				}
				render_character(&buffer[i]);
				++i;
			} while ((buffer[i])
			      && (buffer[i] != range_end[match]));
			render_character(&buffer[i]);
			++i;
			render_colour(WHITE, BOLD);
		} else if ((match = compare_characters(buffer[i], match_character, match_count)) != -1) {
			render_colour(match_colour[match], match_effect[match]);
			render_character(&buffer[i]);
			++i;
		} else {
			render_colour(WHITE, BOLD);
			render_character(&buffer[i]);
			++i;
		}
	} while (buffer[i]);

	render_cancel();
}

int main(int      argc,
         char * * argv) {
	UNUSED(argc);
	UNUSED(argv);

	buffer = realloc(buffer, ALLOCATION_CHUNK);

	drange_begin = calloc(80UL, sizeof(*drange_begin));
	drange_end   = calloc(80UL, sizeof(*drange_begin));
	for (int i = 0; i != 80; ++i) drange_begin[i] = calloc(4UL, 1UL);
	for (int i = 0; i != 80; ++i) drange_end[i]   = calloc(4UL, 1UL);

	syntax_character_array(".,:;<=>+-*/%!&~^", BLUE, BOLD);
	syntax_character_array("()[]{}", GREEN, BOLD);
	syntax_simple_range('\'', '\'', '\\', RED, BOLD);
	syntax_simple_range('"', '"', '\\', RED, BOLD);
	syntax_double_range("//", "\n", GREY, BOLD);
	syntax_double_range("/*", "*/", GREY, BOLD);

	do {
		if (!((buffer_size + 1) % ALLOCATION_CHUNK)) {
			// Linear incremental reallocation (advanced)!
			/* Test... */
			size_t chunks = (buffer_size + 1) / ALLOCATION_CHUNK;
			buffer = realloc(buffer, ++chunks * ALLOCATION_CHUNK);
		}
		buffer[buffer_size] = '\0';
		read(STDIN_FILENO, &buffer[buffer_size], sizeof (*buffer));
		++buffer_size;
	} while (buffer[buffer_size - 1]);

	buffer[buffer_size - 1] = '\0';

	render_buffer();

	for (int i = 0; i != 80; ++i) free(drange_begin[i]);
	for (int i = 0; i != 80; ++i) free(drange_end[i]);
	free(drange_begin);
	free(drange_end);

	free(buffer);

	return 0;
}
#endif