#include "c4d_memory.h"
#include "c4d_general.h"
#include "c4d_coffee.h"

Coffee* Coffee::Alloc()
{
	return C4DOS.Co->GeCoffeeAlloc();
}

void Coffee::Free(Coffee* &cof)
{
	C4DOS.Co->GeCoffeeFree(cof);
}

Bool GeCoffeeCompileString(Coffee* cof, const String& src)
{
	return C4DOS.Co->GeCoffeeCompileString(cof,src);
}

Bool GeCoffeeCompileFile(Coffee* cof, const Filename& file)
{
	return C4DOS.Co->GeCoffeeCompileFile(cof,file);
}

Coffee *GetCoffeeMaster(void)
{
	return C4DOS.Co->CoGetMaster();
}

VALUE* GeCoffeeAddGlobalSymbol(Coffee* cof, const String& name)
{
	return C4DOS.Co->GeCoffeeAddGlobalSymbol(cof,name);
}

VALUE* GeCoffeeFindGlobalSymbol(Coffee* cof, const String& name)
{
	return C4DOS.Co->GeCoffeeFindGlobalSymbol(cof,name);
}

Bool GeCoffeeExecute(Coffee* cof, VALUE* func, GeData* retval, GeData* arg1, GeData* arg2, GeData* arg3)
{
	return C4DOS.Co->GeCoffeeExecute(cof,func,retval,arg1,arg2,arg3);
}

Bool GeCoffeeGeData2Value(Coffee* cof, const GeData& src, VALUE* dest)
{
	return C4DOS.Co->GeCoffeeGeData2Value(cof,src,dest);
}

Bool GeCoffeeValue2GeData(Coffee* cof, VALUE *src, GeData* dest)
{
	return C4DOS.Co->GeCoffeeValue2GeData(cof,src,dest);
}

Bool GeCoffeeGetLastError(Coffee* cof, String *err_string, LONG *err_line, LONG *err_pos)
{
	return C4DOS.Co->GeCoffeeGetLastError(cof,err_string,err_line,err_pos);
}

Bool CoffeeEditor_Open(BaseList2D *obj,CoffeeEditorCallback *callback)
{
	return C4DOS.Co->CoffeeEditor_Open(obj,callback);
}

OBJECT *Coffee::AllocDynamic(BaseList2D *bl, Bool coffeeallocation)
{
	return C4DOS.Co->CoAllocDynamic(this, bl, coffeeallocation);
}
CLASS *Coffee::AddInheritance(LONG id, const String &name, const String &from, Bool use_constructor)
{
	return C4DOS.Co->CoAddInheritance(this, id, name, from, use_constructor);
}
Bool Coffee::CompileFile(const Filename &fn, Bool tofile)
{
	return C4DOS.Co->CoCompileFile(this, fn, tofile);
}

VALUE::VALUE(void)
{
	v_type = COFFEE_VTYPE_NIL;
}

Bool VALUE::IsType(COFFEE_VTYPE type) const
{
	if (type == COFFEE_VTYPE_NUMBER)
	{
		if (v_type == COFFEE_VTYPE_LONG) return TRUE;
		if (v_type == COFFEE_VTYPE_FLOAT) return TRUE;
		return FALSE;
	}
	return (type == v_type);
}

LONG VALUE::GetLong(LONG *err) const
{
	LONG r = 0;
	if (err) *err = 0;
	if (v_type == COFFEE_VTYPE_LONG) r = v.v_integer;
	else if (v_type == COFFEE_VTYPE_FLOAT) r = (LONG)v.v_float;
	else if (err) *err = -1;
	return r;
}

Real VALUE::GetReal(LONG *err) const
{
	Real r = 0.0;
	if (err) *err = 0;
	if (v_type == COFFEE_VTYPE_LONG) r = (Real)v.v_integer;
	else if (v_type == COFFEE_VTYPE_FLOAT) r = v.v_float;
	else if (err) *err = -1;
	return r;
}

Vector VALUE::GetVector(LONG *err) const
{
	if (err) *err = 0;
	if (v_type == COFFEE_VTYPE_VECTOR) return (*((Vector*)v.v_vector));
	else if (err) *err = -1;
	return 0.0;
}

void* VALUE::GetVoid(LONG *err) const
{
	if (err) *err = 0;
	if (v_type == COFFEE_VTYPE_VOID) return v.v_void;
	else if (err) *err = -1;
	return NULL;
}

OBJECT* VALUE::GetObject(LONG *err)
{
	return C4DOS.Co->CoValGetObject(this,err);
}

Bool VALUE::IsInstanceOf(VALUE *cl, LONG *err)
{
	return C4DOS.Co->CoValIsInstanceOf(this,cl,err);
}

