--
-- KirovetsK700A
-- Specialization for KirovetsK700A
--
-- @author  	Manuel Leithner (SFM-Modding)
-- @version 	v2.0
-- @date  		15/10/10
-- @history:	v1.0 - Initial version
--				v2.0 - added network support, changed update to updateTick
--

KirovetsK700A = {};

function KirovetsK700A.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(ArticulatedAxis, specializations);
end;

function KirovetsK700A:load(xmlFile)
	
	self.backAttacherJoint = {};
	self.backAttacherJoint.node = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.trailerAttacherJointInfo#node"));
	self.backAttacherJoint.lowRot = Utils.degToRad(getXMLFloat(xmlFile, "vehicle.trailerAttacherJointInfo#lowRot"));
	self.backAttacherJoint.upRot = Utils.degToRad(getXMLFloat(xmlFile, "vehicle.trailerAttacherJointInfo#upRot"));
	
	self.implementAdapter = {};
	self.implementAdapter.node = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.attacherJoints#adapter"));
	self.implementAdapter.attacherJoint = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.attacherJoints#attacherJoint"));
	self.implementAdapter.topReferenceNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.attacherJoints#topReferenceNode"));
	self.implementAdapter.backup = {};
	local x,y,z = getTranslation(self.implementAdapter.node);
	self.implementAdapter.backup.trans = {x,y,z};
	self.implementAdapter.backup.attacherJoint = nil;
    self.implementAdapter.backup.topReferenceNode = nil;	
	
	local shaftCount = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.drivingPowerShafts#count"), 0);
    self.drivingPowerShafts = {};
    for i=1, shaftCount do
		local shaft = {};
        local shaftName = string.format("vehicle.drivingPowerShafts.powerShaft%d", i);
		shaft.node = Utils.indexToObject(self.components, getXMLString(xmlFile, shaftName .. "#index"));		
		shaft.trans = Utils.getNoNil(getXMLFloat(xmlFile, shaftName .. "#translation"), 0);
		local x,y,z = getTranslation(getParent(shaft.node));
		shaft.orgTrans = {x,y,z};
		shaft.rot = Utils.degToRad(Utils.getNoNil(getXMLFloat(xmlFile, shaftName .. "#rotation"), 0));	
		shaft.speedFactor = Utils.getNoNil(getXMLFloat(xmlFile, shaftName .. "#speedFactor"), 2);
		table.insert(self.drivingPowerShafts, shaft);        
    end;
	
	self.topArm = {};
	self.topArm.node = getChildAt(self.attacherJoints[1].topArm.rotationNode, 0);
	self.topArm.rotation = {getRotation(self.topArm.node)};
	
	self.updateJoint = false;
	
end;

function KirovetsK700A:delete()
end;

function KirovetsK700A:readStream(streamId, connection)
end;

function KirovetsK700A:writeStream(streamId, connection)
end;

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

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

function KirovetsK700A:update(dt)
end;

function KirovetsK700A:updateTick(dt)

	if self:getIsActive() then
		local steeringAngle;
		if self.isServer then
			steeringAngle = self.articulatedAxis.curRot;
		else
			steeringAngle = self.rotatedTime * self.articulatedAxis.rotSpeed;
			if steeringAngle > self.articulatedAxis.rotMax then
				steeringAngle = self.articulatedAxis.rotMax;
			elseif steeringAngle < self.articulatedAxis.rotMin then
				steeringAngle = self.articulatedAxis.rotMin;
			end;
		end;
        
        local newX,_,_ = getRotation(self.wheels[1].driveNode)
        if self.lastReferenceWheelRotation == nil then
            self.lastReferenceWheelRotation = newX;
        end;
        if newX - self.lastReferenceWheelRotation < -math.pi then
            self.lastReferenceWheelRotation = self.lastReferenceWheelRotation - 2*math.pi;
        elseif newX - self.lastReferenceWheelRotation > math.pi then
            self.lastReferenceWheelRotation = self.lastReferenceWheelRotation + 2*math.pi;
        end;        
        local deltaRot = newX - self.lastReferenceWheelRotation;
        self.lastReferenceWheelRotation = newX;

		for _, shaft in pairs(self.drivingPowerShafts) do
			--local x,y,z = getRotation(self.wheels[1].driveNode);
			--setRotation(shaft.node, 0 ,0, x*shaft.speedFactor);
            rotate(shaft.node, 0,0,deltaRot*shaft.speedFactor);

			if shaft.trans ~= 0 then
				local newTrans = shaft.trans * steeringAngle/self.articulatedAxis.rotMax;
				local x,y,z = unpack(shaft.orgTrans);
				setTranslation(getParent(shaft.node), x + newTrans,y,z);
			end;
			if shaft.rot ~= 0 then
				newRot = shaft.rot * steeringAngle/self.articulatedAxis.rotMax;
				setRotation(getParent(shaft.node), 0, newRot, 0);
			end;			
		end;		
	end;
