--
-- MF1200series
-- Specialization class for MF 1200 and 1250
--
-- @author  PeterJ - euroDZN
-- @date  09/12/2013
--
-- http://eurodzn.wordpress.com/
--
-- Copyright (C) euroDZN, Confidential, All Rights Reserved.

MF1200series = {};

function MF1200series.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Steerable, specializations) and SpecializationUtil.hasSpecialization(ArticulatedAxis, specializations);
end;

function MF1200series:load(xmlFile)
	
	self.operateLifterArms = SpecializationUtil.callSpecializationsFunction("operateLifterArms");
	self.isLifted = false;
	self.allowOperateArms = true;

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

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

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

        self.clutch.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.clutch#rotTime"), 2)*1000;
    end;
	local brakesPart = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.brakes#index"));
    if brakesPart ~= nil then
        self.brakes = {};
        self.brakes.node = brakesPart;

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

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

        self.brakes.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.brakes#rotTime"), 2)*1000;
    end;
	local throttlePart = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.throttle#index"));
    if throttlePart ~= nil then
        self.throttle = {};
        self.throttle.node = throttlePart;

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

        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.throttle#maxRot"));
        self.throttle.maxRot = {};
        self.throttle.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.throttle.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.throttle.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
	end;
	local handThrottlePart = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.handThrottle#index"));
    if handThrottlePart ~= nil then
        self.handThrottle = {};
        self.handThrottle.node = handThrottlePart;

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

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.handThrottle#maxRot"));
        self.handThrottle.maxRot = {};
        self.handThrottle.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.handThrottle.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.handThrottle.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
	end;	
	local liftLeverPart = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.liftLever#index"));
    if liftLeverPart ~= nil then
        self.liftLever = {};
        self.liftLever.node = liftLeverPart;

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

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

        self.liftLever.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.liftLever#rotTime"), 2)*1000;
    end;
	local lightSwitchPart = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.lightSwitch#index"));
    if lightSwitchPart ~= nil then
        self.lightSwitch = {};
        self.lightSwitch.node = lightSwitchPart;

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

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

        self.lightSwitch.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.lightSwitch#rotTime"), 2)*1000;
		self.lightsOn = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.lights.light#decoration"));
    end;
	local batteryPart = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.needles.battery#index"));
    if batteryPart ~= nil then
        self.batteryNeedle = {};
        self.batteryNeedle.node = batteryPart;

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

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.needles.battery#maxRot"));
        self.batteryNeedle.maxRot = {};
        self.batteryNeedle.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.batteryNeedle.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.batteryNeedle.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
		
        self.batteryNeedle.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.needles.battery#rotTime"), 2)*1000;
	end;
	local temperaturePart = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.needles.temperature#index"));
    if temperaturePart ~= nil then
        self.tempNeedle = {};
        self.tempNeedle.node = temperaturePart;

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

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

        self.tempNeedle.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.needles.temperature#rotTime"), 2)*1000;
    end;
	local pressurePart = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.needles.pressure#index"));
    if pressurePart ~= nil then
        self.pressureNeedle = {};
        self.pressureNeedle.node = pressurePart;

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

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

        self.pressureNeedle.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.needles.pressure#rotTime"), 2)*1000;
    end;
	local RPMneedlePart = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.needles.rpm#index"));
    if RPMneedlePart ~= nil then
        self.RPMneedle = {};
        self.RPMneedle.node = RPMneedlePart;

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

        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.needles.rpm#maxRot"));
        self.RPMneedle.maxRot = {};
        self.RPMneedle.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.RPMneedle.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.RPMneedle.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
	end;
	if batteryPart ~= nil or temperaturePart ~= nil or pressurePart ~= nil then 
		self.hasNeedles = true;
	end;
	
	self.lifterArmsAnim = getXMLString(xmlFile, "vehicle.lifterArms#animationName");
	
	self.toplinkSup = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.attachers#toplinkSup"));
	local highHitch = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.attachers#highHitch"));
	if highHitch ~= nil then
		self.highHitch = highHitch;
		setVisibility(self.highHitch, false);
	end;
	
	local fuelIndicatorPart = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.needles.fuel#index"));
	if fuelIndicatorPart ~= nil then
        self.fuelIndicator = {};
        self.fuelIndicator.node = fuelIndicatorPart;
		local x,_,z = getScale(self.fuelIndicator.node);
        self.fuelIndicator.x = x;
        self.fuelIndicator.z = z;
	end;
	
	self.articulatedPart = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.articulatedAxis.articulatedPart#index"));

	self.drivingShaft = {};
	local i = 0;
	while true do
		local key = string.format("vehicle.drivingShaft.driveShaft(%d)", i);
		if not hasXMLProperty(xmlFile, key) then
			break;
		end;
		local driveShaft = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#index"));
		local speed = Utils.getNoNil(getXMLFloat(xmlFile, key.."#speed"), 0.003);
		local yOffset = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, key.."#yOffset"),0));
		if driveShaft ~= nil then
			table.insert(self.drivingShaft, {node=driveShaft, speed=speed, yOffset=yOffset});
		end;
		i = i + 1;
	end;
	self.powerShaft = {};
	local i = 0;
	while true do
		local key = string.format("vehicle.powerShaftNodes.powerShaft(%d)", i);
		if not hasXMLProperty(xmlFile, key) then
			break;
		end;
		local driveShaft = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#index"));
		local x,y,z = Utils.getVectorFromString(getXMLString(xmlFile, key.. "#speed"));
		local speed = {x,y,z};
		local runOutTime = Utils.getNoNil(getXMLFloat(xmlFile, key.. "#runOutTime"), 2)*1000;
		if driveShaft ~= nil then
			local rotationSpeedMax = speed;
			local rotationSpeedMin = {0,0,0};
			local rotationSpeedCurrent = {0,0,0};
			table.insert(self.powerShaft, {node=driveShaft, speed=speed, rotationSpeedMax=rotationSpeedMax, rotationSpeedMin=rotationSpeedMin, rotationSpeedCurrent=rotationSpeedCurrent, runOutTime=runOutTime, runOutTime=runOutTime});
		end;
		i = i + 1;
	end;

	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;

		local attacherJointCount = i;
		i = 0;
		while true do
			local baseName = string.format("vehicle.trailerAttacherJoints.trailerAttacherJoint(%d)", i);
			local index = getXMLString(xmlFile, baseName.. "#index");
			if index == nil then
				break;
			end;
			
			local joint = self.attacherJoints[attacherJointCount + 1 + i];
			local hoseAttacher = Utils.indexToObject(self.components, getXMLString(xmlFile, baseName .. "#hose"));
			if hoseAttacher ~= nil then
				joint.hydrahoseAttacher = hoseAttacher;
			end;
			i = i+1;
		end;
	end;
	
    self.beaconLightsRot = {};
    local i = 0;
    while true do
        local key = string.format("vehicle.beaconLights.beaconLight(%d)", i);
        if not hasXMLProperty(xmlFile, key) then
            break;
        end;
        local node = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#rotPart"));
        local speed = Utils.getNoNil(getXMLFloat(xmlFile, key.."#speed"), 0.02);
        if node ~= nil then
            table.insert(self.beaconLightsRot, {node=node, speed=speed});
        end;
        i = i + 1;
    end;
