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


// int xlSheetCellType(SheetHandle handle, int row, int col);
ERL_NIF_TERM c_xlSheetCellType(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	int ret = xlSheetCellType(sheet_resource->handle, row, col);

	return enif_make_int(env, ret);
}

// int xlSheetIsFormula(SheetHandle handle, int row, int col);
ERL_NIF_TERM c_xlSheetIsFormula(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	int ret = xlSheetIsFormula(sheet_resource->handle, row, col);

	return enif_make_int(env, ret);
}

// void xlSheetSetCellFormat(SheetHandle handle, int row, int col, FormatHandle format);
ERL_NIF_TERM c_xlSheetSetCellFormat(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	FormatType *format_resource = NULL;

	FormatType tmp = {NULL};

	if(isNilAtom(env, argv[3])) {
		format_resource = &tmp;
	} else {
		if (0 == enif_get_resource(env, argv[3], TypeOfFormat, (void**)&format_resource)) {
			return enif_make_badarg(env);
		}
	}

	xlSheetSetCellFormat(sheet_resource->handle, row, col, format_resource->handle);

	return enif_make_atom(env, "nil");
}

// const wchar_t* xlSheetReadStr(SheetHandle handle, int row, int col, FormatHandle* format);
ERL_NIF_TERM c_xlSheetReadStr(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	FormatType *format = enif_alloc_resource(TypeOfFormat, sizeof(FormatType));

	const wchar_t *wstr = xlSheetReadStr(sheet_resource->handle, row, col, &format->handle);

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

	ErlNifBinary ret = convertWcharToMbBinary(wstr);

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

	ERL_NIF_TERM handle = enif_make_resource(env, format);

	enif_release_resource(format);

	return enif_make_list2(env,
		enif_make_binary(env, &ret),
		handle
	);
}

// int xlSheetWriteStr(SheetHandle handle, int row, int col, const wchar_t* value, FormatHandle format);
ERL_NIF_TERM c_xlSheetWriteStr(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	ErlNifBinary value_temp;

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

	unsigned char *pt1 = createNullTermMbString(value_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_value[character_count1 + 1];

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

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

		return enif_make_badarg(env);
	}

	free(pt1);

	FormatType *format_resource = NULL;

	FormatType tmp = {NULL};

	if(isNilAtom(env, argv[4])) {
		format_resource = &tmp;
	} else {
		if (0 == enif_get_resource(env, argv[4], TypeOfFormat, (void**)&format_resource)) {
			return enif_make_badarg(env);
		}
	}

	int ret = xlSheetWriteStr(sheet_resource->handle, row, col, w_value, format_resource->handle);

	return enif_make_int(env, ret);
}

// int xlSheetWriteStrAsNum(SheetHandle handle, int row, int col, const wchar_t* value, FormatHandle format);
ERL_NIF_TERM c_xlSheetWriteStrAsNum(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	ErlNifBinary value_temp;

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

	unsigned char *pt1 = createNullTermMbString(value_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_value[character_count1 + 1];

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

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

		return enif_make_badarg(env);
	}

	free(pt1);

	FormatType *format_resource = NULL;

	FormatType tmp = {NULL};

	if(isNilAtom(env, argv[4])) {
		format_resource = &tmp;
	} else {
		if (0 == enif_get_resource(env, argv[4], TypeOfFormat, (void**)&format_resource)) {
			return enif_make_badarg(env);
		}
	}

	int ret = xlSheetWriteStrAsNum(sheet_resource->handle, row, col, w_value, format_resource->handle);

	return enif_make_int(env, ret);
}

// RichStringHandle xlSheetReadRichStr(SheetHandle handle, int row, int col, FormatHandle* format);
ERL_NIF_TERM c_xlSheetReadRichStr(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	FormatType *format = enif_alloc_resource(TypeOfFormat, sizeof(FormatType));

	RichStringType *ret = enif_alloc_resource(TypeOfRichString, sizeof(RichStringType));

	ret->handle = xlSheetReadRichStr(sheet_resource->handle, row, col, &format->handle);

	ERL_NIF_TERM ret_resource = enif_make_resource(env, ret);

	ERL_NIF_TERM format_resource = enif_make_resource(env, format);

	enif_release_resource(ret);

	enif_release_resource(format);

	return enif_make_list2(env,
		ret_resource,
		format_resource
	);
}

// int xlSheetWriteRichStr(SheetHandle handle, int row, int col, RichStringHandle richString, FormatHandle format);
ERL_NIF_TERM c_xlSheetWriteRichStr(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	RichStringType *rich_string_resource = NULL;

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

	FormatType *format_resource = NULL;

	FormatType tmp = {NULL};

	if(isNilAtom(env, argv[4])) {
		format_resource = &tmp;
	} else {
		if (0 == enif_get_resource(env, argv[4], TypeOfFormat, (void**)&format_resource)) {
			return enif_make_badarg(env);
		}
	}

	int ret = xlSheetWriteRichStr(sheet_resource->handle, row, col, rich_string_resource->handle, format_resource->handle);

	return enif_make_int(env, ret);
}

// double xlSheetReadNum(SheetHandle handle, int row, int col, FormatHandle* format);
ERL_NIF_TERM c_xlSheetReadNum(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	FormatType *format = enif_alloc_resource(TypeOfFormat, sizeof(FormatType));

	double ret = xlSheetReadNum(sheet_resource->handle, row, col, &format->handle);

	ERL_NIF_TERM format_resource = enif_make_resource(env, format);

	enif_release_resource(format);

	return enif_make_list2(env,
		enif_make_double(env, ret),
		format_resource
	);
}

// int xlSheetWriteNum(SheetHandle handle, int row, int col, double value, FormatHandle format);
ERL_NIF_TERM c_xlSheetWriteNum(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	double value;

	if (0 == enif_get_double(env, argv[3], &value)) {
		return enif_make_badarg(env);
	}

	FormatType *format_resource = NULL;

	FormatType tmp = {NULL};

	if(isNilAtom(env, argv[4])) {
		format_resource = &tmp;
	} else {
		if (0 == enif_get_resource(env, argv[4], TypeOfFormat, (void**)&format_resource)) {
			return enif_make_badarg(env);
		}
	}

	int ret = xlSheetWriteNum(sheet_resource->handle, row, col, value, format_resource->handle);

	return enif_make_int(env, ret);
}

// int xlSheetReadBool(SheetHandle handle, int row, int col, FormatHandle* format);
ERL_NIF_TERM c_xlSheetReadBool(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	FormatType *format = enif_alloc_resource(TypeOfFormat, sizeof(FormatType));

	int ret = xlSheetReadBool(sheet_resource->handle, row, col, &format->handle);

	ERL_NIF_TERM handle = enif_make_resource(env, format);

	enif_release_resource(format);

	return enif_make_list2(env,
		enif_make_int(env, ret),
		handle
	);
}

// int xlSheetWriteBool(SheetHandle handle, int row, int col, int value, FormatHandle format);
ERL_NIF_TERM c_xlSheetWriteBool(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	int value;

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

	FormatType *format_resource = NULL;

	FormatType tmp = {NULL};

	if(isNilAtom(env, argv[4])) {
		format_resource = &tmp;
	} else {
		if (0 == enif_get_resource(env, argv[4], TypeOfFormat, (void**)&format_resource)) {
			return enif_make_badarg(env);
		}
	}

	int ret = xlSheetWriteBool(sheet_resource->handle, row, col, value, format_resource->handle);

	return enif_make_int(env, ret);
}

// int xlSheetReadBlank(SheetHandle handle, int row, int col, FormatHandle* format);
ERL_NIF_TERM c_xlSheetReadBlank(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	FormatType *format = enif_alloc_resource(TypeOfFormat, sizeof(FormatType));

	int ret = xlSheetReadBlank(sheet_resource->handle, row, col, &format->handle);

	ERL_NIF_TERM handle = enif_make_resource(env, format);

	enif_release_resource(format);

	return enif_make_list2(env,
		enif_make_int(env, ret),
		handle
	);
}

// int xlSheetWriteBlank(SheetHandle handle, int row, int col, FormatHandle format);
ERL_NIF_TERM c_xlSheetWriteBlank(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	FormatType *format_resource = NULL;

	FormatType tmp = {NULL};

	if(isNilAtom(env, argv[3])) {
		format_resource = &tmp;
	} else {
		if (0 == enif_get_resource(env, argv[3], TypeOfFormat, (void**)&format_resource)) {
			return enif_make_badarg(env);
		}
	}

	int ret = xlSheetWriteBlank(sheet_resource->handle, row, col, format_resource->handle);

	return enif_make_int(env, ret);
}

