#include "mexToolbox.h"

void mexPrintFormat(int bufferSize, string strTemplate, int first)
{
	char * buffer = new char[bufferSize];
	sprintf_s(buffer, bufferSize, strTemplate.c_str(), first);
	mexPrintf(buffer);
	delete buffer;
}

void mexPrintFormat(int bufferSize, string strTemplate, int first, int second)
{
	char * buffer = new char[bufferSize];
	sprintf_s(buffer, bufferSize, strTemplate.c_str(), first, second);
	mexPrintf(buffer);
	delete buffer;
}

void mexPrintFormat(int bufferSize, string strTemplate, int first, int second, int third)
{
	char * buffer = new char[bufferSize];
	sprintf_s(buffer, bufferSize, strTemplate.c_str(), first, second, third);
	mexPrintf(buffer);
	delete buffer;
}

void mexPrintFormat(int bufferSize, string strTemplate, int first, int second, double third)
{
	char * buffer = new char[bufferSize];
	sprintf_s(buffer, bufferSize, strTemplate.c_str(), first, second, third);
	mexPrintf(buffer);
	delete buffer;
}

void mexPrintFormat(int bufferSize, string strTemplate, int first, double second, double third)
{
	char * buffer = new char[bufferSize];
	sprintf_s(buffer, bufferSize, strTemplate.c_str(), first, second, third);
	mexPrintf(buffer);
	delete buffer;
}

bool validateParamCount(int input, int givenInputs, int output, int givenOutput)
{
	int bufferSize = 1000;
	char * buffer = new char[bufferSize];

	if (input != givenInputs)
	{
		sprintf_s(buffer, bufferSize, "%i inputs are expected. Terminating.", input);
		mexErrMsgIdAndTxt("MyToolbox:myFuncRevision:nrhs", buffer);
		return false;
	}

	if (output != givenOutput)
	{
		sprintf_s(buffer, bufferSize, "The function produces %i outputs. Terminating.", output);
		mexErrMsgIdAndTxt("MyToolbox:myFuncRevision:nlhs", buffer);
		return false;
	}
	return true;
}

void mexPrintIntArray(int dim, int * arr)
{
	mexPrintf("Dim: %i. Accepted index: (", dim);
	for (int i = 0; i < dim; i++)
	{
		mexPrintf("%i", arr[i]);
		if (i != dim - 1)
			mexPrintf(",");
	}
	mexPrintf(")\n");
}

int getFlatIndex(int dim, int * offsets, ...)
{
	va_list vl;
	va_start(vl, offsets);
	int finalIndex = 0;
	for (int i = 0; i < dim; i++)
	{
		finalIndex += offsets[i] * va_arg(vl, int);
	}
	va_end(vl);
	return finalIndex;
}

int getFlatIndex(int dim, size_t * offsets, ...)
{
	va_list vl;
	va_start(vl, offsets);
	int finalIndex = 0;
	for (int i = 0; i < dim; i++)
	{
		finalIndex += offsets[i] * va_arg(vl, int);
	}
	va_end(vl);
	return finalIndex;
}

int * mexGetOffsetArray(int dimNum, const size_t * dimSizes)
{
	int * offsets = new int[dimNum];
	offsets[0] = 1;
	for (int i = 1; i < dimNum; i++)
	{
		offsets[i] = offsets[i - 1] * dimSizes[i - 1];
	}
	return offsets;
}

int checkIndexInRange(int dim, int * offsets, ...)
{
	va_list vl;
	va_start(vl, offsets);
	int finalIndex = 0;
	for (int i = 0; i < dim; i++)
	{
		finalIndex += offsets[i] * va_arg(vl, int);
	}
	va_end(vl);
	return finalIndex;
}