end;

function MF1200series:delete()
end;

function MF1200series:readStream(streamId, connection)
	local isLifted = streamReadBool(streamId);
	self:operateLifterArms(isLifted, true);
end;

function MF1200series:writeStream(streamId, connection)
	streamWriteBool(streamId, self.isLifted);
end;

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

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

function MF1200series:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	if not resetVehicles then
		local isLifted = getXMLBool(xmlFile, key.."#liftArmsRaised");
		if isLifted ~= nil then
			self:operateLifterArms(isLifted);
		end;
	end;
	return BaseMission.VEHICLE_LOAD_OK;
end;

function MF1200series:getSaveAttributesAndNodes(nodeIdent)
	local attributes = 'liftArmsRaised="'..tostring(self.isLifted)..'"';
	return attributes, nil;
end;

function MF1200series:update(dt)
	if self:getIsActive() then
		if self:getIsActiveForInput(true) then
			if self.isMotorStarted and self.allowOperateArms then
				if InputBinding.hasEvent(InputBinding.LOWER_IMPLEMENT) then
					self:operateLifterArms(not self.isLifted);
				end;
			end;
		end;
		if self.clutch ~= nil then
			local x, y, z = getRotation(self.clutch.node);
			local rot = {x,y,z};
			local newRot = Utils.getMovedLimitedValues(rot, self.clutch.maxRot, self.clutch.minRot, 3, self.clutch.rotTime, dt, (self.brakeLightsVisibility or self.movingDirection == 0));
			setRotation(self.clutch.node, unpack(newRot));
		end;
		if self.brakes ~= nil then
			local x, y, z = getRotation(self.brakes.node);
			local rot = {x,y,z};
			local newRot = Utils.getMovedLimitedValues(rot, self.brakes.maxRot, self.brakes.minRot, 3, self.brakes.rotTime, dt, (self.brakeLightsVisibility or self.movingDirection == 0));
			setRotation(self.brakes.node, unpack(newRot));
		end;
		local maxThrottle = 1500;
		if self.throttle ~= nil and self.RPMneedle ~= nil then
			if self.isMotorStarted then
				local x, y, z = getRotation(self.throttle.node);
				x = ((self.throttle.maxRot[1] - self.throttle.minRot[1]) / maxThrottle) * (self.motor.lastMotorRpm/1.5) + self.throttle.minRot[1];
				y = ((self.throttle.maxRot[2] - self.throttle.minRot[2]) / maxThrottle) * (self.motor.lastMotorRpm/1.5) + self.throttle.minRot[2];
				z = ((self.throttle.maxRot[3] - self.throttle.minRot[3]) / maxThrottle) * (self.motor.lastMotorRpm/1.5) + self.throttle.minRot[3];
				setRotation(self.throttle.node, x, y ,z);
				local x1, y1, z1 = getRotation(self.RPMneedle.node);
				x1 = ((self.RPMneedle.maxRot[1] - self.RPMneedle.minRot[1]) / maxThrottle) * (self.motor.lastMotorRpm/1.5) + self.RPMneedle.minRot[1];
				y1 = ((self.RPMneedle.maxRot[2] - self.RPMneedle.minRot[2]) / maxThrottle) * (self.motor.lastMotorRpm/1.5) + self.RPMneedle.minRot[2];
				z1 = ((self.RPMneedle.maxRot[3] - self.RPMneedle.minRot[3]) / maxThrottle) * (self.motor.lastMotorRpm/1.5) + self.RPMneedle.minRot[3];
				setRotation(self.RPMneedle.node, x1, y1 ,z1);
			elseif not self.isMotorStarted then
				setRotation(self.throttle.node, self.throttle.minRot[1], self.throttle.minRot[2], self.throttle.minRot[3]);
				setRotation(self.RPMneedle.node, self.RPMneedle.minRot[1], self.RPMneedle.minRot[2], self.RPMneedle.minRot[3]);
			end;
		end;
		if self.handThrottle ~= nil and self.rotLeverPercent ~= nil then
			local maxX,maxY,maxZ = (self.handThrottle.maxRot[1] - self.handThrottle.minRot[1]), (self.handThrottle.maxRot[2] - self.handThrottle.minRot[2]), (self.handThrottle.maxRot[3] - self.handThrottle.minRot[3]);
			local rotX,rotY,rotZ = maxX*(self.rotLeverPercent/100),maxY*(self.rotLeverPercent/100),maxZ*(self.rotLeverPercent/100);
			setRotation(self.handThrottle.node, rotX,rotY,rotZ);
		end;
		if self.liftLever ~= nil then
			if table.getn(self.attachedImplements) > 0 then			
				for k,implement in pairs(self.attachedImplements) do
					local jointIndex = implement.jointDescIndex;
					local attachedTool = implement.object;
					if jointIndex == 1 then
						if attachedTool.allowsLowering then
							if attachedTool:isLowered(false) then
								self.liftArmsLever = true;
							else
								self.liftArmsLever = false;
							end;
						end;
					else
						if self.allowOperateArms then
							self.liftArmsLever = not self.isLifted;
						end;							
					end;
					if attachedTool.isTurnedOn ~= nil then
						if attachedTool.isTurnedOn then
							if attachedTool.ptoInput ~= nil and attachedTool.ptoInput.node ~= nil then
								self.operatePTO = true;
							elseif attachedTool.powerShaft ~= nil and attachedTool.powerShaft.node ~= nil then
								self.operatePTO = true;
							end;
						else
							self.operatePTO = false;
						end;
					end;
					if attachedTool.isThreshing ~= nil then
						if attachedTool.isThreshing then
							if attachedTool.ptoInput ~= nil and attachedTool.ptoInput.node ~= nil then
								self.operatePTO = true;
							elseif attachedTool.powerShaft ~= nil and attachedTool.powerShaft.node ~= nil then
								self.operatePTO = true;
							end;
						else
							self.operatePTO = false;
						end;
					end;
				end;
			else
				if self.allowOperateArms then
					self.liftArmsLever = not self.isLifted;
				end;
				self.operatePTO = false;
			end;
			local x, y, z = getRotation(self.liftLever.node);
			local rot = {x,y,z};
			local newRot = Utils.getMovedLimitedValues(rot, self.liftLever.maxRot, self.liftLever.minRot, 3, self.liftLever.rotTime, dt, not self.liftArmsLever);
			setRotation(self.liftLever.node, unpack(newRot));
		end;
		if self.lightSwitch ~= nil then
			self.isLightsOn = getVisibility(self.lightsOn);
			local x, y, z = getRotation(self.lightSwitch.node);
			local rot = {x,y,z};
			local newRot = Utils.getMovedLimitedValues(rot, self.lightSwitch.maxRot, self.lightSwitch.minRot, 3, self.lightSwitch.rotTime, dt, not self.isLightsOn);
			setRotation(self.lightSwitch.node, unpack(newRot));
		end;
		if self.hasNeedles then
			if self.isMotorStarted then
				self.operateNeedles = true;
			else
				self.operateNeedles = false;
			end;
			if self.fuelIndicator.node ~= nil then
				local currentFuelPercentage = self.fuelFillLevel / self.fuelCapacity;
				setScale(self.fuelIndicator.node, self.fuelIndicator.x, currentFuelPercentage, self.fuelIndicator.z);
			end;
			if self.batteryNeedle.node ~= nil then
				local x, y, z = getRotation(self.batteryNeedle.node);
				local rot = {x,y,z};
				local newRot = Utils.getMovedLimitedValues(rot, self.batteryNeedle.maxRot, self.batteryNeedle.minRot, 3, self.batteryNeedle.rotTime, dt, not self.operateNeedles);
				setRotation(self.batteryNeedle.node, unpack(newRot));
			end;
			if self.tempNeedle.node ~= nil then
				local x, y, z = getRotation(self.tempNeedle.node);
				local rot = {x,y,z};
				local newRot = Utils.getMovedLimitedValues(rot, self.tempNeedle.maxRot, self.tempNeedle.minRot, 3, self.tempNeedle.rotTime, dt, not self.operateNeedles);
				setRotation(self.tempNeedle.node, unpack(newRot));
			end;
			if self.pressureNeedle.node ~= nil then
				local x, y, z = getRotation(self.pressureNeedle.node);
				local rot = {x,y,z};
				local newRot = Utils.getMovedLimitedValues(rot, self.pressureNeedle.maxRot, self.pressureNeedle.minRot, 3, self.pressureNeedle.rotTime, dt, not self.operateNeedles);
				setRotation(self.pressureNeedle.node, unpack(newRot));
			end;
		end;	
	end;
	if self.articulatedPart ~= nil then
		local 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;
		setRotation(self.articulatedPart, 0, steeringAngle, 0);
	end;
