-- NI Modding
--
-- author  	Henly20 
-- date  	03-02-2013.
-- ni_modding@hotmail.com
-- http://nimodding.wordpress.com

FordForce3000 = {};

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

function FordForce3000:load(xmlFile)

	local rotationRpmNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.rotationRpm#index"));
		if rotationRpmNode ~= nil then
        self.rotationRpm = {};
        self.rotationRpm.node = rotationRpmNode;

        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rotationRpm#minRot"));
        self.rotationRpm.minRot = {};
        self.rotationRpm.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationRpm.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationRpm.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rotationRpm#maxRot"));
        self.rotationRpm.maxRot = {};
        self.rotationRpm.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationRpm.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationRpm.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        self.rotationRpm.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationRpm#rotTime"), 2)*1000;
        self.rotationRpm.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationRpm#touchRotLimit"), 10));
    end;
	local rotationFuelNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.rotationFuel#index"));
		if rotationFuelNode ~= nil then
        self.rotationFuel = {};
        self.rotationFuel.node = rotationFuelNode;

        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rotationFuel#minRot"));
        self.rotationFuel.minRot = {};
        self.rotationFuel.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationFuel.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationFuel.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rotationFuel#maxRot"));
        self.rotationFuel.maxRot = {};
        self.rotationFuel.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationFuel.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationFuel.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        self.rotationFuel.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationFuel#rotTime"), 2)*1000;
        self.rotationFuel.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationFuel#touchRotLimit"), 10));
    end;
	local rotationPartNode4 = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.rotationPart4#index"));
		if rotationPartNode4 ~= nil then
        self.rotationPart4 = {};
        self.rotationPart4.node = rotationPartNode4;

        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rotationPart4#minRot"));
        self.rotationPart4.minRot = {};
        self.rotationPart4.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationPart4.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationPart4.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rotationPart4#maxRot"));
        self.rotationPart4.maxRot = {};
        self.rotationPart4.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationPart4.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationPart4.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        self.rotationPart4.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPart4#rotTime"), 2)*1000;
        self.rotationPart4.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPart4#touchRotLimit"), 10));
    end;
	local rotationPartNode8 = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.rotationPart8#index"));
    if rotationPartNode8 ~= nil then
        self.rotationPart8 = {};
        self.rotationPart8.node = rotationPartNode8;

        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rotationPart8#minRot"));
        self.rotationPart8.minRot = {};
        self.rotationPart8.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationPart8.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationPart8.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rotationPart8#maxRot"));
        self.rotationPart8.maxRot = {};
        self.rotationPart8.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationPart8.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationPart8.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        self.rotationPart8.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPart8#rotTime"), 2)*1000;
        self.rotationPart8.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPart8#touchRotLimit"), 10));
    end;
	local rotationPartNode10 = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.rotationPart10#index"));
    if rotationPartNode10 ~= nil then
        self.rotationPart10 = {};
        self.rotationPart10.node = rotationPartNode10;

        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rotationPart10#minRot"));
        self.rotationPart10.minRot = {};
        self.rotationPart10.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationPart10.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationPart10.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rotationPart10#maxRot"));
        self.rotationPart10.maxRot = {};
        self.rotationPart10.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationPart10.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationPart10.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        self.rotationPart10.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPart10#rotTime"), 2)*1000;
        self.rotationPart10.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPart10#touchRotLimit"), 10));
    end;
	local rotationPartNode11 = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.rotationPart11#index"));
    if rotationPartNode11 ~= nil then
        self.rotationPart11 = {};
        self.rotationPart11.node = rotationPartNode11;

        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rotationPart11#minRot"));
        self.rotationPart11.minRot = {};
        self.rotationPart11.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationPart11.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationPart11.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rotationPart11#maxRot"));
        self.rotationPart11.maxRot = {};
        self.rotationPart11.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationPart11.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationPart11.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        self.rotationPart11.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPart11#rotTime"), 2)*1000;
        self.rotationPart11.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPart11#touchRotLimit"), 10));
    end;

	self.rotationMax4Active = false;
	self.rotationMax8Active = false;
	self.rotationMax10 = false;

	local rotationLifter = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.Lifter#index"));
	self.Lifter = {};
	self.Lifter.node = rotationLifter;

	local rotationLifterArm = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.LifterArm#index"));
	self.LifterArm = {};
	self.LifterArm.node = rotationLifterArm;

	local rotationLifterBottom = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.LifterBottom#index"));
	self.bottomArm2 = {};
	self.bottomArm2.node = rotationLifterBottom;

	local BottomArmNode = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.attacherJoints.attacherJoint.bottomArm#rotationNode"));
	self.bottomArm = {};
	self.bottomArm.node = BottomArmNode;
    
	self.setHydraulicDirection = SpecializationUtil.callSpecializationsFunction("setHydraulicDirection");
	
	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"));	
		local xUp, yUp, zUp = Utils.getVectorFromString(Utils.getNoNil(getXMLString(xmlFile, hydraulicName .. "#upVectors"),"0 1 0"));
		self.hydraulics[i].upVectors = {xUp, yUp, zUp};
		
		local ax, ay, az;		
		if self.hydraulics[i].punch ~= nil then
			ax, ay, az = getWorldTranslation(self.hydraulics[i].punch);
		else
			ax, ay, az = getWorldTranslation(self.hydraulics[i].node);
		end;
		if self.hydraulics[i].translationPunch ~= nil then
			local bx, by, bz = getWorldTranslation(self.hydraulics[i].translationPunch);		
			self.hydraulics[i].punchDistance = Utils.vector3Length(ax-bx, ay-by, az-bz);
		end;
	end;
	self.setHydraulicTime = 30;
	
	self.toplink = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.topLink#index"));
	self.highhitch = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.highHitch#index"));
 	setVisibility((self.toplink), false);
 	setVisibility((self.highhitch), true);
		
    self.fanNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.fan#index"));
	
	self.backAttacherJoint = {};
	self.backAttacherJoint.node = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.trailerAttacherJoints#node"));
	self.backAttacherJoint.lowRot = Utils.degToRad(getXMLFloat(xmlFile, "vehicle.trailerAttacherJoints#lowRot"));
	self.backAttacherJoint.upRot = Utils.degToRad(getXMLFloat(xmlFile, "vehicle.trailerAttacherJoints#upRot"));
	
	self.drawbar = {};
	self.drawbar[1] = Utils.indexToObject(self.components,getXMLString(xmlFile,"vehicle.drawbar#index"));
	self.drawbar[2] = Utils.indexToObject(self.components,getXMLString(xmlFile,"vehicle.drawbar#index1"));
	
	setVisibility(self.drawbar[1], true);
	setVisibility(self.drawbar[2], false); 	
	self.isSelectable = true;	

