Balefork = {};

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

function Balefork:load(xmlFile)
    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");
	self.jointpunkt = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.joint#index"));
	self.breakCounter = 41; self.breakCounterEnd = 40;
	self.warnCounter = 41; self.warnCounterEnd = 40;
	self.isClosed = false;
	self.isBaleAttached = false;
	self.motorLowered = false;

	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;

	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;
	if self.attacherVehicle ~= nil then
	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;