end;

function MF1200series:updateTick(dt)
	if self.drivingShaft ~= nil then
		for _, driveShaft in pairs(self.drivingShaft) do
			local x,_,_ = getRotation(self.wheels[1].driveNode);
			setRotation(driveShaft.node, 0, driveShaft.yOffset, x*driveShaft.speed);
		end;
	end;
	if self.powerShaft ~= nil then
		for _, pto in pairs(self.powerShaft) do
			local values = Utils.getMovedLimitedValues(pto.rotationSpeedCurrent, pto.rotationSpeedMax, pto.rotationSpeedMin, 3, pto.runOutTime, dt, not self.operatePTO);
			pto.rotationSpeedCurrent = values;
			local x,y,z = unpack(pto.rotationSpeedCurrent);
			rotate(pto.node, x, y, z);
		end;
	end;
	if self.beaconLightsActive then
		for _, beaconLightRot in pairs(self.beaconLightsRot) do
			rotate(beaconLightRot.node, 0, beaconLightRot.speed*dt, 0);
		end;
	end;
end;

function MF1200series:draw()
	if self:getIsActive() and self:getIsActiveForInput(true) then
		if self.isMotorStarted and self.allowOperateArms then
			if self.isLifted then
				g_currentMission:addHelpButtonText(g_i18n:getText("lower_arms"), InputBinding.LOWER_IMPLEMENT);
			else
				g_currentMission:addHelpButtonText(g_i18n:getText("lift_arms"), InputBinding.LOWER_IMPLEMENT);
			end;
		end;
	end;