end;

function FordForce3000:readStream(streamId, connection)

end;
  
function FordForce3000:writeStream(streamId, connection)

end;

function FordForce3000:keyEvent(unicode, sym, modifier, isDown)

end;

function FordForce3000:update(dt)
    if self.isClient and self:getIsActiveForInput(false) and not self:hasInputConflictWithSelection() then
        if InputBinding.hasEvent(InputBinding.LOWER_IMPLEMENT) then
			self.rotationMax10 = not self.rotationMax10;
        end;	
	end;	
	
	if self:getIsActive() then	
	
		local maxrpmneedle = 1800;
		if self.rotationRpm ~= nil and self.isMotorStarted == true then
			local x, y, z = getRotation(self.rotationRpm.node);
			y = ((self.rotationRpm.maxRot[2] - self.rotationRpm.minRot[2]) / maxrpmneedle) * (self.motor.lastMotorRpm+400) + self.rotationRpm.minRot[2];
			setRotation(self.rotationRpm.node, x, y ,z);
		elseif self.isMotorStarted == false then
			setRotation(self.rotationRpm.node, 0, 0 ,0);
		end;
		local maxfuelguage = 49;
		if self.rotationFuel ~= nil and self.isMotorStarted == true then
			local x, y, z = getRotation(self.rotationFuel.node);
			y = ((self.rotationFuel.maxRot[2] - self.rotationFuel.minRot[2]) / maxfuelguage) * self.fuelFillLevel + self.rotationFuel.minRot[2];
			setRotation(self.rotationFuel.node, x, y ,z);
		elseif self.isMotorStarted == false then
			setRotation(self.rotationFuel.node, 0, 0 ,0);
		end;
		if self.rotationPart4 ~= nil then
			local x, y, z = getRotation(self.rotationPart4.node);
			local rot = {x,y,z};
			local newRot = Utils.getMovedLimitedValues(rot, self.rotationPart4.maxRot, self.rotationPart4.minRot, 3, self.rotationPart4.rotTime, dt, not self.rotationMax4Active);
			setRotation(self.rotationPart4.node, unpack(newRot));
		end;
		if self.rotationPart8 ~= nil then
			local x, y, z = getRotation(self.rotationPart8.node);
			local rot = {x,y,z};
			local newRot = Utils.getMovedLimitedValues(rot, self.rotationPart8.maxRot, self.rotationPart8.minRot, 3, self.rotationPart8.rotTime, dt, not self.rotationMax8Active);
			setRotation(self.rotationPart8.node, unpack(newRot));
		end;
		if self.rotationPart10 ~= nil then
			local x, y, z = getRotation(self.rotationPart10.node);
			local rot = {x,y,z};
			local newRot = Utils.getMovedLimitedValues(rot, self.rotationPart10.maxRot, self.rotationPart10.minRot, 3, self.rotationPart10.rotTime, dt, not self.rotationMax10);
			setRotation(self.rotationPart10.node, unpack(newRot));
		end;	
		local maxhandthrottle = 1800;
		if self.rotationPart11 ~= nil and self.isMotorStarted == true then
			local x, y, z = getRotation(self.rotationPart11.node);
			y = ((self.rotationPart11.maxRot[2] - self.rotationPart11.minRot[2]) / maxrpmneedle) * (self.motor.lastMotorRpm+400) + self.rotationPart11.minRot[2];
			setRotation(self.rotationPart11.node, x, y ,z);
		elseif self.isMotorStarted == false then
			setRotation(self.rotationPart11.node, 0, 0 ,0);
		end;
			
		if self.Lifter.node ~= nil and self.bottomArm2.node ~= nil then
			rBBArmX, rBBArmY, rBBArmZ = getRotation(self.bottomArm2.node);
			setRotation(self.Lifter.node, rBBArmX*1.18, 0, 0);
		end;
		if self.LifterArm.node ~= nil and self.bottomArm2.node ~= nil then
			setRotation(self.LifterArm.node, 0.05-rBBArmX*0.98, 0, 0);
		end;
		
	end;
		if self:getIsActive() then			
			self.setHydraulicTime = 30;	
		end;

		if self.setHydraulicTime > 0 then
			for k,v in pairs(self.hydraulics) do 
				self:setHydraulicDirection(k);
			end;
			self.setHydraulicTime = self.setHydraulicTime - 1;
		end;
		if self.fanNode ~= nil and self.isMotorStarted then 
			 rotate(self.fanNode, 0, 0, self.motor.lastMotorRpm*4);
		end;	