// const wchar_t* xlSheetReadFormula(SheetHandle handle, int row, int col, FormatHandle* format);
ERL_NIF_TERM c_xlSheetReadFormula(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	FormatType *format = enif_alloc_resource(TypeOfFormat, sizeof(FormatType));

	const wchar_t *wstr = xlSheetReadFormula(sheet_resource->handle, row, col, &format->handle);

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

	ErlNifBinary ret = convertWcharToMbBinary(wstr);

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

	ERL_NIF_TERM handle = enif_make_resource(env, format);

	enif_release_resource(format);

	return enif_make_list2(env,
		enif_make_binary(env, &ret),
		handle
	);
}

// int xlSheetWriteFormula(SheetHandle handle, int row, int col, const wchar_t* value, FormatHandle format);
ERL_NIF_TERM c_xlSheetWriteFormula(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	ErlNifBinary value_temp;

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

	unsigned char *pt1 = createNullTermMbString(value_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_value[character_count1 + 1];

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

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

		return enif_make_badarg(env);
	}

	free(pt1);

	FormatType *format_resource = NULL;

	FormatType tmp = {NULL};

	if(isNilAtom(env, argv[4])) {
		format_resource = &tmp;
	} else {
		if (0 == enif_get_resource(env, argv[4], TypeOfFormat, (void**)&format_resource)) {
			return enif_make_badarg(env);
		}
	}

	int ret = xlSheetWriteFormula(sheet_resource->handle, row, col, w_value, format_resource->handle);

	return enif_make_int(env, ret);
}

// int xlSheetWriteFormulaNum(SheetHandle handle, int row, int col, const wchar_t* expr, double value, FormatHandle format);
ERL_NIF_TERM c_xlSheetWriteFormulaNum(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	ErlNifBinary expr_temp;

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

	unsigned char *pt1 = createNullTermMbString(expr_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_expr[character_count1 + 1];

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

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

		return enif_make_badarg(env);
	}

	free(pt1);

	double value;

	if (0 == enif_get_double(env, argv[4], &value)) {
		return enif_make_badarg(env);
	}

	FormatType *format_resource = NULL;

	FormatType tmp = {NULL};

	if(isNilAtom(env, argv[5])) {
		format_resource = &tmp;
	} else {
		if (0 == enif_get_resource(env, argv[5], TypeOfFormat, (void**)&format_resource)) {
			return enif_make_badarg(env);
		}
	}

	int ret = xlSheetWriteFormulaNum(sheet_resource->handle, row, col, w_expr, value, format_resource->handle);

	return enif_make_int(env, ret);
}

// int xlSheetWriteFormulaStr(SheetHandle handle, int row, int col, const wchar_t* expr, const wchar_t* value, FormatHandle format);
ERL_NIF_TERM c_xlSheetWriteFormulaStr(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	ErlNifBinary expr_temp;

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

	unsigned char *pt1 = createNullTermMbString(expr_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_expr[character_count1 + 1];

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

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

		return enif_make_badarg(env);
	}

	free(pt1);


	ErlNifBinary value_temp;

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

	unsigned char *pt2 = createNullTermMbString(value_temp);

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

	size_t mbs_len2 = strlen((const char*)pt2);

	size_t character_count2 = mbstowcs(NULL, (const char*)pt2, mbs_len2);

	wchar_t w_value[character_count2 + 1];

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

	if((size_t)-1 == mbstowcs(w_value, (const char*)pt2, character_count2 + 1)) {
		free(pt2);

		return enif_make_badarg(env);
	}

	free(pt2);

	FormatType *format_resource = NULL;

	FormatType tmp = {NULL};

	if(isNilAtom(env, argv[5])) {
		format_resource = &tmp;
	} else {
		if (0 == enif_get_resource(env, argv[5], TypeOfFormat, (void**)&format_resource)) {
			return enif_make_badarg(env);
		}
	}

	int ret = xlSheetWriteFormulaStr(sheet_resource->handle, row, col, w_expr, w_value, format_resource->handle);

	return enif_make_int(env, ret);
}

// int xlSheetWriteFormulaBool(SheetHandle handle, int row, int col, const wchar_t* expr, int value, FormatHandle format);
ERL_NIF_TERM c_xlSheetWriteFormulaBool(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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


	int row;

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

	int col;

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

	ErlNifBinary expr_temp;

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

	unsigned char *pt1 = createNullTermMbString(expr_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_expr[character_count1 + 1];

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

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

		return enif_make_badarg(env);
	}

	free(pt1);

	int value;

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

	FormatType *format_resource = NULL;

	FormatType tmp = {NULL};

	if(isNilAtom(env, argv[5])) {
		format_resource = &tmp;
	} else {
		if (0 == enif_get_resource(env, argv[5], TypeOfFormat, (void**)&format_resource)) {
			return enif_make_badarg(env);
		}
	}

	int ret = xlSheetWriteFormulaBool(sheet_resource->handle, row, col, w_expr, value, format_resource->handle);

	return enif_make_int(env, ret);
}

// const wchar_t* xlSheetReadComment(SheetHandle handle, int row, int col);
ERL_NIF_TERM c_xlSheetReadComment(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	const wchar_t *wstr = xlSheetReadComment(sheet_resource->handle, row, col);

	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);
}

// void xlSheetWriteComment(SheetHandle handle, int row, int col, const wchar_t* value, const wchar_t* author, int width, int height);
ERL_NIF_TERM c_xlSheetWriteComment(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	ErlNifBinary value_temp;

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

	unsigned char *pt1 = createNullTermMbString(value_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_value[character_count1 + 1];

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

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

		return enif_make_badarg(env);
	}

	free(pt1);

	ErlNifBinary author_temp;

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

	unsigned char *pt2 = createNullTermMbString(author_temp);

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

	size_t mbs_len2 = strlen((const char*)pt2);

	size_t character_count2 = mbstowcs(NULL, (const char*)pt2, mbs_len2);

	wchar_t w_author[character_count2 + 1];

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

	if((size_t)-1 == mbstowcs(w_author, (const char*)pt2, character_count2 + 1)) {
		free(pt2);

		return enif_make_badarg(env);
	}

	free(pt2);

	int width;

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

	int height;

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

	xlSheetWriteComment(sheet_resource->handle, row, col, w_value, w_author, width, height);

	return enif_make_atom(env, "nil");
}

// void xlSheetRemoveComment(SheetHandle handle, int row, int col);
ERL_NIF_TERM c_xlSheetRemoveComment(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	xlSheetRemoveComment(sheet_resource->handle, row, col);

	return enif_make_atom(env, "nil");
}

// int xlSheetIsDate(SheetHandle handle, int row, int col);
ERL_NIF_TERM c_xlSheetIsDate(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	int ret = xlSheetIsDate(sheet_resource->handle, row, col);

	return enif_make_int(env, ret);
}

// int xlSheetIsRichStr(SheetHandle handle, int row, int col);
ERL_NIF_TERM c_xlSheetIsRichStr(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	int ret = xlSheetIsRichStr(sheet_resource->handle, row, col);

	return enif_make_int(env, ret);
}

// int xlSheetReadError(SheetHandle handle, int row, int col);
ERL_NIF_TERM c_xlSheetReadError(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	int ret = xlSheetReadError(sheet_resource->handle, row, col);

	return enif_make_int(env, ret);
}

// void xlSheetWriteError(SheetHandle handle, int row, int col, int error, FormatHandle format);
ERL_NIF_TERM c_xlSheetWriteError(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	int error;

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

	FormatType *format_resource = NULL;

	FormatType tmp = {NULL};

	if(isNilAtom(env, argv[4])) {
		format_resource = &tmp;
	} else {
		if (0 == enif_get_resource(env, argv[4], TypeOfFormat, (void**)&format_resource)) {
			return enif_make_badarg(env);
		}
	}

	xlSheetWriteError(sheet_resource->handle, row, col, error, format_resource->handle);

	return enif_make_atom(env, "nil");
}

// double xlSheetColWidth(SheetHandle handle, int col);
ERL_NIF_TERM c_xlSheetColWidth(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int col;

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

	double ret = xlSheetColWidth(sheet_resource->handle, col);

	return enif_make_double(env, ret);
}

// double xlSheetRowHeight(SheetHandle handle, int row);
ERL_NIF_TERM c_xlSheetRowHeight(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	double ret = xlSheetRowHeight(sheet_resource->handle, row);

	return enif_make_double(env, ret);
}

// int xlSheetColWidthPx(SheetHandle handle, int col);
ERL_NIF_TERM c_xlSheetColWidthPx(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int col;

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

	int ret = xlSheetColWidthPx(sheet_resource->handle, col);

	return enif_make_int(env, ret);
}

// int xlSheetRowHeightPx(SheetHandle handle, int row);
ERL_NIF_TERM c_xlSheetRowHeightPx(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int ret = xlSheetRowHeightPx(sheet_resource->handle, row);

	return enif_make_int(env, ret);
}

