--
-- Rolmasz S061 "Pomorzanin"
-- author: Burner
-- date: 17.01.2012
-- edit: 19.04.2013
--

S061 = {};

function S061.prerequisitesPresent(specializations)
	return SpecializationUtil.hasSpecialization(SowingMachine, specializations);
end;

function S061:load(xmlFile)
	self.objectInRange = S061.objectInRange;
	self.getIsAreaActive = Utils.overwrittenFunction(self.getIsAreaActive, S061.getIsAreaActive);
	self.aiFreeze = SpecializationUtil.callSpecializationsFunction("aiFreeze");
	self.aiUnfreeze = SpecializationUtil.callSpecializationsFunction("aiUnfreeze");
	self.setTramlinesOn = SpecializationUtil.callSpecializationsFunction("setTramlinesOn");
	self.setVehicleRpmUp = SpecializationUtil.callSpecializationsFunction("setVehicleRpmUp");
	
	self.powerShaftNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.powerShaft#rootNode"));
	
	self.numMarkerAreas = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.markerAreas#count"), 0);
    self.markerAreas = {}
    for i=1, self.numMarkerAreas do
        self.markerAreas[i] = {};
        local areanamei = string.format("vehicle.markerAreas.markerArea%d", i);
        self.markerAreas[i].start = Utils.indexToObject(self.components, getXMLString(xmlFile, areanamei .. "#startIndex"));
        self.markerAreas[i].width = Utils.indexToObject(self.components, getXMLString(xmlFile, areanamei .. "#widthIndex"));
        self.markerAreas[i].height = Utils.indexToObject(self.components, getXMLString(xmlFile, areanamei .. "#heightIndex"));
    end;
	
	self.aiFieldDetectArea = {};
    self.aiFieldDetectArea.start = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.aiFieldDetectArea#startIndex"));
    self.aiFieldDetectArea.width = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.aiFieldDetectArea#widthIndex"));
    self.aiFieldDetectArea.height = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.aiFieldDetectArea#heightIndex"));
	
	self.aiFirstTimeRun = false;
	self.displayWorkerInfo = false;
	
	self.leftMarkerRope = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.leftMarkerRope#index"));
	self.rightMarkerRope = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.rightMarkerRope#index"));
	
	self.leftMarkerSpeedRotatingParts = {};
	local i=0;
	while true do
		local baseName = string.format("vehicle.leftMarkerSpeedRotatingParts.leftMarkerSpeedRotatingPart(%d)", i);
		local index = getXMLString(xmlFile, baseName.. "#index");
		if index == nil then
			break;
		end;
		local node = Utils.indexToObject(self.components, index);
		if node ~= nil then
			local entry = {};
			entry.node = node;
			entry.rotationSpeedScale = getXMLFloat(xmlFile, baseName.."#rotationSpeedScale");
			if entry.rotationSpeedScale == nil then
				entry.rotationSpeedScale = 1.0/Utils.getNoNil(getXMLFloat(xmlFile, baseName.."#radius"), 1);
			end;
			entry.foldMinLimit = Utils.getNoNil(getXMLFloat(xmlFile, baseName .. "#foldMinLimit"), 0);
			entry.foldMaxLimit = Utils.getNoNil(getXMLFloat(xmlFile, baseName .. "#foldMaxLimit"), 1);
			table.insert(self.leftMarkerSpeedRotatingParts, entry);
		end;
		i = i+1;
	end;
	
	self.rightMarkerSpeedRotatingParts = {};
	local i=0;
	while true do
		local baseName = string.format("vehicle.rightMarkerSpeedRotatingParts.rightMarkerSpeedRotatingPart(%d)", i);
		local index = getXMLString(xmlFile, baseName.. "#index");
		if index == nil then
			break;
		end;
		local node = Utils.indexToObject(self.components, index);
		if node ~= nil then
			local entry = {};
			entry.node = node;
			entry.rotationSpeedScale = getXMLFloat(xmlFile, baseName.."#rotationSpeedScale");
			if entry.rotationSpeedScale == nil then
				entry.rotationSpeedScale = 1.0/Utils.getNoNil(getXMLFloat(xmlFile, baseName.."#radius"), 1);
			end;
			entry.foldMinLimit = Utils.getNoNil(getXMLFloat(xmlFile, baseName .. "#foldMinLimit"), 0);
			entry.foldMaxLimit = Utils.getNoNil(getXMLFloat(xmlFile, baseName .. "#foldMaxLimit"), 1);
			table.insert(self.rightMarkerSpeedRotatingParts, entry);
		end;
		i = i+1;
	end;
	
	self.leftMarkerParticleSystems = {};
	local psName = "vehicle.leftMarkerParticleSystem";
	Utils.loadParticleSystem(xmlFile, self.leftMarkerParticleSystems, psName, self.components, false, nil, self.baseDirectory);
	self.rightMarkerParticleSystems = {};
	local psName = "vehicle.rightMarkerParticleSystem";
	Utils.loadParticleSystem(xmlFile, self.rightMarkerParticleSystems, psName, self.components, false, nil, self.baseDirectory);
	
	local rotorSound = getXMLString(xmlFile, "vehicle.rotorSound#file");
	if rotorSound ~= nil and rotorSound ~= "" then
		rotorSound = Utils.getFilename(rotorSound, self.baseDirectory);
		self.rotorSound = createSample("rotorSound");
		self.rotorSoundEnabled = false;
		loadSample(self.rotorSound, rotorSound, false);
		self.rotorSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.rotorSound#pitchOffset"), 1);
		self.rotorSoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.rotorSound#volume"), 1);
	end;
	
	local grainSound = getXMLString(xmlFile, "vehicle.grainSound#file");
	if grainSound ~= nil and grainSound ~= "" then
		grainSound = Utils.getFilename(grainSound, self.baseDirectory);
		self.grainSound = createSample("grainSound");
		self.grainSoundEnabled = false;
		loadSample(self.grainSound, grainSound, false);
		self.grainSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.grainSound#pitchOffset"), 1);
		self.grainSoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.grainSound#volume"), 1);
	end;
	
	local hydraulicSound = getXMLString(xmlFile, "vehicle.hydraulicSound#file");
	if hydraulicSound ~= nil and hydraulicSound ~= "" then
		hydraulicSound = Utils.getFilename(hydraulicSound, self.baseDirectory);
		self.hydraulicSound = createSample("hydraulicSound");
		self.hydraulicSoundEnabled = false;
		loadSample(self.hydraulicSound, hydraulicSound, false);
		self.hydraulicSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.hydraulicSound#pitchOffset"), 1);
		self.hydraulicSoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.hydraulicSound#volume"), 1);
	end;
	
	local sowingAISound = getXMLString(xmlFile, "vehicle.sowingAISound#file");
		if sowingAISound ~= nil and sowingAISound ~= "" then
		sowingAISound = Utils.getFilename(sowingAISound, self.baseDirectory);
		self.sowingAISoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.sowingAISound#pitchOffset"), 0);
		self.sowingAISoundRadius = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.sowingAISound#radius"), 50);
		self.sowingAISoundInnerRadius = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.sowingAISound#innerRadius"), 10);
		self.sowingAISoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.sowingAISound#volume"), 1);
		self.sowingAISound = createAudioSource("sowingAISound", sowingAISound, self.sowingAISoundRadius, self.sowingAISoundInnerRadius, self.sowingAISoundVolume, 0);
		link(self.components[1].node, self.sowingAISound);
		setVisibility(self.sowingAISound, false);
	end;
		
	self.tramlines = false;
	self.saveMinRpm = 0;