end;

function FordForce3000:updateTick(dt)
	if self:getIsActive() then
		if self.brakeLightsVisibility then
			self.rotationMax4Active = true;
			self.rotationMax8Active = true;
		else
			self.rotationMax4Active = false;
			self.rotationMax8Active = false;
		end;		
			if self.backHydraulic ~= nil then
			-- set correct rotation on rootArm			
			local x, y, z = getRotation(self.attacherJoints[1].bottomArm.rotationNode);
			setRotation(self.backHydraulic.rootArm, x, y, z);	
		end;	
	end;
end;

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

function FordForce3000:draw()
  
end;

function FordForce3000:onEnter()

end;

function FordForce3000:onLeave()

end;

function FordForce3000:setHydraulicDirection(index)
	local hydraulic = self.hydraulics[index];

	if hydraulic.fixPoint ~= nil then
		local ax, ay, az = getWorldTranslation(hydraulic.node);
		local bx, by, bz = getWorldTranslation(hydraulic.fixPoint);
		local x, y, z = worldDirectionToLocal(getParent(hydraulic.node), bx-ax, by-ay, bz-az);
		local xUp, yUp, zUp = unpack(hydraulic.upVectors);
		setDirection(hydraulic.node, x, y, z, xUp, yUp, zUp);
		if hydraulic.punch ~= nil then
			local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
			setTranslation(hydraulic.punch, 0, 0, distance-hydraulic.punchDistance);
		end;
	end;
end;

function FordForce3000:delete()

end;


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

function FordForce3000:attachImplement(implement)
	self.rotationMax10 = false;	
	local jointType = implement.object.attacherJoint.jointType;
	local jointIndex = implement.jointDescIndex;
	
	if jointType == Vehicle.JOINTTYPE_IMPLEMENT then
			if jointIndex == 1 then
			setVisibility((self.toplink), true);
			setVisibility((self.highhitch), false);		
			setVisibility(self.drawbar[1], false);
			setVisibility(self.drawbar[2], true); 				
			end;
	elseif jointType == Vehicle.JOINTTYPE_TRAILER then
		if jointIndex == 2 then
			setRotation(self.attacherJoints[1].bottomArm.rotationNode, self.backAttacherJoint.lowRot, 0, 0);
			setRotation(self.backAttacherJoint.node, -self.backAttacherJoint.lowRot, 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;
		
	self.updateJoint = true;	
end;

function FordForce3000:detachImplement(implementIndex)
	self.rotationMax10 = false;
	local implement = self.attachedImplements[implementIndex];
	local jointIndex = implement.jointDescIndex;
	
	if jointIndex == 1 then
		setVisibility((self.toplink), false);
		setVisibility((self.highhitch), true);
		setVisibility(self.drawbar[1], true);
		setVisibility(self.drawbar[2], false); 	
	elseif jointIndex == 2 or jointIndex == 3 then
		setRotation(self.attacherJoints[1].bottomArm.rotationNode, 0, 0, 0);
		setRotation(self.backAttacherJoint.node, 0, 0, 0);
	end;
end;