COFFEE_VTYPE VALUE::GetType(void) const
{
	return v_type;
}

void VALUE::SetNil(void)
{
	v_type = COFFEE_VTYPE_NIL;
	v.v_integer = 0;
}

void VALUE::SetLong(LONG i)
{
	v_type = COFFEE_VTYPE_LONG;
	v.v_integer = i;
}

void VALUE::SetReal(Real f)
{
	v_type = COFFEE_VTYPE_FLOAT;
	v.v_float = f;
}

void VALUE::SetVector(const Vector &ve)
{
	v_type = COFFEE_VTYPE_VECTOR;
	(*((Vector*)v.v_vector)) = ve;
}

void VALUE::SetString(CSTRING *s)
{
	C4DOS.Co->CoValSetString(this,s);
}

void VALUE::SetArray(ARRAY *a)
{
	C4DOS.Co->CoValSetArray(this,a);
}

void VALUE::SetObject(OBJECT *o)
{
	C4DOS.Co->CoValSetObject(this,o);
}

void VALUE::SetVoid(const void *vo)
{
	v_type = COFFEE_VTYPE_VOID;
	v.v_void = (void*)vo;
}

String VALUE::GetString(void) 
{
	return C4DOS.Co->CoValGetString(this);
}

VALUE* VALUE::GetArrayMember(LONG i) 
{
	return C4DOS.Co->CoValGetArrayMember(this,i);
}

VALUE* VALUE::GetObjMember(LONG i) 
{
	return C4DOS.Co->CoValGetObjMember(this,i);
}

LONG VALUE::GetSize(void) 
{
	return C4DOS.Co->CoValGetSize(this);
}

UCHAR* VALUE::GetBytes(void) 
{
	return C4DOS.Co->CoValGetBytes(this);
}

void Coffee::ErrCheckType(VALUE *v, COFFEE_VTYPE type, LONG *err)
{
	C4DOS.Co->CoErrCheckType(this,v,type,err);
}

void Coffee::ErrCheckObjectType(VALUE *v, const String &cl_name, LONG *err)
{
	C4DOS.Co->CoErrCheckObjectType(this,v,cl_name,err);
}

void Coffee::ErrCheckArgCount(LONG argc, LONG cnt, LONG *err)
{
	C4DOS.Co->CoErrCheckArgCount(this,argc,cnt,err);
}

CSTRING*	Coffee::AllocString(const String &s)
{
	return C4DOS.Co->CoAllocString(this,s);
}

OBJECT*	Coffee::NewObject(const String &cl_name)
{
	return C4DOS.Co->CoNewObject(this,cl_name);
}

Bool	Coffee::AddClassMethod(const String &name, CLASS *c, COFFEE_STYPE type, V_CODE fcn, LONG argc)
{
	return C4DOS.Co->CoAddClassMethod(this,name,c,type,fcn,argc);
}

VALUE*	Coffee::GetGlobalClass(const String &name)
{
	return C4DOS.Co->CoGetGlobalClass(this,name);
}

void Coffee::Wrongcnt(LONG n, LONG cnt)
{
	C4DOS.Co->CoWrongcnt(this,n,cnt);
}

CLASS* Coffee::AddGlobalClass(const String &name, const String &parent)
{
	return C4DOS.Co->CoAddGlobalClass(this,name,parent);
}

Bool Coffee::AddClassMember(const String &name, CLASS *c, COFFEE_STYPE type)
{
	return C4DOS.Co->CoAddClassMember(this,name,c,type);
}

ARRAY* Coffee::NewArray(LONG size)
{
	return C4DOS.Co->CoNewArray(this,size);
}

Bool Coffee::AddGlobalSymbol(const String &name, const VALUE *v, COFFEE_STYPE type)
{
	return C4DOS.Co->CoAddGlobalSymbol(this,name,v,type);
}

Bool	Coffee::AddGlobalFunction(const String &name, V_CODE fcn)
{
	return C4DOS.Co->CoAddGlobalFunction(this,name,fcn);
}

LONG Coffee::GetType(void)
{
	return C4DOS.Co->CoGetType(this);
}

const Filename&	Coffee::GetRootFile(void)
{
	return C4DOS.Co->CoGetRootFile(this);
}

void Coffee::SetRootFile(const Filename &fn)
{
	C4DOS.Co->CoSetRootFile(this,fn);
}

void Coffee::SetError(LONG type,const String &s1, const String &s2)
{
	C4DOS.Co->CoSetError(this,type,s1,s2);
}

void Coffee::InstallErrorHook(COFFEE_ERRORHANDLER *priv_hndl, void *priv_data)
{
	C4DOS.Co->CoInstallErrorHook(this,priv_hndl,priv_data);
}
