--
-- BaleFork
--
-- @author Geri-G
-- @date  15/07/2011 v1.0 LS11
-- @web www.geri-g.de
--
-- Copyright (C) Geri-G, All Rights Reserved.

BaleFork = {};
function BaleFork.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Attachable, specializations);
end;

function BaleFork:load(xmlFile)
	if self.baleSetDown == nil then	
		self.baleSetDown = BaleFork.baleSetDown;
		self.GetBaleInRange = BaleFork.GetBaleInRange;
		self.attachobjects = BaleFork.attachobjects;
		self.detachobjects = BaleFork.detachobjects;
		self.OrientJoint = BaleFork.OrientJoint;
		self.baleSearcher = {};

		local i=0;
		while true do
			local baleSearcher = {};
			local baseName = string.format("vehicle.baleSearchers.baleSearcher(%d)",i);
			local reportNode = Utils.indexToObject(self.components, getXMLString(xmlFile,baseName.."#reportNode"));
			local attachNode = Utils.indexToObject(self.components, Utils.getNoNil(getXMLString(xmlFile,baseName.."#attachNode"),"0>"));
			if reportNode == nil then
				break;
			end;
			baleSearcher.reportNode = reportNode;
			baleSearcher.attachNode = attachNode;
			baleSearcher.hasCallBack = false;
			baleSearcher.forceThreshold = Utils.getNoNil(getXMLFloat(xmlFile,baseName.."#forceThreshold"), 0.001);
			i=i+1;
			self.baleSearcher[reportNode] = baleSearcher;
		end;
		self.balesAttached = false;
		self.foundedBales = {};
		self.foundedObjects = {};
		self.Attachedobjects = {};

		if self.isServer then	
			for k,v in pairs(self.baleSearcher) do
				if not v.hasCallBack then
				--print("callback "..k);
					addContactReport(v.reportNode, v.forceThreshold, "GetBaleInRange", self);
					v.hasCallBack = true;			
				end;
			end;
		end;
	end;
end;

function BaleFork:delete()
end;
function BaleFork:onDetach()
	if self.isServer then	
		for k,v in pairs(self.baleSearcher) do
			if v.hasCallBack then
				removeContactReport(v.reportNode);
				v.hasCallBack = false;			
			end;
		end;
	end;
end;
function BaleFork:onAttach()
	if self.isServer then	
		for k,v in pairs(self.baleSearcher) do
			if not v.hasCallBack then
			--print("callback "..k);
				addContactReport(v.reportNode, v.forceThreshold, "GetBaleInRange", self);
				v.hasCallBack = true;			
			end;
		end;
	end;
end;

function BaleFork:mouseEvent(posX, posY, isDown, isUp, button)
end;

function BaleFork:keyEvent(unicode, sym, modifier, isDown)
end;

function BaleFork:update(dt)

end;

function BaleFork:updateTick(dt)

end;

function BaleFork:OrientJoint(Source, Target)	
	local xw, yw, zw = getWorldTranslation(Source);		
	local x,y,z = worldToLocal(getParent(Target), xw, yw, zw);	
	setTranslation(Target, x,y,z);			
	--JointRotation Anpassung an das Objekt
	local zX, zY, zZ = localDirectionToWorld(Source, 0,0,1);
	local zX, zY, zZ = worldDirectionToLocal(getParent(Target), zX, zY, zZ);
	local yX, yY, yZ = localDirectionToWorld(Source, 0,1,0);
	local yX, yY, yZ = worldDirectionToLocal(getParent(Target), yX, yY, yZ);
	setDirection(Target, zX, zY, zZ, yX, yY, yZ);
	return false;
end;

function BaleFork:attachobjects(object,baleT,attacherTable)
	self.balesAttached = true;
	local attachedobject = {};
	attachedobject.object = object;
	if self.isServer then
		attachedobject.AT = createTransformGroup("AT");
		link(attacherTable.attachNode,attachedobject.AT);
		
		attachedobject.objectMass = getMass(object);
		setMass(object,attachedobject.objectMass*0.6);
		
		self:OrientJoint(object,attachedobject.AT);

		local constr = JointConstructor:new();					
		constr:setActors(attacherTable.attachNode, object);
		constr:setJointTransforms(attachedobject.AT,  object);
		for i=1, 3 do
			constr:setTranslationLimit(i-1, true, 0, 0);
			constr:setRotationLimit(i-1,0,0);
		end;
		attachedobject.JointIndex = constr:finalize();
		
		if baleT ~= nil then
			attachedobject.baleT = baleT;
			baleT.isAttached = true;
		end;
	end;

	self.Attachedobjects[object] = attachedobject;
	return true;
end;

function BaleFork:detachobjects(object)
	if self.isServer and object==nil then
		for k,v in pairs(self.Attachedobjects) do
			removeJoint(v.JointIndex);
			delete(v.AT);
			v.JointIndex = nil;
			setMass(v.object,v.objectMass);
			removeContactReport(v.object);
			if v.baleT ~= nil then
				v.baleT.isAttached = nil;
			end;
		end;
		self.Attachedobjects = nil;
		self.Attachedobjects = {};
		self.balesAttached = false;
	elseif self.isServer and object~=nil then
		v = self.Attachedobjects[object];
		removeJoint(v.JointIndex);
		delete(v.AT);
		v.JointIndex = nil;
		setMass(v.object,v.objectMass);
		removeContactReport(v.object);
		if v.baleT ~= nil then
			v.baleT.isAttached = nil;
		end;
		 self.Attachedobjects[object] = nil;
	end;
end;

function BaleFork:draw()
end;
function BaleFork:GetBaleInRange(objectId, otherObjectId, isStart, normalForce, tangentialForce)
	local object = g_currentMission:getNodeObject(otherObjectId);
	local vehicle = g_currentMission.nodeToVehicle[otherObjectId];

	if object ~= nil and isStart then
		if object:isa(Bale) and not object.isAttached and self.foundedBales[otherObjectId] == nil then 
			object.objectId222222 = objectId;
			self.foundedBales[otherObjectId] = object;
			--print("founded "..tostring(otherObjectId));
			object.attacherV = self;
			addContactReport(otherObjectId, 0.01, "baleSetDown", self);

		end;
	elseif object ~= nil and not isStart and self.Attachedobjects[otherObjectId]==nil then
		--print("removeCP");
		removeContactReport(otherObjectId);
		self.foundedBales[otherObjectId] = nil;
	end;
end;
function BaleFork:baleSetDown(objectId, otherObjectId, isStart, normalForce, tangentialForce)
	local object = self.Attachedobjects[objectId];
	local object2 = self.foundedBales[objectId];
	--print(tostring(objectId).." baleSetDown "..otherObjectId.." isStart "..tostring(isStart).." object1 "..tostring(object).." object2 "..tostring(object2));
	if object ~= nil and isStart then
		--print("abmachen2");
		self:detachobjects(objectId);
	elseif object2~= nil and not isStart then
		--print("festmachen 2");
		if otherObjectId ~= object2.objectId222222 then	
			--print("festmachen 3");
			self:attachobjects(object2.nodeId,object2,self.baleSearcher[object2.objectId222222]);
			object2.objectId222222 = nil;
			self.foundedBales[objectId] = nil;
		end;
	end;
end;
local oldBaledelete =Bale.delete;
Bale.delete = function(self)
    if self.attacherV ~= nil then
		--print("abhaengen");
		if self.attacherV.detachobjects~= nil then
			--self.attacherV:detachobjects(self.nodeId);
		end;
	end;
	oldBaledelete(self);
end;