end;

function KirovetsK700A:draw()	
end;


function KirovetsK700A:attachImplement(implement)
	
	local jointType = implement.object.attacherJoint.jointType;
	local jointIndex = implement.jointDescIndex;

	if jointType == Vehicle.JOINTTYPE_IMPLEMENT then
		if jointIndex == 1 then
			setRotation(self.topArm.node, 0, 0, 0);
			setVisibility(getParent(self.backAttacherJoint.node), false);
			
			local attacherJoint = implement.object.attacherJoint;
			unlink(self.implementAdapter.node);
			link(attacherJoint.node, self.implementAdapter.node);
			setTranslation(self.implementAdapter.node, 0, 0, 0);
			
			if attacherJoint.topReferenceNode ~= nil then
				local x,y,z = getWorldTranslation(attacherJoint.topReferenceNode);
				local x1,y1,z1 = getWorldTranslation(self.implementAdapter.node);
				local xDir, yDir, zDir = worldDirectionToLocal(getParent(self.implementAdapter.node), x-x1, y-y1, z-z1);
				setDirection(self.implementAdapter.node, xDir, yDir, zDir, 0,1,-1);
				
				local x,y,z = getRotation(self.implementAdapter.node);
				setRotation(self.implementAdapter.node, x, math.rad(90), 0);
			else
				setRotation(self.implementAdapter.node, math.rad(-90), math.rad(90), 0);
			end;
			
			self.implementAdapter.backup.attacherJoint = attacherJoint.node;
			self.implementAdapter.backup.topReferenceNode = attacherJoint.topReferenceNode;			
			attacherJoint.node = self.implementAdapter.attacherJoint;
			attacherJoint.topReferenceNode = self.implementAdapter.topReferenceNode;
		
			setVisibility(self.implementAdapter.node, true);
		end;
	elseif jointType == Vehicle.JOINTTYPE_TRAILER then
		if jointIndex == 2 then
			setRotation(self.attacherJoints[1].bottomArm.rotationNode, self.backAttacherJoint.upRot, 0, 0);
			setRotation(self.backAttacherJoint.node, -self.backAttacherJoint.upRot, 0, 0);
		end;
	elseif jointType == Vehicle.JOINTTYPE_TRAILERLOW then
		if jointIndex == 3 then	
			setRotation(self.attacherJoints[1].bottomArm.rotationNode, self.backAttacherJoint.lowRot, 0, 0);
			setRotation(self.backAttacherJoint.node, -self.backAttacherJoint.lowRot, 0, 0);
		end;
	end;
	if self:getIsActive() then
		for _, part in pairs(self.movingParts) do
			part.isDirty = true;
		end;	
	end;
	self.updateJoint = true;	
end;

function KirovetsK700A:detachImplement(implementIndex)

	local implement = self.attachedImplements[implementIndex];
	local jointIndex = implement.jointDescIndex;

	if jointIndex == 1 then
		local x,y,z = unpack(self.topArm.rotation);
		setRotation(self.topArm.node, x,y,z);
		setVisibility(getParent(self.backAttacherJoint.node), true);
		
		setVisibility(self.implementAdapter.node, false);
		local attacherJoint = implement.object.attacherJoint;
		
		attacherJoint.node = self.implementAdapter.backup.attacherJoint;
		attacherJoint.topReferenceNode = self.implementAdapter.backup.topReferenceNode;
		
		unlink(self.implementAdapter.node);
		link(self.components[2].node, self.implementAdapter.node);
		setTranslation(self.implementAdapter.node, unpack(self.implementAdapter.backup.trans));
		setRotation(self.implementAdapter.node, math.rad(-90), 0,0);
		
	elseif jointIndex == 2 or jointIndex == 3 then
		setRotation(self.attacherJoints[1].bottomArm.rotationNode, 0, 0, 0);
		setRotation(self.backAttacherJoint.node, 0, 0, 0);
	end;
	if self:getIsActive() then
		for _, part in pairs(self.movingParts) do
			part.isDirty = true;
		end;	
	end;
end;

function KirovetsK700A:validateAttacherJoint(implement, jointDesc, dt)
    if self.updateJoint then
        self.updateJoint = false;
        return true;
    end;
    return false;
end;