--
-- bobcatT180
-- This is the specialization for Bobcat T180 skisteer
--
-- @author  PeterJ - euroDZN
-- @date  11/07/2013
--
-- http://eurodzn.wordpress.com/
--
-- Copyright (C) euroDZN, Confidential, All Rights Reserved.
  
bobcatT180 = {};
  
function bobcatT180.prerequisitesPresent(specializations)
	return SpecializationUtil.hasSpecialization(Cylindered, specializations);
end;
  
function bobcatT180:load(xmlFile)
	
	--- increase rpm ---
	self.setIsTurnedOn = bobcatT180.setIsTurnedOn;
	self.isTurnedOn = false;
	self.revUpMaxTime = 0;
	self.throttleLeverAnim = getXMLString(xmlFile, "vehicle.throttleLever#animationName");
 	self.setVehicleRpmUp = SpecializationUtil.callSpecializationsFunction("setVehicleRpmUp");
	self.saveMinRpm = self.motor.minRpm;
	
	--- move levers ---
	self.lastArmAngle = 0;
	self.mainArm = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.mainArmLever#mainArm"));
	self.mainArmLever = {};
	self.mainArmLever.node = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.mainArmLever#index"));
	if self.mainArmLever.node ~= nil then
		self.mainArmLever.minRot = {Utils.degToRad(getXMLFloat(xmlFile, "vehicle.mainArmLever#minRot"))};
		self.mainArmLever.maxRot = {Utils.degToRad(getXMLFloat(xmlFile, "vehicle.mainArmLever#maxRot"))};
		self.mainArmLever.Rot = {Utils.degToRad(getXMLFloat(xmlFile, "vehicle.mainArmLever#Rot"))};
		self.mainArmLever.rotTime = getXMLFloat(xmlFile, "vehicle.mainArmLever#rotTime")*1000;
		self.mainArmLever.posX = true;
		self.mainArmLever.posZ = true;
	end;
	
	self.lastToolAngle = 0;
	self.toolReference = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.toolArmLever#toolFrame"));
	self.toolArmLever = {};
	self.toolArmLever.node = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.toolArmLever#index"));
	if self.toolArmLever.node ~= nil then
		self.toolArmLever.minRot = {Utils.degToRad(getXMLFloat(xmlFile, "vehicle.toolArmLever#minRot"))};
		self.toolArmLever.maxRot = {Utils.degToRad(getXMLFloat(xmlFile, "vehicle.toolArmLever#maxRot"))};
		self.toolArmLever.Rot = {Utils.degToRad(getXMLFloat(xmlFile, "vehicle.toolArmLever#Rot"))};
		self.toolArmLever.rotTime = getXMLFloat(xmlFile, "vehicle.toolArmLever#rotTime")*1000;
		self.toolArmLever.posX = true;
		self.toolArmLever.posZ = true;
	end;
	
	--- safety bar ---
	self.safetyBarAnim = getXMLString(xmlFile, "vehicle.safetyBar#animationName");
	
	--- reverse light ---
	self.reverseLight = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.reverseLight#index"));

	--- becon rotPart ---
	self.beaconLightRotIndex = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.beaconLights.beaconLight#rotIndex"));
	
	
	self.deactivateHose = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.hydraulicHose#deactivate"), false);	
	if not self.deactivateHose then	
		local i=0;
		while true do
			local baseName = string.format("vehicle.attacherJoints.attacherJoint(%d)", i);
			local index = getXMLString(xmlFile, baseName.. "#index");
			if index == nil then
				break;
			end;		
			local joint = self.attacherJoints[i+1];
			local hoseAttacher = Utils.indexToObject(self.components, getXMLString(xmlFile, baseName .. "#hose"));
			if hoseAttacher ~= nil then
				joint.hydrahoseAttacher = hoseAttacher;
			end;
			i = i + 1;
		end;
	end;
	
	--- needles ---
	self.hasNeedles = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.needles#hasNeedle"), false);
	local rotationPartFuel = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.needles.fuel#index"));
    if rotationPartFuel ~= nil then
        self.rotationFuel = {};
        self.rotationFuel.node = rotationPartFuel;

        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.needles.fuel#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.needles.fuel#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));
	end;
	local rotationPartTemp = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.needles.temperature#index"));
    if rotationPartTemp ~= nil then
        self.rotationTemp = {};
        self.rotationTemp.node = rotationPartTemp;

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

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

        self.rotationTemp.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.needles.temperature#rotTime"), 2)*1000;
    end;
	self.numberImplements = 0;
	self.runOnce = true;
end;
  
function bobcatT180:delete()
end;
  
function bobcatT180:readStream(streamId, connection)
	local turnedOn = streamReadBool(streamId);
	self:setIsTurnedOn(turnedOn, true);
end;
  
function bobcatT180:writeStream(streamId, connection)
	streamWriteBool(streamId, self.isTurnedOn);
end;

function bobcatT180:mouseEvent(posX, posY, isDown, isUp, button)
end;
  