end;

function S061:readStream(streamId, connection)
	self:setTramlinesOn(streamReadBool(streamId), true);
end;

function S061:writeStream(streamId, connection)
	streamWriteBool(streamId, self.tramlines);
end;

function S061:delete()
	Utils.deleteParticleSystem(self.leftMarkerParticleSystems);
	Utils.deleteParticleSystem(self.rightMarkerParticleSystems);
	if self.rotorSound ~= nil then
		delete(self.rotorSound);
		self.rotorSoundEnabled = false;
	end;
end;

function S061:update(dt)
	if self.isClient then
		-- left arm in range
		if self.animationParts[1].clipEndTime == false then
			if self:objectInRange(self.animationParts[2].rootNode) then
				if InputBinding.hasEvent(InputBinding.S061_FoldSowingArm) then
					if self.animationParts[2].clipEndTime then
						self:setAnimationTime(2, self.animationParts[2].startPosition);
						self:setAnimationTime(5, self.animationParts[5].startPosition);
						self:setAnimationTime(7, self.animationParts[7].startPosition);
					elseif self.animationParts[2].clipStartTime then
						self:setAnimationTime(2, self.animationParts[2].animDuration);
					end;
				end;
				if self.animationParts[2].clipEndTime then
					g_currentMission:addHelpButtonText(string.format(g_i18n:getText("S061_FoldSowingArm")), InputBinding.S061_FoldSowingArm);
				else
					g_currentMission:addHelpButtonText(string.format(g_i18n:getText("S061_UnfoldSowingArm")), InputBinding.S061_FoldSowingArm);
				end;
			end;
		end;
		
		-- right arm in range
		if self.animationParts[1].clipEndTime == false then
			if self:objectInRange(self.animationParts[3].rootNode) then
				if InputBinding.hasEvent(InputBinding.S061_FoldSowingArm) then
					if self.animationParts[3].clipEndTime then
						self:setAnimationTime(3, self.animationParts[3].startPosition);
						self:setAnimationTime(6, self.animationParts[6].startPosition);
						self:setAnimationTime(8, self.animationParts[8].startPosition);
					elseif self.animationParts[3].clipStartTime then
						self:setAnimationTime(3, self.animationParts[3].animDuration);
					end;
				end;
				if self.animationParts[3].clipEndTime then
					g_currentMission:addHelpButtonText(string.format(g_i18n:getText("S061_FoldSowingArm")), InputBinding.S061_FoldSowingArm);
				else
					g_currentMission:addHelpButtonText(string.format(g_i18n:getText("S061_UnfoldSowingArm")), InputBinding.S061_FoldSowingArm);
				end;
			end;
		end;
		
		-- grain tank cover in range
		if self:objectInRange(self.animationParts[4].rootNode) then
			if InputBinding.isPressed(InputBinding.S061_OpenGrainTankCover) then
				self:setAnimationTime(4, self.animationParts[4].currentPosition+(self.animationParts[4].offSet+dt), false);
			elseif InputBinding.isPressed(InputBinding.S061_CloseGrainTankCover) then
				self:setAnimationTime(4, self.animationParts[4].currentPosition-(self.animationParts[4].offSet+dt), false);
			end;
			if self.animationParts[4].clipStartTime == false then
				g_currentMission:addHelpButtonText(string.format(g_i18n:getText("S061_CloseGrainTankCover")), InputBinding.S061_CloseGrainTankCover);
			end;
			if self.animationParts[4].clipEndTime == false then
				g_currentMission:addHelpButtonText(string.format(g_i18n:getText("S061_OpenGrainTankCover")), InputBinding.S061_OpenGrainTankCover);
			end;
		end;
		
		-- left marker in range
		if self.animationParts[2].clipEndTime then
			if self:objectInRange(self.animationParts[5].rootNode) then
				if InputBinding.hasEvent(InputBinding.S061_FoldSowingArm) then
					if self.animationParts[5].clipEndTime then
						self:setAnimationTime(5, self.animationParts[5].startPosition);
						self:setAnimationTime(7, self.animationParts[7].startPosition);
					elseif self.animationParts[5].clipStartTime then
						self:setAnimationTime(5, self.animationParts[5].animDuration);
					end;
				end;
				if self.animationParts[5].clipEndTime then
					g_currentMission:addHelpButtonText(string.format(g_i18n:getText("S061_FoldMarker")), InputBinding.S061_FoldSowingArm);
				else
					g_currentMission:addHelpButtonText(string.format(g_i18n:getText("S061_UnfoldMarker")), InputBinding.S061_FoldSowingArm);
				end;
			end;
		end;
		
		-- right marker in range
		if self.animationParts[3].clipEndTime then
			if self:objectInRange(self.animationParts[6].rootNode) then
				if InputBinding.hasEvent(InputBinding.S061_FoldSowingArm) then
					if self.animationParts[6].clipEndTime then
						self:setAnimationTime(6, self.animationParts[6].startPosition);
						self:setAnimationTime(8, self.animationParts[8].startPosition);
					elseif self.animationParts[6].clipStartTime then
						self:setAnimationTime(6, self.animationParts[6].animDuration);
					end;
				end;
				if self.animationParts[6].clipEndTime then
					g_currentMission:addHelpButtonText(string.format(g_i18n:getText("S061_FoldMarker")), InputBinding.S061_FoldSowingArm);
				else
					g_currentMission:addHelpButtonText(string.format(g_i18n:getText("S061_UnfoldMarker")), InputBinding.S061_FoldSowingArm);
				end;
			end;
		end;
	end;
	
	if self:getIsActiveForSound() and self.isClient then
		if self.animationParts[1].clipEndTime == false and self.animationParts[1].clipStartTime == false then
			if not self.hydraulicSoundEnabled then
				playSample(self.hydraulicSound, 0, self.hydraulicSoundVolume, 0);
				self.hydraulicSoundEnabled = true;
			end;
		else
			if self.hydraulicSoundEnabled then
				stopSample(self.hydraulicSound);
				self.hydraulicSoundEnabled = false;
			end;
		end;
	end;
	
	if self.animationParts[1].clipEndTime then
		-- update left marker area
		if self.animationParts[5].clipEndTime and self.animationParts[7].clipStartTime then
			if self.markerAreas[1] ~= nil then
				local x,y,z = getWorldTranslation(self.markerAreas[1].start);
				local x1,y1,z1 = getWorldTranslation(self.markerAreas[1].width);
				local x2,y2,z2 = getWorldTranslation(self.markerAreas[1].height);
				Utils.updatePloughArea(x, z, x1, z1, x2, z2, false);
			end;
			for k,v in pairs(self.leftMarkerSpeedRotatingParts) do
				rotate(v.node, v.rotationSpeedScale * self.lastSpeedReal * self.movingDirection * dt, 0, 0);
			end;
			if self.lastSpeed*3600 > 3 then
				Utils.setEmittingState(self.leftMarkerParticleSystems, true);
			else
				Utils.setEmittingState(self.leftMarkerParticleSystems, false);
			end;
		else
			Utils.setEmittingState(self.leftMarkerParticleSystems, false);
		end;
				
		-- update right marker area
		if self.animationParts[6].clipEndTime and self.animationParts[8].clipStartTime then
			if self.markerAreas[2] ~= nil then
				local x,y,z = getWorldTranslation(self.markerAreas[2].start);
				local x1,y1,z1 = getWorldTranslation(self.markerAreas[2].width);
				local x2,y2,z2 = getWorldTranslation(self.markerAreas[2].height);
				Utils.updatePloughArea(x, z, x1, z1, x2, z2, false);
			end;
			for k,v in pairs(self.rightMarkerSpeedRotatingParts) do
				rotate(v.node, v.rotationSpeedScale * self.lastSpeedReal * self.movingDirection * dt, 0, 0);
			end;
			if self.lastSpeed*3600 > 3 then
				Utils.setEmittingState(self.rightMarkerParticleSystems, true);
			else
				Utils.setEmittingState(self.rightMarkerParticleSystems, false);
			end;
		else
			Utils.setEmittingState(self.rightMarkerParticleSystems, false);
		end;
		
		-- tramlines
		if self.tramlines then
			for i=3, 4 do
				if self.markerAreas[i] ~= nil then
					local x,y,z = getWorldTranslation(self.markerAreas[i].start);
					local x1,y1,z1 = getWorldTranslation(self.markerAreas[i].width);
					local x2,y2,z2 = getWorldTranslation(self.markerAreas[i].height);
					Utils.updateCultivatorArea(x, z, x1, z1, x2, z2, false);
				end;
			end;
		end;
	end;

	if self:getIsActiveForInput() then
		--lower arms
		if self.animationParts[2].clipEndTime and self.animationParts[3].clipEndTime then
			if InputBinding.hasEvent(InputBinding.S061_LowerSowingArm) then
				if self.animationParts[1].clipEndTime then
					self:setAnimationTime(1, self.animationParts[1].startPosition);
				elseif self.animationParts[1].clipStartTime then
					self:setAnimationTime(1, self.animationParts[1].animDuration);
				end;
			end;
			if InputBinding.hasEvent(InputBinding.S061_ToggleTramlines) then
				self:setTramlinesOn(not self.tramlines);
			end;
		end;
		
		-- switch markers positions
		if self.animationParts[5].clipEndTime and self.animationParts[6].clipEndTime then
			if InputBinding.hasEvent(InputBinding.S061_ToggleMarkers) then
				if self.animationParts[7].clipEndTime then
					self:setAnimationTime(7, self.animationParts[7].startPosition);
					self:setAnimationTime(8, self.animationParts[8].animDuration);
				elseif self.animationParts[7].clipStartTime then
					self:setAnimationTime(7, self.animationParts[7].animDuration);
					self:setAnimationTime(8, self.animationParts[8].startPosition);
				end;
			end;
		end;
	end;
	
	if self.attacherVehicle ~= nil then
		self:setAnimationTime(9, self.animationParts[9].animDuration);
		-- AI support
		if self.attacherVehicle.isAITractorActivated and self.aiFirstTimeRun then
			if self.animationParts[2].clipEndTime == false or self.animationParts[3].clipEndTime == false then
				self:aiFreeze();
				self:setAnimationTime(2, self.animationParts[2].animDuration);
				self:setAnimationTime(3, self.animationParts[3].animDuration);
			elseif self.animationParts[2].clipEndTime and self.animationParts[3].clipEndTime then
				if self.animationParts[5].clipEndTime == false or self.animationParts[6].clipEndTime == false then
					self:aiFreeze();
					if self.animationParts[2].clipEndTime then
						self:setAnimationTime(5, self.animationParts[5].animDuration);
					end;
					if self.animationParts[3].clipEndTime then
						self:setAnimationTime(6, self.animationParts[6].animDuration);
					end;
				elseif self.animationParts[5].clipEndTime and self.animationParts[6].clipEndTime then
					local x,y,z = getWorldTranslation(self.aiFieldDetectArea.start);
					local x1,y1,z1 = getWorldTranslation(self.aiFieldDetectArea.width);
					local x2,y2,z2 = getWorldTranslation(self.aiFieldDetectArea.height);
					local densLeft = 0;
					local densLeft = Utils.getDensity(g_currentMission.terrainDetailId, g_currentMission.ploughChannel, x, z, x1, z1, x2, z2);
					densLeft = densLeft + Utils.getDensity(g_currentMission.terrainDetailId, g_currentMission.cultivatorChannel, x, z, x1, z1, x2, z2);
					if densLeft > 0 then
						self:setAnimationTime(8, self.animationParts[8].animDuration);
					else
						self:setAnimationTime(7, self.animationParts[7].animDuration);
					end;
					self:aiUnfreeze();
					self:setAnimationTime(1, self.animationParts[1].animDuration);
					self.aiFirstTimeRun = false;
				end;
			end;
		else
			self.displayWorkerInfo = false;
		end;
	else
		self.displayWorkerInfo = false;
		self:setAnimationTime(9, self.animationParts[9].startPosition);
	end;

	if self.powerShaftNode ~= nil and self.isTurnedOn then
		rotate(self.powerShaftNode, 0, 0, 0.8);
	end;
	
	if self.leftMarkerRope ~= nil then
		if self.animationParts[5].clipEndTime then
			setVisibility(self.leftMarkerRope, true);
		else
			setVisibility(self.leftMarkerRope, false);
		end;
	end;
	
	if self.rightMarkerRope ~= nil then
		if self.animationParts[6].clipEndTime then
			setVisibility(self.rightMarkerRope, true);
		else
			setVisibility(self.rightMarkerRope, false);
		end;
	end;
	
	if self.isTurnedOn then
		self:setAnimationTime(10, self.animationParts[10].animDuration);
		self:setVehicleRpmUp(dt, true);
		if self.isClient and self:getIsActiveForSound() then
			if not self.rotorSoundEnabled and self:getIsActiveForSound() then
				--setSamplePitch(self.rotorSound, self.rotorSoundPitchOffset);
				playSample(self.rotorSound, 0, self.rotorSoundVolume, 0);
				self.rotorSoundEnabled = true;
			end;
			if not self.grainSoundEnabled  and self.fillLevel > 0 then
				playSample(self.grainSound, 1, self.grainSoundVolume, 0);
				self.grainSoundEnabled = true;
			end
		end;
	else
		self:setAnimationTime(10, self.animationParts[10].startPosition);
		if self.isClient and self:getIsActiveForSound() then
			if self.rotorSoundEnabled then
				stopSample(self.rotorSound);
				self.rotorSoundEnabled = false;
			end;
			if self.grainSoundEnabled then
				playSample(self.grainSound, 1, self.grainSoundVolume, 0);
				self.grainSoundEnabled = false;
			end
		end;
		self:setVehicleRpmUp(dt, false);
	end
	
	if self.isTurnedOn and not self:getIsActiveForSound() then
		if self.sowingAISound ~= nil then
			setVisibility(self.sowingAISound, true);
		end;
	else
		if self.sowingAISound ~= nil then
			setVisibility(self.sowingAISound, false);
		end;		
	end;