// int xlSheetSetCol(SheetHandle handle, int colFirst, int colLast, double width, FormatHandle format, int hidden);
ERL_NIF_TERM c_xlSheetSetCol(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int col_first;

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

	int col_last;

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

	double width;

	if (0 == enif_get_double(env, argv[3], &width)) {
		return enif_make_badarg(env);
	}

	FormatType *format_resource = NULL;

	FormatType tmp = {NULL};

	if(isNilAtom(env, argv[4])) {
		format_resource = &tmp;
	} else {
		if (0 == enif_get_resource(env, argv[4], TypeOfFormat, (void**)&format_resource)) {
			return enif_make_badarg(env);
		}
	}

	int hidden;

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

	int ret = xlSheetSetCol(sheet_resource->handle, col_first, col_last, width, format_resource->handle, hidden);

	return enif_make_int(env, ret);
}

// int xlSheetSetRow(SheetHandle handle, int row, double height, FormatHandle format, int hidden);
ERL_NIF_TERM c_xlSheetSetRow(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int height;

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

	FormatType *format_resource = NULL;

	FormatType tmp = {NULL};

	if(isNilAtom(env, argv[3])) {
		format_resource = &tmp;
	} else {
		if (0 == enif_get_resource(env, argv[3], TypeOfFormat, (void**)&format_resource)) {
			return enif_make_badarg(env);
		}
	}

	int hidden;

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

	int ret = xlSheetSetRow(sheet_resource->handle, row, height, format_resource->handle, hidden);

	return enif_make_int(env, ret);
}

// int xlSheetRowHidden(SheetHandle handle, int row);
ERL_NIF_TERM c_xlSheetRowHidden(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int ret = xlSheetRowHidden(sheet_resource->handle, row);

	return enif_make_int(env, ret);
}

// int xlSheetSetRowHidden(SheetHandle handle, int row, int hidden);
ERL_NIF_TERM c_xlSheetSetRowHidden(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int hidden;

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

	int ret = xlSheetSetRowHidden(sheet_resource->handle, row, hidden);

	return enif_make_int(env, ret);
}

// int xlSheetColHidden(SheetHandle handle, int col);
ERL_NIF_TERM c_xlSheetColHidden(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int col;

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

	int ret = xlSheetColHidden(sheet_resource->handle, col);

	return enif_make_int(env, ret);
}

// int xlSheetSetColHidden(SheetHandle handle, int col, int hidden);
ERL_NIF_TERM c_xlSheetSetColHidden(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int col;

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

	int hidden;

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

	int ret = xlSheetSetColHidden(sheet_resource->handle, col, hidden);

	return enif_make_int(env, ret);
}

// int xlSheetGetMerge(SheetHandle handle, int row, int col, int* rowFirst, int* rowLast, int* colFirst, int* colLast);
ERL_NIF_TERM c_xlSheetGetMerge(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	int rowFirst;
	int rowLast;
	int colFirst;
	int colLast;

	int ret = xlSheetGetMerge(sheet_resource->handle, row, col, &rowFirst, &rowLast, &colFirst, &colLast);

	return enif_make_list5(env,
		enif_make_int(env, ret),
		enif_make_int(env, rowFirst),
		enif_make_int(env, rowLast),
		enif_make_int(env, colFirst),
		enif_make_int(env, colLast)
	);
}

// int xlSheetSetMerge(SheetHandle handle, int rowFirst, int rowLast, int colFirst, int colLast);
ERL_NIF_TERM c_xlSheetSetMerge(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row_fisrt;

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

	int row_last;

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

	int col_first;

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

	int col_last;

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

	int ret = xlSheetSetMerge(sheet_resource->handle, row_fisrt, row_last, col_first, col_last);

	return enif_make_int(env, ret);
}

// int xlSheetDelMerge(SheetHandle handle, int row, int col);
ERL_NIF_TERM c_xlSheetDelMerge(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	int ret = xlSheetDelMerge(sheet_resource->handle, row, col);

	return enif_make_int(env, ret);
}