end;

function MF1200series:attachImplement(implement)
	local jointType = implement.object.attacherJoint.jointType;
	local jointIndex = implement.jointDescIndex;
	
	if jointType == Vehicle.JOINTTYPE_IMPLEMENT then
		setVisibility(self.toplinkSup, false);
		self.allowOperateArms = false;
		if self.isLifted then
			self.isLifted = false;
		end;
	elseif jointType == Vehicle.JOINTTYPE_TRAILER then
		setVisibility(self.highHitch, true);
	end;
end;

function MF1200series:detachImplement(implementIndex)
	local implement = self.attachedImplements[implementIndex];
	local jointIndex = implement.jointDescIndex;
	local jointType = implement.object.attacherJoint.jointType;

	if jointIndex == 1 then
		setVisibility(self.toplinkSup, true);
		self.allowOperateArms = true;
	elseif jointIndex == 3 then
		setVisibility(self.highHitch, false);
	end;
end;

function MF1200series:operateLifterArms(isLifted, noEventSend)
	SetLifterArmsEvent.sendEvent(self, isLifted, noEventSend)
	if isLifted ~= nil and isLifted ~= self.isLifted then
		if self.lifterArmsAnim ~= nil and self.playAnimation ~= nil then
			self.isLifted = isLifted;
			local direction = 1;
			if not self.isLifted then
				direction = -1;
			end;
			self:playAnimation(self.lifterArmsAnim, direction, nil, true);
		end;
	end;