end;

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

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

function S061:draw()
	if self.isClient then
		if self.animationParts[2].clipEndTime or self.animationParts[3].clipEndTime then
			if self.animationParts[1].clipEndTime then
				g_currentMission:addHelpButtonText(g_i18n:getText("S061_RaiseSowingArms"), InputBinding.S061_LowerSowingArm);
			else
				g_currentMission:addHelpButtonText(g_i18n:getText("S061_LowerSowingArms"), InputBinding.S061_LowerSowingArm);
			end;
			if self.tramlines then
				g_currentMission:addHelpButtonText(g_i18n:getText("S061_TramlinesOff"), InputBinding.S061_ToggleTramlines);
			else
				g_currentMission:addHelpButtonText(g_i18n:getText("S061_TramlinesOn"), InputBinding.S061_ToggleTramlines);
			end;
		else
			g_currentMission:addExtraPrintText(g_i18n:getText("S061_FoldSowingArmsInfo"));
		end;
		if self.animationParts[2].clipEndTime and self.animationParts[3].clipEndTime then
			if self.animationParts[5].clipEndTime and self.animationParts[6].clipEndTime then
				g_currentMission:addHelpButtonText(g_i18n:getText("S061_ToggleMarkers"), InputBinding.S061_ToggleMarkers);
			else
				g_currentMission:addExtraPrintText(g_i18n:getText("S061_ToggleMarkersInfo"));
			end;
		end;
		if self.displayWorkerInfo then
			g_currentMission:addWarning(g_i18n:getText("S061_WorkerInfo") .. "\n" .. g_i18n:getText("S061_PleaseWait"), 0.040, 0.035);
		end;
	end;