// int xlSheetMergeSize(SheetHandle handle);
ERL_NIF_TERM c_xlSheetMergeSize(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetMergeSize(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// int xlSheetMerge(SheetHandle handle, int index, int* rowFirst, int* rowLast, int* colFirst, int* colLast);
ERL_NIF_TERM c_xlSheetMerge(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int index;

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

	int rowFirst;
	int rowLast;
	int colFirst;
	int colLast;

	int ret = xlSheetMerge(sheet_resource->handle, index, &rowFirst, &rowLast, &colFirst, &colLast);

	return enif_make_list5(env,
		enif_make_int(env, ret),
		enif_make_int(env, rowFirst),
		enif_make_int(env, rowLast),
		enif_make_int(env, colFirst),
		enif_make_int(env, colLast)
	);
}

// int xlSheetDelMergeByIndex(SheetHandle handle, int index);
ERL_NIF_TERM c_xlSheetDelMergeByIndex(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int index;

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

	int ret = xlSheetDelMergeByIndex(sheet_resource->handle, index);

	return enif_make_int(env, ret);
}

// int xlSheetPictureSize(SheetHandle handle);
ERL_NIF_TERM c_xlSheetPictureSize(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetPictureSize(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// int xlSheetGetPicture(SheetHandle handle, int index, int* rowTop, int* colLeft, int* rowBottom, int* colRight, int* width, int* height, int* offset_x, int* offset_y);
ERL_NIF_TERM c_xlSheetGetPicture(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int index;

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

	int rowTop;
	int colLeft;
	int rowBottom;
	int colRight;
	int width;
	int height;
	int offset_x;
	int offset_y;

	int ret = xlSheetGetPicture(sheet_resource->handle, index, &rowTop, &colLeft, &rowBottom, &colRight, &width, &height, &offset_x, &offset_y);

	return enif_make_list9(env,
		enif_make_int(env, ret),
		enif_make_int(env, rowTop),
		enif_make_int(env, colLeft),
		enif_make_int(env, rowBottom),
		enif_make_int(env, colRight),
		enif_make_int(env, width),
		enif_make_int(env, height),
		enif_make_int(env, offset_x),
		enif_make_int(env, offset_y)
	);
}

// int xlSheetRemovePictureByIndex(SheetHandle handle, int index);
ERL_NIF_TERM c_xlSheetRemovePictureByIndex(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int index;

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

	int ret = xlSheetRemovePictureByIndex(sheet_resource->handle, index);

	return enif_make_int(env, ret);
}

// void xlSheetSetPicture(SheetHandle handle, int row, int col, int pictureId, double scale, int offset_x, int offset_y, int pos);
ERL_NIF_TERM c_xlSheetSetPicture(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	int picture_id;

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

	double scale;

	if (0 == enif_get_double(env, argv[4], &scale)) {
		return enif_make_badarg(env);
	}

	int offset_x;

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

	int offset_y;

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

	int pos;

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

	xlSheetSetPicture(sheet_resource->handle, row, col, picture_id, scale, offset_x, offset_y, pos);

	return enif_make_atom(env, "nil");
}

// void xlSheetSetPicture2(SheetHandle handle, int row, int col, int pictureId, int width, int height, int offset_x, int offset_y, int pos);
ERL_NIF_TERM c_xlSheetSetPicture2(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	int picture_id;

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

	int width;

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

	int height;

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

	int offset_x;

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

	int offset_y;

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

	int pos;

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

	xlSheetSetPicture2(sheet_resource->handle, row, col, picture_id, width, height, offset_x, offset_y, pos);

	return enif_make_atom(env, "nil");
}

// int xlSheetRemovePicture(SheetHandle handle, int row, int col);
ERL_NIF_TERM c_xlSheetRemovePicture(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	int ret = xlSheetRemovePicture(sheet_resource->handle, row, col);

	return enif_make_int(env, ret);
}

// int xlSheetGetHorPageBreak(SheetHandle handle, int index);
ERL_NIF_TERM c_xlSheetGetHorPageBreak(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int index;

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

	int ret = xlSheetGetHorPageBreak(sheet_resource->handle, index);

	return enif_make_int(env, ret);
}

// int xlSheetGetHorPageBreakSize(SheetHandle handle);
ERL_NIF_TERM c_xlSheetGetHorPageBreakSize(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetGetHorPageBreakSize(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// int xlSheetGetVerPageBreak(SheetHandle handle, int index);
ERL_NIF_TERM c_xlSheetGetVerPageBreak(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int index;

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

	int ret = xlSheetGetVerPageBreak(sheet_resource->handle, index);

	return enif_make_int(env, ret);
}

// int xlSheetGetVerPageBreakSize(SheetHandle handle);
ERL_NIF_TERM c_xlSheetGetVerPageBreakSize(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetGetVerPageBreakSize(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// int xlSheetSetHorPageBreak(SheetHandle handle, int row, int pageBreak);
ERL_NIF_TERM c_xlSheetSetHorPageBreak(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int page_break;

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

	int ret = xlSheetSetHorPageBreak(sheet_resource->handle, row, page_break);

	return enif_make_int(env, ret);
}

// int xlSheetSetVerPageBreak(SheetHandle handle, int col, int pageBreak);
ERL_NIF_TERM c_xlSheetSetVerPageBreak(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int col;

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

	int page_break;

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

	int ret = xlSheetSetVerPageBreak(sheet_resource->handle, col, page_break);

	return enif_make_int(env, ret);
}

// void xlSheetSplit(SheetHandle handle, int row, int col);
ERL_NIF_TERM c_xlSheetSplit(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	xlSheetSplit(sheet_resource->handle, row, col);

	return enif_make_atom(env, "nil");
}

// int xlSheetSplitInfo(SheetHandle handle, int* row, int* col);
ERL_NIF_TERM c_xlSheetSplitInfo(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;
	int col;

	int ret = xlSheetSplitInfo(sheet_resource->handle, &row, &col);

	return enif_make_list3(env,
		enif_make_int(env, ret),
		enif_make_int(env, row),
		enif_make_int(env, col)
	);
}

// int xlSheetGroupRows(SheetHandle handle, int rowFirst, int rowLast, int collapsed);
ERL_NIF_TERM c_xlSheetGroupRows(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row_first;

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

	int row_last;

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

	int collapsed;

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

	int ret = xlSheetGroupRows(sheet_resource->handle, row_first, row_last, collapsed);

	return enif_make_int(env, ret);
}

// int xlSheetGroupCols(SheetHandle handle, int colFirst, int colLast, int collapsed);
ERL_NIF_TERM c_xlSheetGroupCols(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int col_first;

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

	int col_last;

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

	int collapsed;

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

	int ret = xlSheetGroupCols(sheet_resource->handle, col_first, col_last, collapsed);

	return enif_make_int(env, ret);
}

// int xlSheetGroupSummaryBelow(SheetHandle handle);
ERL_NIF_TERM c_xlSheetGroupSummaryBelow(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetGroupSummaryBelow(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// void xlSheetSetGroupSummaryBelow(SheetHandle handle, int below);
ERL_NIF_TERM c_xlSheetSetGroupSummaryBelow(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int below;

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

	xlSheetSetGroupSummaryBelow(sheet_resource->handle, below);

	return enif_make_atom(env, "nil");
}

// int xlSheetGroupSummaryRight(SheetHandle handle);
ERL_NIF_TERM c_xlSheetGroupSummaryRight(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetGroupSummaryRight(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// void xlSheetSetGroupSummaryRight(SheetHandle handle, int right);
ERL_NIF_TERM c_xlSheetSetGroupSummaryRight(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int right;

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

	xlSheetSetGroupSummaryRight(sheet_resource->handle, right);

	return enif_make_atom(env, "nil");
}

// int xlSheetClear(SheetHandle handle, int rowFirst, int rowLast, int colFirst, int colLast);
ERL_NIF_TERM c_xlSheetClear(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row_first;

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

	int row_last;

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

	int col_first;

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

	int col_last;

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

	int ret = xlSheetClear(sheet_resource->handle, row_first, row_last, col_first, col_last);

	return enif_make_int(env, ret);
}

// int xlSheetInsertCol(SheetHandle handle, int colFirst, int colLast);
ERL_NIF_TERM c_xlSheetInsertCol(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int col_first;

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

	int col_last;

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

	int ret = xlSheetInsertCol(sheet_resource->handle, col_first, col_last);

	return enif_make_int(env, ret);
}

// int xlSheetInsertRow(SheetHandle handle, int rowFirst, int rowLast);
ERL_NIF_TERM c_xlSheetInsertRow(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row_first;

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

	int row_last;

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

	int ret = xlSheetInsertRow(sheet_resource->handle, row_first, row_last);

	return enif_make_int(env, ret);
}

// int xlSheetRemoveCol(SheetHandle handle, int colFirst, int colLast);
ERL_NIF_TERM c_xlSheetRemoveCol(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int col_first;

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

	int col_last;

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

	int ret = xlSheetRemoveCol(sheet_resource->handle, col_first, col_last);

	return enif_make_int(env, ret);
}

// int xlSheetRemoveRow(SheetHandle handle, int rowFirst, int rowLast);
ERL_NIF_TERM c_xlSheetRemoveRow(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row_first;

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

	int row_last;

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

	int ret = xlSheetRemoveRow(sheet_resource->handle, row_first, row_last);

	return enif_make_int(env, ret);
}

// int xlSheetInsertColAndKeepRanges(SheetHandle handle, int colFirst, int colLast);
ERL_NIF_TERM c_xlSheetInsertColAndKeepRanges(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int col_first;

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

	int col_last;

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

	int ret = xlSheetInsertColAndKeepRanges(sheet_resource->handle, col_first, col_last);

	return enif_make_int(env, ret);
}

// int xlSheetInsertRowAndKeepRanges(SheetHandle handle, int rowFirst, int rowLast);
ERL_NIF_TERM c_xlSheetInsertRowAndKeepRanges(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row_first;

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

	int row_last;

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

	int ret = xlSheetInsertRowAndKeepRanges(sheet_resource->handle, row_first, row_last);

	return enif_make_int(env, ret);
}

// int xlSheetRemoveColAndKeepRanges(SheetHandle handle, int colFirst, int colLast);
ERL_NIF_TERM c_xlSheetRemoveColAndKeepRanges(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int col_first;

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

	int col_last;

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

	int ret = xlSheetRemoveColAndKeepRanges(sheet_resource->handle, col_first, col_last);

	return enif_make_int(env, ret);
}

// int xlSheetRemoveRowAndKeepRanges(SheetHandle handle, int rowFirst, int rowLast);
ERL_NIF_TERM c_xlSheetRemoveRowAndKeepRanges(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row_first;

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

	int row_last;

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

	int ret = xlSheetRemoveRowAndKeepRanges(sheet_resource->handle, row_first, row_last);

	return enif_make_int(env, ret);
}

// int xlSheetCopyCell(SheetHandle handle, int rowSrc, int colSrc, int rowDst, int colDst);
ERL_NIF_TERM c_xlSheetCopyCell(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row_src;

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

	int col_src;

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

	int row_dst;

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

	int col_dst;

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

	int ret = xlSheetCopyCell(sheet_resource->handle, row_src, col_src, row_dst, col_dst);

	return enif_make_int(env, ret);
}

// int xlSheetFirstRow(SheetHandle handle);
ERL_NIF_TERM c_xlSheetFirstRow(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetFirstRow(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// int xlSheetLastRow(SheetHandle handle);
ERL_NIF_TERM c_xlSheetLastRow(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetLastRow(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// int xlSheetFirstCol(SheetHandle handle);
ERL_NIF_TERM c_xlSheetFirstCol(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetFirstCol(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// int xlSheetLastCol(SheetHandle handle);
ERL_NIF_TERM c_xlSheetLastCol(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetLastCol(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// int xlSheetFirstFilledRow(SheetHandle handle);
ERL_NIF_TERM c_xlSheetFirstFilledRow(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetFirstFilledRow(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// int xlSheetLastFilledRow(SheetHandle handle);
ERL_NIF_TERM c_xlSheetLastFilledRow(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetLastFilledRow(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// int xlSheetFirstFilledCol(SheetHandle handle);
ERL_NIF_TERM c_xlSheetFirstFilledCol(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetFirstFilledCol(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// int xlSheetLastFilledCol(SheetHandle handle);
ERL_NIF_TERM c_xlSheetLastFilledCol(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetLastFilledCol(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// int xlSheetDisplayGridlines(SheetHandle handle);
ERL_NIF_TERM c_xlSheetDisplayGridlines(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetDisplayGridlines(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// void xlSheetSetDisplayGridlines(SheetHandle handle, int show);
ERL_NIF_TERM c_xlSheetSetDisplayGridlines(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int show;

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

	xlSheetSetDisplayGridlines(sheet_resource->handle, show);

	return enif_make_atom(env, "nil");
}

// int xlSheetPrintGridlines(SheetHandle handle);
ERL_NIF_TERM c_xlSheetPrintGridlines(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetPrintGridlines(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// void xlSheetSetPrintGridlines(SheetHandle handle, int print);
ERL_NIF_TERM c_xlSheetSetPrintGridlines(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int print;

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

	xlSheetSetPrintGridlines(sheet_resource->handle, print);

	return enif_make_atom(env, "nil");
}

// int xlSheetZoom(SheetHandle handle);
ERL_NIF_TERM c_xlSheetZoom(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetZoom(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// void xlSheetSetZoom(SheetHandle handle, int zoom);
ERL_NIF_TERM c_xlSheetSetZoom(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int zoom;

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

	xlSheetSetZoom(sheet_resource->handle, zoom);

	return enif_make_atom(env, "nil");
}

// int xlSheetPrintZoom(SheetHandle handle);
ERL_NIF_TERM c_xlSheetPrintZoom(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetPrintZoom(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// void xlSheetSetPrintZoom(SheetHandle handle, int zoom);
ERL_NIF_TERM c_xlSheetSetPrintZoom(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int zoom;

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

	xlSheetSetPrintZoom(sheet_resource->handle, zoom);

	return enif_make_atom(env, "nil");
}

// int xlSheetGetPrintFit(SheetHandle handle, int* wPages, int* hPages);
ERL_NIF_TERM c_xlSheetGetPrintFit(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int wPages;
	int hPages;

	int ret = xlSheetGetPrintFit(sheet_resource->handle, &wPages, &hPages);

	return enif_make_list3(env,
		enif_make_int(env, ret),
		enif_make_int(env, wPages),
		enif_make_int(env, hPages)
	);
}

// void xlSheetSetPrintFit(SheetHandle handle, int wPages, int hPages);
ERL_NIF_TERM c_xlSheetSetPrintFit(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int w_pages;

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

	int h_pages;

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

	xlSheetSetPrintFit(sheet_resource->handle, w_pages, h_pages);

	return enif_make_atom(env, "nil");
}

// int xlSheetLandscape(SheetHandle handle);
ERL_NIF_TERM c_xlSheetLandscape(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetLandscape(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// void xlSheetSetLandscape(SheetHandle handle, int landscape);
ERL_NIF_TERM c_xlSheetSetLandscape(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int landscape;

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

	xlSheetSetLandscape(sheet_resource->handle, landscape);

	return enif_make_atom(env, "nil");
}

// int xlSheetPaper(SheetHandle handle);
ERL_NIF_TERM c_xlSheetPaper(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetPaper(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// void xlSheetSetPaper(SheetHandle handle, int paper);
ERL_NIF_TERM c_xlSheetSetPaper(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int paper;

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

	xlSheetSetPaper(sheet_resource->handle, paper);

	return enif_make_atom(env, "nil");
}

// const wchar_t* xlSheetHeader(SheetHandle handle);
ERL_NIF_TERM c_xlSheetHeader(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	const wchar_t *wstr = xlSheetHeader(sheet_resource->handle);

	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 xlSheetSetHeader(SheetHandle handle, const wchar_t* header, double margin);
ERL_NIF_TERM c_xlSheetSetHeader(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	ErlNifBinary header_temp;

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

	unsigned char *pt1 = createNullTermMbString(header_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_header[character_count1 + 1];

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

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

		return enif_make_badarg(env);
	}

	free(pt1);

	double margin;

	if (0 == enif_get_double(env, argv[2], &margin)) {
		return enif_make_badarg(env);
	}

	int ret = xlSheetSetHeader(sheet_resource->handle, w_header, margin);

	return enif_make_int(env, ret);
}

// double xlSheetHeaderMargin(SheetHandle handle);
ERL_NIF_TERM c_xlSheetHeaderMargin(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	double ret = xlSheetHeaderMargin(sheet_resource->handle);

	return enif_make_double(env, ret);
}

// const wchar_t* xlSheetFooter(SheetHandle handle);
ERL_NIF_TERM c_xlSheetFooter(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	const wchar_t *wstr = xlSheetFooter(sheet_resource->handle);

	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 xlSheetSetFooter(SheetHandle handle, const wchar_t* footer, double margin);
ERL_NIF_TERM c_xlSheetSetFooter(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	ErlNifBinary footer_temp;

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

	unsigned char *pt1 = createNullTermMbString(footer_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_footer[character_count1 + 1];

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

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

		return enif_make_badarg(env);
	}

	free(pt1);

	double margin;

	if (0 == enif_get_double(env, argv[2], &margin)) {
		return enif_make_badarg(env);
	}

	int ret = xlSheetSetFooter(sheet_resource->handle, w_footer, margin);

	return enif_make_int(env, ret);
}

// double xlSheetFooterMargin(SheetHandle handle);
ERL_NIF_TERM c_xlSheetFooterMargin(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	double ret = xlSheetFooterMargin(sheet_resource->handle);

	return enif_make_double(env, ret);
}

// int xlSheetHCenter(SheetHandle handle);
ERL_NIF_TERM c_xlSheetHCenter(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetHCenter(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// void xlSheetSetHCenter(SheetHandle handle, int hCenter);
ERL_NIF_TERM c_xlSheetSetHCenter(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int h_center;

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

	xlSheetSetHCenter(sheet_resource->handle, h_center);

	return enif_make_atom(env, "nil");
}

// int xlSheetVCenter(SheetHandle handle);
ERL_NIF_TERM c_xlSheetVCenter(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetVCenter(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// void xlSheetSetVCenter(SheetHandle handle, int vCenter);
ERL_NIF_TERM c_xlSheetSetVCenter(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int v_center;

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

	xlSheetSetVCenter(sheet_resource->handle, v_center);

	return enif_make_atom(env, "nil");
}

// double xlSheetMarginLeft(SheetHandle handle);
ERL_NIF_TERM c_xlSheetMarginLeft(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	double ret = xlSheetMarginLeft(sheet_resource->handle);

	return enif_make_double(env, ret);
}

// void xlSheetSetMarginLeft(SheetHandle handle, double margin);
ERL_NIF_TERM c_xlSheetSetMarginLeft(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	double margin;

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

	xlSheetSetMarginLeft(sheet_resource->handle, margin);

	return enif_make_atom(env, "nil");
}

// double xlSheetMarginRight(SheetHandle handle);
ERL_NIF_TERM c_xlSheetMarginRight(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	double ret = xlSheetMarginRight(sheet_resource->handle);

	return enif_make_double(env, ret);
}

// void xlSheetSetMarginRight(SheetHandle handle, double margin);
ERL_NIF_TERM c_xlSheetSetMarginRight(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	double margin;

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

	xlSheetSetMarginRight(sheet_resource->handle, margin);

	return enif_make_atom(env, "nil");
}

// double xlSheetMarginTop(SheetHandle handle);
ERL_NIF_TERM c_xlSheetMarginTop(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	double ret = xlSheetMarginTop(sheet_resource->handle);

	return enif_make_double(env, ret);
}

// void xlSheetSetMarginTop(SheetHandle handle, double margin);
ERL_NIF_TERM c_xlSheetSetMarginTop(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	double margin;

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

	xlSheetSetMarginTop(sheet_resource->handle, margin);

	return enif_make_atom(env, "nil");
}

// double xlSheetMarginBottom(SheetHandle handle);
ERL_NIF_TERM c_xlSheetMarginBottom(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	double ret = xlSheetMarginBottom(sheet_resource->handle);

	return enif_make_double(env, ret);
}

// void xlSheetSetMarginBottom(SheetHandle handle, double margin);
ERL_NIF_TERM c_xlSheetSetMarginBottom(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	double margin;

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

	xlSheetSetMarginBottom(sheet_resource->handle, margin);

	return enif_make_atom(env, "nil");
}

// int xlSheetPrintRowCol(SheetHandle handle);
ERL_NIF_TERM c_xlSheetPrintRowCol(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetPrintRowCol(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// void xlSheetSetPrintRowCol(SheetHandle handle, int print);
ERL_NIF_TERM c_xlSheetSetPrintRowCol(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int print;

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

	xlSheetSetPrintRowCol(sheet_resource->handle, print);

	return enif_make_atom(env, "nil");
}

// int xlSheetPrintRepeatRows(SheetHandle handle, int* rowFirst, int* rowLast);
ERL_NIF_TERM c_xlSheetPrintRepeatRows(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int rowFirst;
	int rowLast;

	int ret = xlSheetPrintRepeatRows(sheet_resource->handle, &rowFirst, &rowLast);

	return enif_make_list3(env,
		enif_make_int(env, ret),
		enif_make_int(env, rowFirst),
		enif_make_int(env, rowLast)
	);
}

// void xlSheetSetPrintRepeatRows(SheetHandle handle, int rowFirst, int rowLast);
ERL_NIF_TERM c_xlSheetSetPrintRepeatRows(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row_first;

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

	int row_last;

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

	xlSheetSetPrintRepeatRows(sheet_resource->handle, row_first, row_last);

	return enif_make_atom(env, "nil");
}

// int xlSheetPrintRepeatCols(SheetHandle handle, int* colFirst, int* colLast);
ERL_NIF_TERM c_xlSheetPrintRepeatCols(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int colFirst;
	int colLast;

	int ret = xlSheetPrintRepeatCols(sheet_resource->handle, &colFirst, &colLast);

	return enif_make_list3(env,
		enif_make_int(env, ret),
		enif_make_int(env, colFirst),
		enif_make_int(env, colLast)
	);
}

// void xlSheetSetPrintRepeatCols(SheetHandle handle, int colFirst, int colLast);
ERL_NIF_TERM c_xlSheetSetPrintRepeatCols(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int col_fist;

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

	int col_last;

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

	xlSheetSetPrintRepeatCols(sheet_resource->handle, col_fist, col_last);

	return enif_make_atom(env, "nil");
}

// int xlSheetPrintArea(SheetHandle handle, int* rowFirst, int* rowLast, int* colFirst, int* colLast);
ERL_NIF_TERM c_xlSheetPrintArea(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int rowFirst;
	int rowLast;
	int colFirst;
	int colLast;

	int ret = xlSheetPrintArea(sheet_resource->handle, &rowFirst, &rowLast, &colFirst, &colLast);

	return enif_make_list5(env,
		enif_make_int(env, ret),
		enif_make_int(env, rowFirst),
		enif_make_int(env, rowLast),
		enif_make_int(env, colFirst),
		enif_make_int(env, colLast)
	);
}

// void xlSheetSetPrintArea(SheetHandle handle, int rowFirst, int rowLast, int colFirst, int colLast);
ERL_NIF_TERM c_xlSheetSetPrintArea(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row_first;

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

	int row_last;

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

	int col_first;

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

	int col_last;

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

	xlSheetSetPrintArea(sheet_resource->handle, row_first, row_last, col_first, col_last);

	return enif_make_atom(env, "nil");
}

// void xlSheetClearPrintRepeats(SheetHandle handle);
ERL_NIF_TERM c_xlSheetClearPrintRepeats(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	xlSheetClearPrintRepeats(sheet_resource->handle);

	return enif_make_atom(env, "nil");
}

// void xlSheetClearPrintArea(SheetHandle handle);
ERL_NIF_TERM c_xlSheetClearPrintArea(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	xlSheetClearPrintArea(sheet_resource->handle);

	return enif_make_atom(env, "nil");
}

// int xlSheetGetNamedRange(SheetHandle handle, const wchar_t* name, int* rowFirst, int* rowLast, int* colFirst, int* colLast, int scopeId, int* hidden);
ERL_NIF_TERM c_xlSheetGetNamedRange(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	ErlNifBinary name_temp;

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

	unsigned char *pt1 = createNullTermMbString(name_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_name[character_count1 + 1];

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

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

		return enif_make_badarg(env);
	}

	free(pt1);

	int scope_id;

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

	int rowFirst;
	int rowLast;
	int colFirst;
	int colLast;
	int hidden;

	int ret = xlSheetGetNamedRange(sheet_resource->handle, w_name, &rowFirst, &rowLast, &colFirst, &colLast, scope_id, &hidden);

	return enif_make_list6(env,
		enif_make_int(env, ret),
		enif_make_int(env, rowFirst),
		enif_make_int(env, rowLast),
		enif_make_int(env, colFirst),
		enif_make_int(env, colLast),
		enif_make_int(env, hidden)
	);
}

// int xlSheetSetNamedRange(SheetHandle handle, const wchar_t* name, int rowFirst, int rowLast, int colFirst, int colLast, int scopeId);
ERL_NIF_TERM c_xlSheetSetNamedRange(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	ErlNifBinary name_temp;

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

	unsigned char *pt1 = createNullTermMbString(name_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_name[character_count1 + 1];

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

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

		return enif_make_badarg(env);
	}

	free(pt1);

	int row_first;

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

	int row_last;

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

	int col_first;

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

	int col_last;

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

	int scope_id;

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

	int ret = xlSheetSetNamedRange(sheet_resource->handle, w_name, row_first, row_last, col_first, col_last, scope_id);

	return enif_make_int(env, ret);
}

// int xlSheetDelNamedRange(SheetHandle handle, const wchar_t* name, int scopeId);
ERL_NIF_TERM c_xlSheetDelNamedRange(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	ErlNifBinary name_temp;

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

	unsigned char *pt1 = createNullTermMbString(name_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_name[character_count1 + 1];

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

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

		return enif_make_badarg(env);
	}

	free(pt1);

	int scope_id;

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

	int ret = xlSheetDelNamedRange(sheet_resource->handle, w_name, scope_id);

	return enif_make_int(env, ret);
}

// int xlSheetNamedRangeSize(SheetHandle handle);
ERL_NIF_TERM c_xlSheetNamedRangeSize(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetNamedRangeSize(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// const wchar_t* xlSheetNamedRange(SheetHandle handle, int index, int* rowFirst, int* rowLast, int* colFirst, int* colLast, int* scopeId, int* hidden);
ERL_NIF_TERM c_xlSheetNamedRange(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int index;

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

	int rowFirst;
	int rowLast;
	int colFirst;
	int colLast;
	int scopeId;
	int hidden;

	const wchar_t *wstr = xlSheetNamedRange(sheet_resource->handle, index, &rowFirst, &rowLast, &colFirst, &colLast, &scopeId, &hidden);

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

	ErlNifBinary ret = convertWcharToMbBinary(wstr);

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

	return enif_make_list6(env,
		enif_make_binary(env, &ret),
		enif_make_int(env, rowFirst),
		enif_make_int(env, rowLast),
		enif_make_int(env, colFirst),
		enif_make_int(env, colLast),
		enif_make_int(env, hidden)
	);
}

// int xlSheetTableSize(SheetHandle handle);
ERL_NIF_TERM c_xlSheetTableSize(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetTableSize(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// const wchar_t* xlSheetTable(SheetHandle handle, int index, int* rowFirst, int* rowLast, int* colFirst, int* colLast, int* headerRowCount, int* totalsRowCount);
ERL_NIF_TERM c_xlSheetTable(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int index;

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

	int rowFirst;
	int rowLast;
	int colFirst;
	int colLast;
	int headerRowCount;
	int totalsRowCount;

	const wchar_t *wstr = xlSheetTable(sheet_resource->handle, index, &rowFirst, &rowLast, &colFirst, &colLast, &headerRowCount, &totalsRowCount);

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

	ErlNifBinary ret = convertWcharToMbBinary(wstr);

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

	return enif_make_list7(env,
		enif_make_binary(env, &ret),
		enif_make_int(env, rowFirst),
		enif_make_int(env, rowLast),
		enif_make_int(env, colFirst),
		enif_make_int(env, colLast),
		enif_make_int(env, headerRowCount),
		enif_make_int(env, totalsRowCount)
	);
}

// int xlSheetHyperlinkSize(SheetHandle handle);
ERL_NIF_TERM c_xlSheetHyperlinkSize(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetHyperlinkSize(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// const wchar_t* xlSheetHyperlink(SheetHandle handle, int index, int* rowFirst, int* rowLast, int* colFirst, int* colLast);
ERL_NIF_TERM c_xlSheetHyperlink(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int index;

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

	int rowFirst;
	int rowLast;
	int colFirst;
	int colLast;

	const wchar_t *wstr = xlSheetHyperlink(sheet_resource->handle, index, &rowFirst, &rowLast, &colFirst, &colLast);

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

	ErlNifBinary ret = convertWcharToMbBinary(wstr);

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

	return enif_make_list5(env,
		enif_make_binary(env, &ret),
		enif_make_int(env, rowFirst),
		enif_make_int(env, rowLast),
		enif_make_int(env, colFirst),
		enif_make_int(env, colLast)
	);
}

// int xlSheetDelHyperlink(SheetHandle handle, int index);
ERL_NIF_TERM c_xlSheetDelHyperlink(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int index;

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

	int ret = xlSheetDelHyperlink(sheet_resource->handle, index);

	return enif_make_int(env, ret);
}

// void xlSheetAddHyperlink(SheetHandle handle, const wchar_t* hyperlink, int rowFirst, int rowLast, int colFirst, int colLast);
ERL_NIF_TERM c_xlSheetAddHyperlink(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	ErlNifBinary hyper_link_temp;

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

	unsigned char *pt1 = createNullTermMbString(hyper_link_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_hyper_link[character_count1 + 1];

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

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

		return enif_make_badarg(env);
	}

	free(pt1);

	int row_fisrt;

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

	int row_last;

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

	int col_first;

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

	int col_last;

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

	xlSheetAddHyperlink(sheet_resource->handle, w_hyper_link, row_fisrt, row_last, col_first, col_last);

	return enif_make_atom(env, "nil");
}

// int xlSheetIsAutoFilter(SheetHandle handle);
ERL_NIF_TERM c_xlSheetIsAutoFilter(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetIsAutoFilter(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// void xlSheetApplyFilter(SheetHandle handle);
ERL_NIF_TERM c_xlSheetApplyFilter(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	xlSheetApplyFilter(sheet_resource->handle);

	return enif_make_atom(env, "nil");
}

// void xlSheetRemoveFilter(SheetHandle handle);
ERL_NIF_TERM c_xlSheetRemoveFilter(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	xlSheetRemoveFilter(sheet_resource->handle);

	return enif_make_atom(env, "nil");
}

// const wchar_t* xlSheetName(SheetHandle handle);
ERL_NIF_TERM c_xlSheetName(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	const wchar_t *wstr = xlSheetName(sheet_resource->handle);

	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);
}

// void xlSheetSetName(SheetHandle handle, const wchar_t* name);
ERL_NIF_TERM c_xlSheetSetName(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

	if (0 == enif_get_resource(env, argv[0], TypeOfSheet, (void**)&sheet_resource)) {
		return enif_make_badarg(env);
	}
	ErlNifBinary name_temp;

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

	unsigned char *pt1 = createNullTermMbString(name_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_name[character_count1 + 1];

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

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

		return enif_make_badarg(env);
	}

	free(pt1);

	xlSheetSetName(sheet_resource->handle, w_name);

	return enif_make_atom(env, "nil");
}

// int xlSheetProtect(SheetHandle handle);
ERL_NIF_TERM c_xlSheetProtect(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetProtect(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// void xlSheetSetProtect(SheetHandle handle, int protect);
ERL_NIF_TERM c_xlSheetSetProtect(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int protect;

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

	xlSheetSetProtect(sheet_resource->handle, protect);

	return enif_make_atom(env, "nil");
}

// void xlSheetSetProtectEx(SheetHandle handle, int protect, const wchar_t* password, int enhancedProtection);
ERL_NIF_TERM c_xlSheetSetProtectEx(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int protect;

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

	ErlNifBinary password_temp;

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

	unsigned char *pt1 = createNullTermMbString(password_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_password[character_count1 + 1];

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

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

		return enif_make_badarg(env);
	}

	free(pt1);

	int enhanced_protection;

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

	xlSheetSetProtectEx(sheet_resource->handle, protect, w_password, enhanced_protection);

	return enif_make_atom(env, "nil");
}

// int xlSheetHidden(SheetHandle handle);
ERL_NIF_TERM c_xlSheetHidden(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetHidden(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// int xlSheetSetHidden(SheetHandle handle, int hidden);
ERL_NIF_TERM c_xlSheetSetHidden(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int hidden;

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

	int ret = xlSheetSetHidden(sheet_resource->handle, hidden);

	return enif_make_int(env, ret);
}

// void xlSheetGetTopLeftView(SheetHandle handle, int* row, int* col);
ERL_NIF_TERM c_xlSheetGetTopLeftView(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;
	int col;

	xlSheetGetTopLeftView(sheet_resource->handle, &row, &col);

	return enif_make_list2(env,
		enif_make_int(env, row),
		enif_make_int(env, col)
	);
}

// void xlSheetSetTopLeftView(SheetHandle handle, int row, int col);
ERL_NIF_TERM c_xlSheetSetTopLeftView(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	xlSheetSetTopLeftView(sheet_resource->handle, row, col);

	return enif_make_atom(env, "nil");
}

// int xlSheetRightToLeft(SheetHandle handle);
ERL_NIF_TERM c_xlSheetRightToLeft(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetRightToLeft(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// void xlSheetSetRightToLeft(SheetHandle handle, int rightToLeft);
ERL_NIF_TERM c_xlSheetSetRightToLeft(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int right_to_left;

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

	xlSheetSetRightToLeft(sheet_resource->handle, right_to_left);

	return enif_make_atom(env, "nil");
}

// void xlSheetSetAutoFitArea(SheetHandle handle, int rowFirst, int colFirst, int rowLast, int colLast);
ERL_NIF_TERM c_xlSheetSetAutoFitArea(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row_first;

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

	int col_first;

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

	int row_last;

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

	int col_last;

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

	xlSheetSetAutoFitArea(sheet_resource->handle, row_first, col_first, row_last, col_last);

	return enif_make_atom(env, "nil");
}

// void xlSheetAddrToRowCol(SheetHandle handle, const wchar_t* addr, int* row, int* col, int* rowRelative, int* colRelative);
ERL_NIF_TERM c_xlSheetAddrToRowCol(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	ErlNifBinary addr_temp;

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

	unsigned char *pt1 = createNullTermMbString(addr_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_addr[character_count1 + 1];

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

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

		return enif_make_badarg(env);
	}

	free(pt1);

	int row;
	int col;
	int rowRelative;
	int colRelative;

	xlSheetAddrToRowCol(sheet_resource->handle, w_addr, &row, &col, &rowRelative, &colRelative);

	return enif_make_list4(env,
		enif_make_int(env, row),
		enif_make_int(env, col),
		enif_make_int(env, rowRelative),
		enif_make_int(env, colRelative)
	);
}

// const wchar_t* xlSheetRowColToAddr(SheetHandle handle, int row, int col, int rowRelative, int colRelative);
ERL_NIF_TERM c_xlSheetRowColToAddr(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	int row_relative;

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

	int col_relative;

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

	const wchar_t *wstr = xlSheetRowColToAddr(sheet_resource->handle, row, col, row_relative, col_relative);

	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);
}

// void xlSheetSetTabColor(SheetHandle handle, int color);
ERL_NIF_TERM c_xlSheetSetTabColor(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int color;

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

	xlSheetSetTabColor(sheet_resource->handle, color);

	return enif_make_atom(env, "nil");
}

// void xlSheetSetTabRgbColor(SheetHandle handle, int red, int green, int blue);
ERL_NIF_TERM c_xlSheetSetTabRgbColor(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int red;

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

	int green;

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

	int blue;

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

	xlSheetSetTabRgbColor(sheet_resource->handle, red, green, blue);

	return enif_make_atom(env, "nil");
}

// int xlSheetAddIgnoredError(SheetHandle handle, int rowFirst, int colFirst, int rowLast, int colLast, int iError);
ERL_NIF_TERM c_xlSheetAddIgnoredError(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row_first;

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

	int col_first;

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

	int row_last;

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

	int col_last;

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

	int i_error;

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

	int ret = xlSheetAddIgnoredError(sheet_resource->handle, row_first, col_first, row_last, col_last, i_error);

	return enif_make_int(env, ret);
}

// void xlSheetAddDataValidation(SheetHandle handle, int type, int op, int rowFirst, int rowLast, int colFirst, int colLast, const wchar_t* value1, const wchar_t* value2);
ERL_NIF_TERM c_xlSheetAddDataValidation(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int type;

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

	int op;

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

	int row_first;

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

	int col_first;

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

	int row_last;

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

	int col_last;

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

	ErlNifBinary value1_temp;

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

	unsigned char *pt1 = createNullTermMbString(value1_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_value1[character_count1 + 1];

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

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

		return enif_make_badarg(env);
	}

	free(pt1);

	ErlNifBinary value2_temp;

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

	unsigned char *pt2 = createNullTermMbString(value2_temp);

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

	size_t mbs_len2 = strlen((const char*)pt2);

	size_t character_count2 = mbstowcs(NULL, (const char*)pt2, mbs_len2);

	wchar_t w_value2[character_count2 + 1];

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

	if((size_t)-1 == mbstowcs(w_value2, (const char*)pt2, character_count2 + 1)) {
		free(pt2);

		return enif_make_badarg(env);
	}

	free(pt2);

	xlSheetAddDataValidation(sheet_resource->handle, type, op, row_first, row_last, col_first, col_last, w_value1, w_value2);

	return enif_make_atom(env, "nil");
}

// void xlSheetAddDataValidationEx(SheetHandle handle, int type, int op, int rowFirst, int rowLast, int colFirst, int colLast, const wchar_t* value1, const wchar_t* value2, int allowBlank, int hideDropDown, int showInputMessage, int showErrorMessage, const wchar_t* promptTitle, const wchar_t* prompt, const wchar_t* errorTitle, const wchar_t* error, int errorStyle);
ERL_NIF_TERM c_xlSheetAddDataValidationEx(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int type;

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

	int op;

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

	int row_first;

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

	int col_first;

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

	int row_last;

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

	int col_last;

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

	ErlNifBinary value1_temp;

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

	unsigned char *pt1 = createNullTermMbString(value1_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_value1[character_count1 + 1];

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

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

		return enif_make_badarg(env);
	}

	free(pt1);

	ErlNifBinary value2_temp;

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

	unsigned char *pt2 = createNullTermMbString(value2_temp);

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

	size_t mbs_len2 = strlen((const char*)pt2);

	size_t character_count2 = mbstowcs(NULL, (const char*)pt2, mbs_len2);

	wchar_t w_value2[character_count2 + 1];

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

	if((size_t)-1 == mbstowcs(w_value2, (const char*)pt2, character_count2 + 1)) {
		free(pt2);

		return enif_make_badarg(env);
	}

	free(pt2);

	int allow_blank;

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

	int hide_drop_down;

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

	int show_input_message;

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

	int show_error_message;

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

	ErlNifBinary prompt_title_temp;

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

	unsigned char *pt3 = createNullTermMbString(prompt_title_temp);

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

	size_t mbs_len3 = strlen((const char*)pt3);

	size_t character_count3 = mbstowcs(NULL, (const char*)pt3, mbs_len3);

	wchar_t w_prompt_title[character_count3 + 1];

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

	if((size_t)-1 == mbstowcs(w_prompt_title, (const char*)pt3, character_count3 + 1)) {
		free(pt3);

		return enif_make_badarg(env);
	}

	free(pt3);

	ErlNifBinary prompt_temp;

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

	unsigned char *pt4 = createNullTermMbString(prompt_temp);

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

	size_t mbs_len4 = strlen((const char*)pt4);

	size_t character_count4 = mbstowcs(NULL, (const char*)pt4, mbs_len4);

	wchar_t w_prompt[character_count4 + 1];

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

	if((size_t)-1 == mbstowcs(w_prompt, (const char*)pt4, character_count4 + 1)) {
		free(pt4);

		return enif_make_badarg(env);
	}

	free(pt4);

	ErlNifBinary error_title_temp;

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

	unsigned char *pt5 = createNullTermMbString(error_title_temp);

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

	size_t mbs_len5 = strlen((const char*)pt5);

	size_t character_count5 = mbstowcs(NULL, (const char*)pt5, mbs_len5);

	wchar_t w_error_title[character_count5 + 1];

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

	if((size_t)-1 == mbstowcs(w_error_title, (const char*)pt5, character_count5 + 1)) {
		free(pt5);

		return enif_make_badarg(env);
	}

	free(pt5);

	ErlNifBinary error_temp;

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

	unsigned char *pt6 = createNullTermMbString(error_temp);

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

	size_t mbs_len6 = strlen((const char*)pt6);

	size_t character_count6 = mbstowcs(NULL, (const char*)pt6, mbs_len6);

	wchar_t w_error[character_count6 + 1];

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

	if((size_t)-1 == mbstowcs(w_error, (const char*)pt6, character_count6 + 1)) {
		free(pt6);

		return enif_make_badarg(env);
	}

	free(pt6);

	int error_style;

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

	xlSheetAddDataValidationEx(sheet_resource->handle, type, op, row_first, row_last, col_first, col_last, w_value1, w_value2, allow_blank, hide_drop_down, show_input_message, show_error_message, w_prompt_title, w_prompt, w_error_title, w_error, error_style);

	return enif_make_atom(env, "nil");
}

// void xlSheetAddDataValidationDouble(SheetHandle handle, int type, int op, int rowFirst, int rowLast, int colFirst, int colLast, double value1, double value2);
ERL_NIF_TERM c_xlSheetAddDataValidationDouble(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int type;

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

	int op;

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

	int row_first;

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

	int col_first;

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

	int row_last;

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

	int col_last;

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

	double value1;

	if (0 == enif_get_double(env, argv[7], &value1)) {
		return enif_make_badarg(env);
	}

	double value2;

	if (0 == enif_get_double(env, argv[8], &value2)) {
		return enif_make_badarg(env);
	}

	xlSheetAddDataValidationDouble(sheet_resource->handle, type, op, row_first, row_last, col_first, col_last, value1, value2);

	return enif_make_atom(env, "nil");
}

// void xlSheetAddDataValidationDoubleEx(SheetHandle handle, int type, int op, int rowFirst, int rowLast, int colFirst, int colLast, double value1, double value2, int allowBlank, int hideDropDown, int showInputMessage, int showErrorMessage, const wchar_t* promptTitle, const wchar_t* prompt, const wchar_t* errorTitle, const wchar_t* error, int errorStyle);
ERL_NIF_TERM c_xlSheetAddDataValidationDoubleEx(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int type;

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

	int op;

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

	int row_first;

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

	int col_first;

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

	int row_last;

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

	int col_last;

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

	double value1;

	if (0 == enif_get_double(env, argv[7], &value1)) {
		return enif_make_badarg(env);
	}

	double value2;

	if (0 == enif_get_double(env, argv[8], &value2)) {
		return enif_make_badarg(env);
	}

	int allow_blank;

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

	int hide_drop_down;

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

	int show_input_message;

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

	int show_error_message;

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

	ErlNifBinary prompt_title_temp;

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

	unsigned char *pt1 = createNullTermMbString(prompt_title_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_prompt_title[character_count1 + 1];

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

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

		return enif_make_badarg(env);
	}

	free(pt1);

	ErlNifBinary prompt_temp;

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

	unsigned char *pt2 = createNullTermMbString(prompt_temp);

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

	size_t mbs_len2 = strlen((const char*)pt2);

	size_t character_count2 = mbstowcs(NULL, (const char*)pt2, mbs_len2);

	wchar_t w_prompt[character_count2 + 1];

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

	if((size_t)-1 == mbstowcs(w_prompt, (const char*)pt2, character_count2 + 1)) {
		free(pt2);

		return enif_make_badarg(env);
	}

	free(pt2);

	ErlNifBinary error_title_temp;

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

	unsigned char *pt3 = createNullTermMbString(error_title_temp);

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

	size_t mbs_len3 = strlen((const char*)pt3);

	size_t character_count3 = mbstowcs(NULL, (const char*)pt3, mbs_len3);

	wchar_t w_error_title[character_count3 + 1];

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

	if((size_t)-1 == mbstowcs(w_error_title, (const char*)pt3, character_count3 + 1)) {
		free(pt3);

		return enif_make_badarg(env);
	}

	free(pt3);

	ErlNifBinary error_temp;

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

	unsigned char *pt4 = createNullTermMbString(error_temp);

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

	size_t mbs_len4 = strlen((const char*)pt4);

	size_t character_count4 = mbstowcs(NULL, (const char*)pt4, mbs_len4);

	wchar_t w_error[character_count4 + 1];

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

	if((size_t)-1 == mbstowcs(w_error, (const char*)pt4, character_count4 + 1)) {
		free(pt4);

		return enif_make_badarg(env);
	}

	free(pt4);

	int error_style;

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

	xlSheetAddDataValidationDoubleEx(sheet_resource->handle, type, op, row_first, row_last, col_first, col_last, value1, value2, allow_blank, hide_drop_down, show_input_message, show_error_message, w_prompt_title, w_prompt, w_error_title, w_error, error_style);

	return enif_make_atom(env, "nil");
}

// void xlSheetRemoveDataValidations(SheetHandle handle);
ERL_NIF_TERM c_xlSheetRemoveDataValidations(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	xlSheetRemoveDataValidations(sheet_resource->handle);

	return enif_make_atom(env, "nil");
}

// FormatHandle xlSheetCellFormat(SheetHandle handle, int row, int col);
ERL_NIF_TERM c_xlSheetCellFormat(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int row;

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

	int col;

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

	FormatHandle format_handle = xlSheetCellFormat(sheet_resource->handle, row, col);

	if(!format_handle) {
		return enif_make_atom(env, "nil");
	} else {
		FormatType *ret = enif_alloc_resource(TypeOfFormat, sizeof(FormatType));

		ret->handle = format_handle;

		ERL_NIF_TERM handle = enif_make_resource(env, ret);

		enif_release_resource(ret);

		return handle;
	}
}

// AutoFilterHandle xlSheetAutoFilter(SheetHandle handle);
ERL_NIF_TERM c_xlSheetAutoFilter(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	AutoFilterHandle auto_filter_handle = xlSheetAutoFilter(sheet_resource->handle);

	if(!auto_filter_handle) {
		return enif_make_atom(env, "nil");
	} else {
		AutofilterType *ret = enif_alloc_resource(TypeOfAutofilter, sizeof(AutofilterType));

		ret->handle = auto_filter_handle;

		ERL_NIF_TERM handle = enif_make_resource(env, ret);

		enif_release_resource(ret);

		return handle;
	}
}

// int xlSheetFormControlSize(SheetHandle handle);
ERL_NIF_TERM c_xlSheetFormControlSize(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int ret = xlSheetFormControlSize(sheet_resource->handle);

	return enif_make_int(env, ret);
}

// FormControlHandle xlSheetFormControl(SheetHandle handle, int index);
ERL_NIF_TERM c_xlSheetFormControl(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	SheetType *sheet_resource = NULL;

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

	int index;

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

	FormControlHandle form_control_handle = xlSheetFormControl(sheet_resource->handle, index);

	if(!form_control_handle) {
		return enif_make_atom(env, "nil");
	} else {
		FormControlType *ret = enif_alloc_resource(TypeOfFormControl, sizeof(FormControlType));

		ret->handle = form_control_handle;

		ERL_NIF_TERM handle = enif_make_resource(env, ret);

		enif_release_resource(ret);

		return handle;
	}
}
