#include "random.h"

int Generate() {

	HCRYPTPROV provider;
	BYTE bytes[RANDOM_CHUNK_SIZE];
	wchar_t buffer[RANDOM_CHUNK_SIZE / sizeof(wchar_t)];

	const double max = (double) (1 << sizeof(wchar_t) * 8) - 1;
	unsigned short int random;
	int r = 0;

	if (!CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
		fwprintf(stderr, L"context acquire failure\n");
		return 0;
	}

	for (unsigned int i = 0; i < parameters.lines; i++) {

		for (unsigned int j = 0; j < parameters.count; j++) {

			if (r == 0 && !CryptGenRandom(provider, RANDOM_CHUNK_SIZE, bytes)) {
				fwprintf(stderr, L"random failure\n");
				return 0;
			}

			random = bytes[r] << 8 | bytes[r + 1];
			buffer[r / sizeof(wchar_t)] = parameters.characters[(int) ((((double) random) / max) * parameters.range)];
			r += sizeof(wchar_t);

			if (j + 1 == parameters.count || r == RANDOM_CHUNK_SIZE) {
				wprintf(L"%.*ls", r / sizeof(wchar_t), buffer);
				memset(&buffer, 0, sizeof(buffer));
				r = 0;
			}

		}

		wprintf(L"\n");

	}

	if (!CryptReleaseContext(provider, 0)) {
		fwprintf(stderr, L"context release failure\n");
	}

	return 1;

}