BririKlappe = {};

function BririKlappe.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Fillable, specializations);
end;

function BririKlappe:load(xmlFile)

	self.setTowballDirection = SpecializationUtil.callSpecializationsFunction("setTowballDirection");
	
	local hydraulicsCount = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.hydraulics#count"), 0);	
	self.hydraulics = {};	
	for i=1, hydraulicsCount do
		local hydraulicName = string.format("vehicle.hydraulics.hydraulic%d", i);		
		self.hydraulics[i] = {};		
		self.hydraulics[i].node = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#index"));
		self.hydraulics[i].punch = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#punch"));
		self.hydraulics[i].translationPunch = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#punchFixpoint"));
		self.hydraulics[i].fixPoint = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#fixpoint"));
		if self.hydraulics[i].punch ~= nil and self.hydraulics[i].translationPunch ~= nil then
			local ax, ay, az = getWorldTranslation(self.hydraulics[i].punch);
			local bx, by, bz = getWorldTranslation(self.hydraulics[i].translationPunch);		
			self.hydraulics[i].punchDistance = Utils.vector3Length(ax-bx, ay-by, az-bz);
		end;
	end;
	
	self.attacherCylinder = {};
	self.attacherCylinder.leftCylinder = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.towBallZylinder#leftZylinder"));
	self.attacherCylinder.leftPunch = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.towBallZylinder#leftZylinderPunch"));
	self.attacherCylinder.leftFixPoint = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.towBallZylinder#leftZylinderFixPoint"));
	if self.attacherCylinder.leftPunch ~= nil then
		local ax, ay, az = getWorldTranslation(self.attacherCylinder.leftPunch);
		local bx, by, bz = getWorldTranslation(self.attacherCylinder.leftFixPoint);
		self.attacherCylinder.leftDistance = Utils.vector3Length(ax-bx, ay-by, az-bz);
	end;
	self.attacherCylinder.rightCylinder = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.towBallZylinder#rightZylinder"));
	self.attacherCylinder.rightPunch = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.towBallZylinder#rightZylinderPunch"));
	self.attacherCylinder.rightFixPoint = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.towBallZylinder#rightZylinderFixPoint"));
	if self.attacherCylinder.rightPunch ~= nil then
		local ax, ay, az = getWorldTranslation(self.attacherCylinder.rightPunch);
		local bx, by, bz = getWorldTranslation(self.attacherCylinder.rightFixPoint);
		self.attacherCylinder.rightDistance = Utils.vector3Length(ax-bx, ay-by, az-bz);
	end;
	
	self.towBallAngle = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.towBallAngle#index"));
	
	self.wallsDown = true;
	
end;

function BririKlappe:delete()
end;

function BririKlappe:readStream(streamId, connection)	
end;

function BririKlappe:writeStream(streamId, connection)
end;

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

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

function BririKlappe:update(dt)
	
	self:setTowballDirection();
	self.wallsDown = self.animationParts[1].clipStartTime and self.animationParts[1].inputDone;
	self.allowFillFromAir = self.wallsDown;
	
	if self:getIsActiveForInput() then
		if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA) then
			if self.wallsDown then
				self:setAnimationTime(1, self.animationParts[1].animDuration);
			else
				self:setAnimationTime(1, self.animationParts[1].offSet);
			end;
		end;
	end;
	
	for i=1, table.getn(self.hydraulics) do
		local ax, ay, az = getWorldTranslation(self.hydraulics[i].node);
		local bx, by, bz = getWorldTranslation(self.hydraulics[i].fixPoint);
		local x, y, z = worldDirectionToLocal(getParent(self.hydraulics[i].node), bx-ax, by-ay, bz-az);
		setDirection(self.hydraulics[i].node, x, y, z, 0, 1, 0);
		local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
		if self.hydraulics[i].punchDistance ~= nil then
			setTranslation(self.hydraulics[i].punch, 0, 0, distance-self.hydraulics[i].punchDistance);
		end;
	end;
	
	if self.updateSteeringAxleAngle then
		if self.attacherVehicle ~= nil and self.movingDirection < 0 then
			local x,y,z = worldDirectionToLocal(self.steeringAxleNode, localDirectionToWorld(self.attacherVehicle.steeringAxleNode, 0, 0, 1));
			local dot = z;
			dot = dot / Utils.vector2Length(x,z);
			local angle = math.acos(dot);
			if x < 0 then
				angle = -angle;
			end;
			local startSpeed = self.steeringAxleAngleScaleStart;
			local endSpeed = self.steeringAxleAngleScaleEnd;
			local scale = Utils.clamp(1 + (self.lastSpeed*-3600-startSpeed) * 1.0/(startSpeed-endSpeed), 0, 1);
			self.steeringAxleAngle = angle*scale;
		end;
	end;

end;

function BririKlappe:updateTick(dt)

	local steeringAxleAngle = 0;
	if self.attacherVehicle ~= nil then
		local x,y,z = worldDirectionToLocal(self.steeringAxleNode, localDirectionToWorld(self.attacherVehicle.steeringAxleNode, 0, 0, 1));
		local dot = z;
		dot = dot / Utils.vector2Length(x,z);
		local angle = math.acos(dot);
		if x > 0 then
			angle = -angle;
		end;
		steeringAxleAngle = -angle*0.75;
	end;
	setRotation(self.towBallAngle, 0, steeringAxleAngle, 0);
	
end;

function BririKlappe:setTowballDirection()
	if self.leftFixPoint ~= nil then
		local ax, ay, az = getWorldTranslation(self.attacherCylinder.leftCylinder);
		local bx, by, bz = getWorldTranslation(self.leftFixPoint);
		local x, y, z = worldDirectionToLocal(getParent(self.attacherCylinder.leftCylinder), bx-ax, by-ay, bz-az);
		setDirection(self.attacherCylinder.leftCylinder, x, y, z, 0, 1, 0);
		local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
		if self.attacherCylinder.leftDistance ~= nil then
			setTranslation(self.attacherCylinder.leftPunch, 0, 0, distance-self.attacherCylinder.leftDistance);
		end;
	end;
	if self.rightFixPoint ~= nil then
		local ax, ay, az = getWorldTranslation(self.attacherCylinder.rightCylinder);
		local bx, by, bz = getWorldTranslation(self.rightFixPoint);
		local x, y, z = worldDirectionToLocal(getParent(self.attacherCylinder.rightCylinder), bx-ax, by-ay, bz-az);
		setDirection(self.attacherCylinder.rightCylinder, x, y, z, 0, 1, 0);
		local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
		if self.attacherCylinder.rightDistance ~= nil then
			setTranslation(self.attacherCylinder.rightPunch, 0, 0, distance-self.attacherCylinder.rightDistance);
		end;
	end;
end;

function BririKlappe:draw()
	if self.wallsDown then
		g_currentMission:addHelpButtonText(g_i18n:getText("BririKlappe_1"), InputBinding.IMPLEMENT_EXTRA);
	else
		g_currentMission:addHelpButtonText(g_i18n:getText("BririKlappe_2"), InputBinding.IMPLEMENT_EXTRA);
	end;
end;

function BririKlappe:onAttach(attacherVehicle)
	self.attacherVehicle = attacherVehicle;
end;

function BririKlappe:onDetach()
end;