end;

function S061:objectInRange(object)
	if g_currentMission.player ~= nil and object ~= nil then
		local nearestDistance = 2;
		local vx, vy, vz = getWorldTranslation(g_currentMission.player.rootNode);
		local px, py, pz = getWorldTranslation(object); 
		local distance = Utils.vector3Length(px-vx, py-vy, pz-vz);	
		if distance < nearestDistance then
			return true;
		else
			return false;
		end;
	else
		return false;
	end;
end;

function S061:getIsAreaActive(superFunc, area)
	if self.animationParts[1].clipEndTime and self.animationParts[2].clipEndTime and self.animationParts[3].clipEndTime then
		isLowered = true;
	else
		isLowered = false;
	end;
	if superFunc ~= nil then
		return superFunc(self, area) and isLowered;
	end;
	return isLowered;
end;

function S061:setVehicleRpmUp(dt, isActive)
	if self.attacherVehicleCopy ~= nil and self.saveMinRpm ~= 0 then
		if dt ~= nil then
			if isActive == true then
				self.attacherVehicleCopy.motor.minRpm = math.max(self.attacherVehicleCopy.motor.minRpm-(dt*2), -1200);
			else
				self.attacherVehicleCopy.motor.minRpm = math.min(self.attacherVehicleCopy.motor.minRpm+(dt*5), self.saveMinRpm);
			end;
		else
			self.attacherVehicleCopy.motor.minRpm = self.saveMinRpm;
		end;
	end;