function bobcatT180:keyEvent(unicode, sym, modifier, isDown)
end;
 
function bobcatT180:update(dt)
	if self.runOnce then
		self.defaultMass = getMass(self.components[1].node);
		self.runOnce = false;
	end;
	if self.isClient then
		if self:getIsActiveForInput(false) then
			if InputBinding.hasEvent(InputBinding.TOGGLE_AI) then
				self:setIsTurnedOn(not self.isTurnedOn);
			end;
		end;
	end;	

	if self:getIsActive() then
		local currentMass = getMass(self.components[1].node);
		if self.numberImplements > 0 then				
			for k,implement in pairs(self.attachedImplements) do
				local tool = implement.object;
				if tool.isBaleAttach and tool.isSkidsteerTool then
					local newMass = self.defaultMass*1.9;
					if currentMass ~= self.defaultMass*1.9 then
						setMass(self.components[1].node, newMass);
					end;
				else
					if currentMass ~= self.defaultMass then
						setMass(self.components[1].node, self.defaultMass);
					end;
				end;
			end;
		else
			if currentMass ~= self.defaultMass then
				setMass(self.components[1].node, self.defaultMass);
			end;
		end;
	end;
end;
  
function bobcatT180:updateTick(dt)
	if self:getIsActive() then
		local revUp = false;
		if self.mainArm ~= nil then
			--- arm lever ---
			local x,_,_ = getRotation(self.mainArm);
			self.armMoveAngle = x;
			if self.lastArmAngle > self.armMoveAngle then
				self.mainArmLever.posX = true;
				x,y,z = getRotation(self.mainArmLever.node);	
				local newRot = Utils.getMovedLimitedValues({x}, self.mainArmLever.maxRot, self.mainArmLever.minRot, 1, self.mainArmLever.rotTime, dt, true);
				setRotation(self.mainArmLever.node, newRot[1],y,z);
				revUp = true;
			elseif self.lastArmAngle < self.armMoveAngle then
				self.mainArmLever.posX = false;
				x,y,z = getRotation(self.mainArmLever.node);	
				local newRot = Utils.getMovedLimitedValues({x}, self.mainArmLever.maxRot, self.mainArmLever.minRot, 1, self.mainArmLever.rotTime, dt, false );
				setRotation(self.mainArmLever.node, newRot[1],y,z);
				revUp = true;	
			end;
			if self.lastArmAngle == self.armMoveAngle then
				if self.mainArmLever.posX then
					x,y,z = getRotation(self.mainArmLever.node);	
					local newRot = Utils.getMovedLimitedValues({x}, self.mainArmLever.minRot, self.mainArmLever.Rot, 1, self.mainArmLever.rotTime/2, dt, true);
					setRotation(self.mainArmLever.node, newRot[1],y,z);
				else
					x,y,z = getRotation(self.mainArmLever.node);	
					local newRot = Utils.getMovedLimitedValues({x}, self.mainArmLever.maxRot, self.mainArmLever.Rot, 1, self.mainArmLever.rotTime/2, dt, true);
					setRotation(self.mainArmLever.node, newRot[1],y,z);		
				end;
			end;
			self.lastArmAngle = self.armMoveAngle;
		end;
		if self.toolReference ~= nil then
			--- tool lever ---
			local x,_,_ = getRotation(self.toolReference);
			self.toolMoveAngle = x;
			if self.lastToolAngle > self.toolMoveAngle then
				self.toolArmLever.posX = true;
				x,y,z = getRotation(self.toolArmLever.node);	
				local newRot = Utils.getMovedLimitedValues({x}, self.toolArmLever.maxRot, self.toolArmLever.minRot, 1, self.toolArmLever.rotTime, dt, true);
				setRotation(self.toolArmLever.node, newRot[1],y,z);
				revUp = true;
			elseif self.lastToolAngle < self.toolMoveAngle then
				self.toolArmLever.posX = false;
				x,y,z = getRotation(self.toolArmLever.node);	
				local newRot = Utils.getMovedLimitedValues({x}, self.toolArmLever.maxRot, self.toolArmLever.minRot, 1, self.toolArmLever.rotTime, dt, false );
				setRotation(self.toolArmLever.node, newRot[1],y,z);	
				revUp = true;	
			end;
			if self.lastToolAngle == self.toolMoveAngle then
				if self.toolArmLever.posX then
					x,y,z = getRotation(self.toolArmLever.node);	
					local newRot = Utils.getMovedLimitedValues({x}, self.toolArmLever.minRot, self.toolArmLever.Rot, 1, self.toolArmLever.rotTime/2, dt, true);
					setRotation(self.toolArmLever.node, newRot[1],y,z);
				else
					x,y,z = getRotation(self.toolArmLever.node);	
					local newRot = Utils.getMovedLimitedValues({x}, self.toolArmLever.maxRot, self.toolArmLever.Rot, 1, self.toolArmLever.rotTime/2, dt, true);
					setRotation(self.toolArmLever.node, newRot[1],y,z);		
				end;
			end;
			self.lastToolAngle = self.toolMoveAngle;
		end;
		if self.revUpMaxTime > self.time then
			self:setVehicleRpmUp(dt, true);
		else
			if self.isTurnedOn then
				self:setIsTurnedOn(false);
			else
				if revUp then
					self:setIsTurnedOn(true);
				end;
			end;
		end;
		if self.isMotorStarted then
			if not self.isTurnedOn then
				self:setVehicleRpmUp(dt, false);
			end;
		else
			if self.isTurnedOn then
				self:setIsTurnedOn(false);
			end;
		end;
		
		--setVisibility(self.reverseLight, self.reverseDriveSoundEnabled);
		if self.beaconLightsActive and self.beaconLightRotIndex ~= nil then
			rotate(self.beaconLightRotIndex, 0, self.beaconLights[1].speed*dt, 0);
		end;
		if self.hasNeedles then
			if self.isMotorStarted then
				local x, y, z = getRotation(self.rotationFuel.node);
				x = (self.rotationFuel.maxRot[1] - self.rotationFuel.minRot[1]) * (self.fuelFillLevel/self.fuelCapacity);
				y = (self.rotationFuel.maxRot[2] - self.rotationFuel.minRot[2]) * (self.fuelFillLevel/self.fuelCapacity);
				z = (self.rotationFuel.maxRot[3] - self.rotationFuel.minRot[3]) * (self.fuelFillLevel/self.fuelCapacity);
				setRotation(self.rotationFuel.node, x, y, z);
			else
				setRotation(self.rotationFuel.node, self.rotationFuel.minRot[1], self.rotationFuel.minRot[2], self.rotationFuel.minRot[3]);
			end;
			local x, y, z = getRotation(self.rotationTemp.node);
			local rot = {x,y,z};
			local newRot = Utils.getMovedLimitedValues(rot, self.rotationTemp.maxRot, self.rotationTemp.minRot, 3, self.rotationTemp.rotTime, dt, not self.isMotorStarted);
			setRotation(self.rotationTemp.node, unpack(newRot));
		end;
	end;
