#include "charlist.h"

/**
 * Reallocates memory for character list.
 */
static void append_char_realloc(int *a) {

	if (parameters.range + 1 > *a) {

		*a *= 2;

		if (*a == 0) {
			*a = 2;
		}

		wchar_t * realloced = realloc(parameters.characters, *a * sizeof(wchar_t));
		parameters.characters = realloced;

	}

}

/**
 * Appends a character to list.
 */
static void append_char(int *a, wchar_t c) {
	append_char_realloc(a);
	parameters.characters[parameters.range++] = c;
}

/**
 * Parses character list.
 */
int ParseList(wchar_t * param) {

	unsigned int len = wcslen(param);

	wchar_t * expanded = malloc(len * sizeof(wchar_t));
	char * modifiers = malloc(len);

	static wchar_t is[3];
	int len_e = 0;

	for (unsigned int i = 0; i < len; i++) {

		for (unsigned int j = i + 1; j - i < 5 && param[i] == '{' && j < len; j++) {

			if (param[j] == '}') {

				unsigned int ic = j - i - 1;
				memset(is, 0, sizeof(is));
				wcsncpy_s(is, ic + 1, param + i + 1, _TRUNCATE);
				unsigned int num = _wtoi(is);

				if ((num > 0 && num < 256) || (ic == 1 && is[0] == '0')) {
					expanded[len_e++] = num;
					i = j + 1;
				}

			}

		}

		expanded[len_e++] = param[i];

		if (param[i] == '-') {
			modifiers[len_e - 1] = 1;
		}

	}

	if (len_e == 0) {
		return 0;
	}

	int a = 0;

	for (unsigned int i = 0; i < len_e; i++) {

		if (i + 2 < len_e && expanded[i + 1] == '-' && modifiers[i + 1]) {

			wchar_t min = expanded[i];
			wchar_t max = expanded[i + 2];

			if (min > max) {
				wchar_t swap = min;
				min = max;
				max = swap;
			}

			for (wchar_t j = min; j <= max; j++) {
				append_char(&a, j);
			}

			i += 2;
			continue;

		}

		append_char(&a, expanded[i]);

	}

	free(expanded);
	free(modifiers);

	return 1;

}