end;

function S061:aiTurnOn()
	if self.animationParts[2].clipEndTime and self.animationParts[3].clipEndTime and self.animationParts[5].clipEndTime and self.animationParts[6].clipEndTime and (self.animationParts[7].clipEndTime or self.animationParts[8].clipEndTime) then
		self:setAnimationTime(1, self.animationParts[1].animDuration);
	else
		self.aiFirstTimeRun = true;
	end;
end;

function S061:aiTurnOff()
	self:setAnimationTime(1, self.animationParts[1].startPosition);
end;

function S061:aiLower()
	self:setAnimationTime(1, self.animationParts[1].animDuration);
end;

function S061:aiRaise()
	self:setAnimationTime(1, self.animationParts[1].startPosition);
end;

function S061:aiRotateLeft()
	if self.animationParts[5].clipEndTime and self.animationParts[6].clipEndTime then
		self:setAnimationTime(7, self.animationParts[7].animDuration);
		self:setAnimationTime(8, self.animationParts[8].startPosition);
	end;
end;

function S061:aiRotateRight()
	if self.animationParts[5].clipEndTime and self.animationParts[6].clipEndTime then
		self:setAnimationTime(7, self.animationParts[7].startPosition);
		self:setAnimationTime(8, self.animationParts[8].animDuration);
	end;