end;
  
function bobcatT180:draw()
	if self.isClient then
		if self.isMotorStarted then
		--if self:getIsActiveForInput(true) then
			if self.isTurnedOn then
				g_currentMission:addHelpButtonText(string.format(g_i18n:getText("revDOWN")), InputBinding.TOGGLE_AI);
			else
				g_currentMission:addHelpButtonText(string.format(g_i18n:getText("revUP")), InputBinding.TOGGLE_AI);
			end;
		end;
	end;
end;

function bobcatT180:onEnter(isControlling)
	if self.safetyBarAnim ~= nil and self.playAnimation ~= nil then
		self:playAnimation(self.safetyBarAnim, 1, nil, true);
	end;
end;

function bobcatT180:onLeave()
	if self.safetyBarAnim ~= nil and self.playAnimation ~= nil then
		self:playAnimation(self.safetyBarAnim, -1, nil, true);
	end;
end;

function bobcatT180:attachImplement(implement)
	self.numberImplements = self.numberImplements + 1;
end;

function bobcatT180:detachImplement(implementIndex)
	self.numberImplements = math.min(self.numberImplements - 1, 0);
end;
  
function bobcatT180:setIsTurnedOn(isTurnedOn, noEventSend)
	if isTurnedOn ~= self.isTurnedOn then
		SetTurnedOnEvent.sendEvent(self, isTurnedOn, noEventSend)
		self.isTurnedOn = isTurnedOn;
		local speed = 1;
		if self.isTurnedOn then
			self.revUpMaxTime = self.time + 33000;
		else
			self.revUpMaxTime = 0;
			speed = -1;
		end;
		self:setVehicleRpmUp(dt, self.isTurnedOn);
		if self.throttleLeverAnim ~= nil and self.playAnimation ~= nil then
			self:playAnimation(self.throttleLeverAnim, speed, nil, true);
		end;
	end;
end;

function bobcatT180:setVehicleRpmUp(dt, isActive)
	if self.isMotorStarted and self.saveMinRpm ~= 0 then
		if dt ~= nil then
			if isActive == true then
				self.motor.minRpm = math.max(self.motor.minRpm-dt, -1000);
			else
				self.motor.minRpm = math.min(self.motor.minRpm+dt*2, self.saveMinRpm);
			end;
		else
			self.motor.minRpm = self.saveMinRpm;
		end;
		local fuelUsed = 0.00000017*math.abs(self.motor.minRpm);
		self:setFuelFillLevel(self.fuelFillLevel-fuelUsed);
		g_currentMission.missionStats.fuelUsageTotal = g_currentMission.missionStats.fuelUsageTotal + fuelUsed;
		g_currentMission.missionStats.fuelUsageSession = g_currentMission.missionStats.fuelUsageSession + fuelUsed;
	end;
end;