#include <stdio.h>
#include <string>
#include <vector>
#include <mex.h>

#include <mexhelper.h>

void testMexConvertDouble (mxArray *t)
{
	double d;
	bool res = mexConvert(t, d);
	mexPrintf("mexConvert<double>(): %i - %.2f\n", res, d);
}

void testMexConvertInt (mxArray *t)
{
	int i;
	bool res = mexConvert(t, i);
	mexPrintf("mexConvert<int>(): %i - %i\n", res, i);
}

template<class T> void iterate (const T &obj, void (*func) (const T &obj))
{
	for (typename T::const_iterator i=obj.begin(); i!=obj.end(); i++)
		func(*i);
}

template<class T> const char *prettyPrint (const T &obj);

template<class T> const char *prettyPrint (const std::vector<T> &vec)
{
	std::string ret = "";
	typedef typename std::vector<T>::const_iterator iterT;
	for (iterT i=vec.begin(); i!=vec.end(); i++)
	{
		ret += prettyPrint(*i);
		ret += ", ";
	}
	return ret.c_str();
}

template<> const char *prettyPrint (const double &d)
{
	char *buf = (char *)malloc(20);
	snprintf(buf, 20, "%.2f", d);
	return buf;
}

void testMexConvertVector (mxArray *t)
{
	std::vector<double> vec(3);
	bool res = mexConvert(t, vec);
	mexPrintf("mexConvert<vector>(): %i - %s\n", res, prettyPrint(vec));
}

void testMexConvertVectorVector (mxArray *t)
{
	std::vector<std::vector<double> > vec(3);
	for (int i=0;i<3;i++)
		vec[i].resize(2);
	bool res = mexConvert(t, vec);
	mexPrintf("mexConvert<vector>(): %i - %s\n", res, prettyPrint(vec));
}

extern "C"
{
void mexFunction (int nresults, mxArray **arrresults, int nargs,
		const mxArray **arrargs)
{
	mxArray **t = (mxArray **)malloc(2*sizeof(mxArray*));
	t[0] = mxCreateDoubleScalar(42.5);
	t[1] = mxCreateDoubleMatrix(3, 1, mxREAL);

	for (int i=0;i<2;i++)
	{
		testMexConvertDouble(t[i]);
		testMexConvertInt(t[i]);
		testMexConvertVector(t[i]);
		testMexConvertVectorVector(t[i]);
	}

	matrix<double> foo(3, 2);
	mexConvert(foo, *arrresults);
}
}
