import DynamicCall;

import std.stdio;

Param createParam(T)(T value)
{
	//T* ptr = new T;	// BUG! Doesn't work for delegate type
	T* ptr = cast(T*)(new void[T.sizeof]).ptr;
	*ptr = value;

	Param param;
	param.type = ParamTypeFromT!(T);
	param.ptr = cast(void*)ptr;

	return param;
}

struct b1
{
	char c;
}

struct b2
{
	wchar w;
}

struct b4
{
	dchar d;
}

real foo(byte b, short s, int i, long l, float f, double d, real r, b1 c, b2 w, b4 d2, int function() func, int delegate() dg, int* ptr)
{
	writeln(b + s + i + l + f + d + r + c.c + w.w + d2.d + func() + dg() + *ptr);

	return 13;
}

int func()
{
	return 42;
}

void main()
{
	int dg()
	{
		return 14;
	}

	Call call;
	call.funcptr = &foo;
	
	int* i = new int;
	*i = 128;

	call.input ~= createParam!(byte)(cast(byte)1);
	call.input ~= createParam!(short)(200);
	call.input ~= createParam!(int)(4);
	call.input ~= createParam!(long)(cast(long)8);
	call.input ~= createParam!(float)(16.0f);
	call.input ~= createParam!(double)(32.0);
	call.input ~= createParam!(real)(64.0);
	call.input ~= createParam!(b1)(b1(1));
	call.input ~= createParam!(b2)(b2(2));
	call.input ~= createParam!(b4)(b4(4));
	call.input ~= createParam!(int function())(&func);
	call.input ~= createParam!(int delegate())(&dg);
	call.input ~= createParam!(int*)(i);

	call.output.type = ParamType.Real;
	call.output.ptr = new real;

	makeDynamicCall(&call);
	
	writeln(*cast(real*)call.output.ptr);
}