#include "types.h"
#include "common.h"

// FontHandle xlRichStringAddFont(RichStringHandle handle, FontHandle initFont);
ERL_NIF_TERM c_xlRichStringAddFont(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	RichStringType *rich_string_resource = NULL;

	if (0 == enif_get_resource(env, argv[0], TypeOfRichString, (void**)&rich_string_resource)) {
		return enif_make_badarg(env);
	}

	FontType *font_resource = NULL;

	FontType tmp = {NULL};

	if(isNilAtom(env, argv[1])) {
		font_resource = &tmp;
	} else {
		if (0 == enif_get_resource(env, argv[1], TypeOfFont, (void**)&font_resource)) {
			return enif_make_badarg(env);
		}
	}

	FontHandle font_handle = xlRichStringAddFont(rich_string_resource->handle, font_resource->handle);

	if(!font_handle) {
		return enif_make_atom(env, "nil");
	} else {
		FontType *ret = enif_alloc_resource(TypeOfFont, sizeof(FontType));

		ret->handle = font_handle;

		ERL_NIF_TERM handle = enif_make_resource(env, ret);

		enif_release_resource(ret);

		return handle;
	}
}

// void xlRichStringAddText(RichStringHandle handle, const wchar_t* text, FontHandle font);
ERL_NIF_TERM c_xlRichStringAddText(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	RichStringType *rich_string_resource = NULL;

	if (0 == enif_get_resource(env, argv[0], TypeOfRichString, (void**)&rich_string_resource)) {
		return enif_make_badarg(env);
	}

	ErlNifBinary text_temp;

	if(enif_inspect_binary(env, argv[1], &text_temp) < 1) {
		return enif_make_badarg(env);
	}

	unsigned char *pt1 = createNullTermMbString(text_temp);

	if(!pt1) {
		return enif_make_badarg(env);
	}

	size_t mbs_len1 = strlen((const char*)pt1);

	size_t character_count1 = mbstowcs(NULL, (const char*)pt1, mbs_len1);

	wchar_t w_text[character_count1 + 1];

	(void)memset(w_text, '\0', sizeof(w_text) / sizeof(w_text[0]));

	if((size_t)-1 == mbstowcs(w_text, (const char*)pt1, character_count1 + 1)) {
		free(pt1);

		return enif_make_badarg(env);
	}

	free(pt1);

	FontType *font_resource = NULL;

	if (0 == enif_get_resource(env, argv[2], TypeOfFont, (void**)&font_resource)) {
		return enif_make_badarg(env);
	}

	xlRichStringAddText(rich_string_resource->handle, w_text, font_resource->handle);

	return enif_make_atom(env, "nil");
}

// const wchar_t* xlRichStringGetText(RichStringHandle handle, int index, FontHandle* font);
ERL_NIF_TERM c_xlRichStringGetText(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	RichStringType *rich_string_resource = NULL;

	if (0 == enif_get_resource(env, argv[0], TypeOfRichString, (void**)&rich_string_resource)) {
		return enif_make_badarg(env);
	}

	int index;

	if (0 == enif_get_int(env, argv[1], &index)) {
		return enif_make_badarg(env);
	}

	FontType *font_resource = NULL;

	if (0 == enif_get_resource(env, argv[2], TypeOfFont, (void**)&font_resource)) {
		return enif_make_badarg(env);
	}

	const wchar_t *wstr = xlRichStringGetText(rich_string_resource->handle, index, NULL);

	if(!wstr) {
		return enif_make_atom(env, "error");
	}

	ErlNifBinary ret = convertWcharToMbBinary(wstr);

	if(!ret.data) {
		return enif_make_atom(env, "error");
	}

	return enif_make_binary(env, &ret);
}

// int xlRichStringTextSize(RichStringHandle handle);
ERL_NIF_TERM c_xlRichStringTextSize(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	RichStringType *rich_string_resource = NULL;

	if (0 == enif_get_resource(env, argv[0], TypeOfRichString, (void**)&rich_string_resource)) {
		return enif_make_badarg(env);
	}

	int ret = xlRichStringTextSize(rich_string_resource->handle);

	return enif_make_int(env, ret);
}