end;

 
SetLifterArmsEvent = {};
SetTurnedOnEvent_mt = Class(SetLifterArmsEvent, Event);
  
InitEventClass(SetLifterArmsEvent, "SetLifterArmsEvent");
  
function SetLifterArmsEvent:emptyNew()
	local self = Event:new(SetTurnedOnEvent_mt);
	return self;
end;

function SetLifterArmsEvent:new(object, isLifted)
	local self = SetLifterArmsEvent:emptyNew()
	self.object = object;
	self.isLifted = isLifted;
	return self;
end;

function SetLifterArmsEvent:readStream(streamId, connection)
	local id = streamReadInt32(streamId);
	self.isLifted = streamReadBool(streamId);
	self.object = networkGetObject(id);
	self:run(connection);
end;

function SetLifterArmsEvent:writeStream(streamId, connection)
	streamWriteInt32(streamId, networkGetObjectId(self.object));
	streamWriteBool(streamId, self.isLifted);
end;

function SetLifterArmsEvent:run(connection)
	if not connection:getIsServer() then
		g_server:broadcastEvent(self, false, connection, self.object);
	end;
	if self.object ~= nil then
		self.object:operateLifterArms(self.isLifted, true);
	end;
end;

function SetLifterArmsEvent.sendEvent(vehicle, isLifted, noEventSend)
	if isLifted ~= vehicle.isLifted then
		if noEventSend == nil or noEventSend == false then
			if g_server ~= nil then
				g_server:broadcastEvent(SetLifterArmsEvent:new(vehicle, isLifted), nil, nil, vehicle);
			else
				g_client:getServerConnection():sendEvent(SetLifterArmsEvent:new(vehicle, isLifted));
			end;
		end;
	end;
end;