end;

function S061:onAttach(attacherVehicle)
	self.av = attacherVehicle;
	self.av.motor.maxRpmBackup = {}
	for k, steerable in pairs(g_currentMission.steerables) do
		if steerable == attacherVehicle then
			self.saveMinRpm = attacherVehicle.motor.minRpm;
			if self.attacherVehicleCopy == nil then
				self.attacherVehicleCopy = self.attacherVehicle;
			end;
		elseif steerable == attacherVehicle.attacherVehicle then
			self.saveMinRpm = attacherVehicle.attacherVehicle.motor.minRpm;
			if self.attacherVehicleCopy == nil then
				self.attacherVehicleCopy = attacherVehicle.attacherVehicle;
			end;
		end;
	end;
end;

function S061:onDetach()
	S061.onDeactivateSounds(self);
	if self.grainSoundEnabled then
		stopSample(self.grainSound);
		self.grainSoundEnabled = false;
	end;
end;

function S061:onDeactivate()
	Utils.setEmittingState(self.leftMarkerParticleSystems, false);
	Utils.setEmittingState(self.rightMarkerParticleSystems, false);
	self:setVehicleRpmUp(nil, false);
	S061.onDeactivateSounds(self);
	if self.grainSoundEnabled then
		stopSample(self.grainSound);
		self.grainSoundEnabled = false;
	end;
