def gLinkedClassConstructors = {};
def gLinkedClasses = {};
def gLinkedObjectTable = {};
def gLinkedDynCallTable = {};

def gLinkedClassNames = {};

function RegisterLinkedClass(theClassName, theClass)
{
	//print("RegisterLinkedClass: "..theClassName);
	gLinkedClasses[theClassName] = theClass;
}

function RegisterLinkedConstructor(theClassName, theConstructor)
{
	gLinkedClassConstructors[theClassName] = theConstructor;
}

function CreateLinkedObject(theClassName, theCObj)	
{
	if (gLinkedObjectTable[theCObj] != nil)
		return;
	
	gLinkedClassNames[theCObj] = theClassName;
	
	local aClass = gLinkedClasses[theClassName];
	if (aClass)
	{
		gLinkedDynCallTable.a = aClass["new"];
		local aLuaObject = gLinkedDynCallTable@aClass:a(theCObj);
		gLinkedObjectTable[theCObj] = aLuaObject;
	}
	else
	{
		local aConstructor = gLinkedClassConstructors[theClassName];
		local aLuaObject = aConstructor(theCObj);
		gLinkedObjectTable[theCObj] = aLuaObject;
	}
}

function SetLinkedObject(theCObj, theLuaObject)
{
	:gLinkedObjectTable[theCObj] = theLuaObject;
}

function DeleteLinkedObject(theCObj)
{
	local anObj = :gLinkedObjectTable[theCObj];
	if (anObj == nil)
		return;
	
	//print("DeleteLinkedObject: class = "..gLinkedClassNames[theCObj]..", address = "..tostring(theCObj));
	gLinkedClassNames[theCObj] = nil;
	
	if (table.contains(anObj, "CObjDeleted"))
		anObj:CObjDeleted();

	:gLinkedObjectTable[theCObj] = nil;
}

function CallLinkedMethod(theCObject, theMethodName, ...)
{
	local aLuaObject = gLinkedObjectTable[theCObject];	
	:gLinkedDynCallTable.a = aLuaObject[theMethodName];	
	return gLinkedDynCallTable@aLuaObject:a(unpack(arg));
}

function GetLinkedLuaObject(theCObject)
{
	return gLinkedObjectTable[theCObject];
}
