Balefork = {};

function Balefork.prerequisitesPresent(specializations)
    return true;
end;


function Balefork:load(xmlFile)
-- additional functions
    	self.baleContactReport1 = SpecializationUtil.callSpecializationsFunction("baleContactReport1");
    	self.baleContactReport2 = SpecializationUtil.callSpecializationsFunction("baleContactReport2");
	self.attachBale = SpecializationUtil.callSpecializationsFunction("attachBale");
	self.detachBale = SpecializationUtil.callSpecializationsFunction("detachBale");
	self.setOpenState = SpecializationUtil.callSpecializationsFunction("setOpenState");

-- indices
	self.jointpunkt = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.joint#index"));

-- tables

-- integers
	self.breakCounter = 41; self.breakCounterEnd = 40;

	self.warnCounter = 41; self.warnCounterEnd = 40;

-- booleans
	self.isClosed = false;
	self.isBaleAttached = false;
	self.motorLowered = false;

-- overlays

-- sounds
	local hydSound = getXMLString(xmlFile, "vehicle.hydraulicSound#file");
    	if hydSound ~= nil and hydSound ~= "" then
     	  hydSound = Utils.getFilename(hydSound, self.baseDirectory); 
     	  self.hydSound = createSample("hydSound");
      	  self.hydSoundEnabled = false;
      	  loadSample(self.hydSound, hydSound, false);
	  setSamplePitch(self.hydSound,1);
    	end;
end;

function Balefork:delete()
	Balefork.removeContactReports(self);
end;

function Balefork:readStream(streamId, connection)
end;

function Balefork:writeStream(streamId, connection)
end;

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

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

function Balefork:update(dt)


	self.breakCounter = self.breakCounter + 1; self.warnCounter = self.warnCounter + 1;

	Balefork.addContactReports1(self); Balefork.addContactReports2(self);

	if self:getIsActiveForInput() then
		if InputBinding.hasEvent(InputBinding.FOLD) then
			if not self.isClosed then
				if self.breakCounter > self.breakCounterEnd then
					self:playAnimation("foldFork", 2);
					self:setAnimationSpeed("foldFork", 2)
					self:setOpenState(true);
				end;
			else
				self:playAnimation("foldFork", -2);
				self:setAnimationSpeed("foldFork", -2)
				self:setOpenState(false);
				if self.isBaleAttached then
					self:detachBale();
				end;
			end;
		end;
	end;





	-- update Joints
	if self:getIsAnimationPlaying("foldFork") then
		setJointFrame(self.componentJoints[1].jointIndex , 0 , self.componentJoints[1].jointNode);
		setJointFrame(self.componentJoints[2].jointIndex , 0 , self.componentJoints[2].jointNode);
	end;


	if self.breakCounter < self.breakCounterEnd then
		self.innerBale1 = nil;
		self.innerBale2 = nil;
	end;
end;

function Balefork:updateTick(dt)
	if self:getIsAnimationPlaying("foldFork") then
		if not self.hydSoundEnabled then
			if self:getIsActiveForSound() and self.attacherVehicle ~= nil then
				playSample(self.hydSound, 0, 0.5, 2); self.hydSoundEnabled = true;
			end;

		end;
	else
		if self.motorLowered and self.attacherVehicle ~= nil then
			self.attacherVehicle.motorSoundPitchOffset = self.attacherVehicle.motorSoundPitchOffset + 0.05; self.motorLowered = false;
		end;
		stopSample(self.hydSound); self.hydSoundEnabled = false;
	end;

	if self.innerBale1 ~= nil and self.innerBale1 == self.innerBale2 and self.breakCounter > self.breakCounterEnd and self:getIsAnimationPlaying("foldFork") then
		if not self.isBaleAttached then
			self:attachBale();
		end;
		self:stopAnimation("foldFork");		
	end;
end;


function Balefork:draw()
	g_currentMission:addHelpButtonText(string.format(g_i18n:getText("BALEFORK_OPENCLOSE"), self.typeDesc), InputBinding.FOLD);
	if self.warnCounter < self.warnCounterEnd then
		g_currentMission:addWarning(g_i18n:getText("BALEFORK_EMERGENCY"), 0.040, 0.035);
	end;
end;

function Balefork:onAttach(attacherVehicle)
	self.lastAttacherVehicle = attacherVehicle;
end;