end;

function S061:onDeactivateSounds()
	if self.rotorSoundEnabled then
		stopSample(self.rotorSound);
		self.rotorSoundEnabled = false;
	end;
	if self.hydraulicSoundEnabled then
		stopSample(self.hydraulicSound);
		self.hydraulicSoundEnabled = false;
	end;
end;

function S061:onLeave()
    if self.deactivateOnLeave then
        RPMControl.onDeactivate(self);
    end;
	S061.onDeactivateSounds(self)
end;

function S061:aiFreeze()
	self.attacherVehicle.motor.maxRpm[1] = 0;
	self.attacherVehicle.motor.maxRpm[2] = 0;
	self.displayWorkerInfo = true;
end;

function S061:aiUnfreeze()
end;

function S061:setTramlinesOn(tramlinesOn, noEventSend)
	SetTramlinesOnEvent.sendEvent(self, tramlinesOn, noEventSend)
	self.tramlines = tramlinesOn;
end;

-- events
SetTramlinesOnEvent = {};
SetTramlinesOnEvent_mt = Class(SetTramlinesOnEvent, Event);

InitEventClass(SetTramlinesOnEvent, "SetTramlinesOnEvent");

function SetTramlinesOnEvent:emptyNew()
    local self = Event:new(SetTramlinesOnEvent_mt);
    self.className="SetTramlinesOnEvent";
    return self;
end;

function SetTramlinesOnEvent:new(vehicle, tramlinesState)
    local self = SetTramlinesOnEvent:emptyNew()
    self.vehicle = vehicle;
	self.tramlinesState = tramlinesState;
    return self;
end;

function SetTramlinesOnEvent:readStream(streamId, connection)
    local id = streamReadInt32(streamId);
	self.tramlinesState = streamReadBool(streamId);
    self.vehicle = networkGetObject(id);
    self:run(connection);
end;

function SetTramlinesOnEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));
	streamWriteBool(streamId, self.tramlinesState);
end;

function SetTramlinesOnEvent:run(connection)   
	self.vehicle:setTramlinesOn(self.tramlinesState, true);
    if not connection:getIsServer() then
        g_server:broadcastEvent(SetTramlinesOnEvent:new(self.vehicle, self.tramlinesState), nil, connection, self.vehicle);
    end;
end;

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