function Balefork:onDetach()
	if self.motorLowered then
		self.lastAttacherVehicle.motorSoundPitchOffset = self.lastAttacherVehicle.motorSoundPitchOffset + 0.05;
	end;
	stopSample(self.hydSound); self.hydSoundEnabled = false;
	self:stopAnimation("foldFork");	
end;

function Balefork:onLeave()
end;

function Balefork:addContactReports1()
    if not self.childContactReportsActive1 then
        addContactReport(self.components[2].node, 0.0001, "baleContactReport1", self);

        self.BaleforkContactReportsActive1 = true;
    end;
end;
function Balefork:addContactReports2()
    if not self.childContactReportsActive2 then
        addContactReport(self.components[3].node, 0.0001, "baleContactReport2", self);

        self.BaleforkContactReportsActive2 = true;
    end;
end;
function Balefork:removeContactReports()
    if self.BaleforkContactReportsActive then
        self.innerBale1 = nil;
        self.innerBale2 = nil;
        self.BaleforkContactReportsActive1 = false;
        self.BaleforkContactReportsActive2 = false;
    end;
end;

function Balefork:baleContactReport1(objectId, otherObjectId, isStart, normalForce, tangentialForce)

	if getUserAttribute(otherObjectId,"isRoundbale") or getUserAttribute(otherObjectId,"isHaybale") or getUserAttribute(otherObjectId,"isStrawbale") or getName(otherObjectId) == "strawbaleBaler" or (getRigidBodyType(otherObjectId) == "Dynamic" and getName(getParent(otherObjectId)) == "RootNode") then                                                       
		if isStart and otherObjectId then
			self.innerBale1 = otherObjectId;
		else
			self.innerBale1 = nil;
		end;
	end;
end;

function Balefork:baleContactReport2(objectId, otherObjectId, isStart, normalForce, tangentialForce)

	if getUserAttribute(otherObjectId,"isRoundbale") or getUserAttribute(otherObjectId,"isHaybale") or getUserAttribute(otherObjectId,"isStrawbale") or getName(otherObjectId) == "strawbaleBaler" or (getRigidBodyType(otherObjectId) == "Dynamic" and getName(getParent(otherObjectId)) == "RootNode") then                                                       
		if isStart and otherObjectId then
			self.innerBale2 = otherObjectId;
		else
			self.innerBale2 = nil;
		end;
	end;
end;

function Balefork:attachBale(noEventSend)


	if not self.isBaleAttached and self.innerBale1 ~= nil and self.breakCounter > self.breakCounterEnd then
     		local x,y,z = getWorldTranslation(self.innerBale1);  
     		local x1,x2,x3 = worldToLocal(self.components[1].node, x,y,z);  
     		setTranslation(self.jointpunkt, x1,x2,x3)


		local zX, zY, zZ = localDirectionToWorld(self.innerBale1, 0,0,1);
		local zX, zY, zZ = worldDirectionToLocal(self.components[1].node, zX, zY, zZ);

		local yX, yY, yZ = localDirectionToWorld(self.innerBale1, 0,1,0);
		local yX, yY, yZ = worldDirectionToLocal(self.components[1].node, yX, yY, yZ);

		setDirection(self.jointpunkt, zX, zY, zZ, yX, yY, yZ);



	     	local constr = JointConstructor:new();  
     		for i= 0, 2 do 
       			constr:setTranslationLimit(i, true, 0, 0); 
       			constr:setRotationLimit(i, 0, 0); 
    		end;
     		constr:setActors(self.components[1].node , self.innerBale1);
     		constr:setJointTransforms(self.jointpunkt , self.innerBale1);
     		self.joint = constr:finalize();
		self.isBaleAttached = true;
		self.innerBale = self.innerBale1;
		AttachEvent.sendEvent(self, noEventSend);
	end;
end;

function Balefork:detachBale(noEventSend)
	if self.isBaleAttached then
		removeJoint(self.joint);
		self.isBaleAttached = false;
		self.breakCounter = 0;
		self:playAnimation("foldFork", -2);
		self:setAnimationSpeed("foldFork", -2)
		self:setOpenState(false);
		DetachEvent.sendEvent(self, noEventSend);
	end;
end;



function Balefork:setOpenState(isClosed, noEventSend)
	self.isClosed = isClosed;
	SetOpenStateEvent.sendEvent(self, isClosed, noEventSend);
end;

