

KPS4 = {};

function KPS4.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Attachable, specializations); 
end;

function KPS4:load(xmlFile)
	self.aiTerrainDetailChannel1 = g_currentMission.sowingChannel; 
	self.aiTerrainDetailChannel2 = g_currentMission.ploughChannel; 		

    numparts = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.parts#count"), 0);
	self.parts = {};
    for i=1, numparts do
        local partnamei = string.format("vehicle.parts.part%d", i);
        self.parts[i] = Utils.indexToObject(self.components, getXMLString(xmlFile, partnamei .. "#index"));
        setVisibility(self.parts[i], false);
    end;
	self.partsActive = false;
	
	local RamaLapXNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.RamaLap#index"));
    if RamaLapXNode ~= nil then
        self.RamaLap = {};
        self.RamaLap.node = RamaLapXNode;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.RamaLap#minRot"));
        self.RamaLap.minRot = {};
        self.RamaLap.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.RamaLap.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.RamaLap.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

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

        self.RamaLap.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.RamaLap#rotTime"), 2)*1000;
        self.RamaLap.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.RamaLap#touchRotLimit"), 10));
    end;	
	local PlankaXNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.Planka#index"));
    if PlankaXNode ~= nil then
        self.Planka = {};
        self.Planka.node = PlankaXNode;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.Planka#minRot"));
        self.Planka.minRot = {};
        self.Planka.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.Planka.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.Planka.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

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

        self.Planka.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.Planka#rotTime"), 2)*1000;
        self.Planka.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.Planka#touchRotLimit"), 10));
    end;
	local BoronaXNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.Borona#index"));
    if BoronaXNode ~= nil then
        self.Borona = {};
        self.Borona.node = BoronaXNode;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.Borona#minRot"));
        self.Borona.minRot = {};
        self.Borona.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.Borona.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.Borona.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

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

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

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

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

        self.Planka2.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.Planka2#rotTime"), 2)*1000;
        self.Planka2.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.Planka2#touchRotLimit"), 10));
    end;
	
	local Borona2XNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.Borona2#index"));
    if Borona2XNode ~= nil then
        self.Borona2 = {};
        self.Borona2.node = Borona2XNode;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.Borona2#minRot"));
        self.Borona2.minRot = {};
        self.Borona2.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.Borona2.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.Borona2.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

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

        self.Borona2.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.Borona2#rotTime"), 2)*1000;
        self.Borona2.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.Borona2#touchRotLimit"), 10));
    end;
	
	local Planka3XNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.Planka3#index"));
    if Planka3XNode ~= nil then
        self.Planka3 = {};
        self.Planka3.node = Planka3XNode;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.Planka3#minRot"));
        self.Planka3.minRot = {};
        self.Planka3.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.Planka3.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.Planka3.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

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

        self.Planka3.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.Planka3#rotTime"), 2)*1000;
        self.Planka3.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.Planka3#touchRotLimit"), 10));
    end;
	local Borona3XNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.Borona3#index"));
    if Borona3XNode ~= nil then
        self.Borona3 = {};
        self.Borona3.node = Borona3XNode;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.Borona3#minRot"));
        self.Borona3.minRot = {};
        self.Borona3.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.Borona3.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.Borona3.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

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

        self.Borona3.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.Borona3#rotTime"), 2)*1000;
        self.Borona3.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.Borona3#touchRotLimit"), 10));
    end;	
	local Planka4XNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.Planka4#index"));
    if Planka4XNode ~= nil then
        self.Planka4 = {};
        self.Planka4.node = Planka4XNode;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.Planka4#minRot"));
        self.Planka4.minRot = {};
        self.Planka4.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.Planka4.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.Planka4.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

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

        self.Planka4.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.Planka4#rotTime"), 2)*1000;
        self.Planka4.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.Planka4#touchRotLimit"), 10));
    end;
	local Borona4XNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.Borona4#index"));
    if Borona4XNode ~= nil then
        self.Borona4 = {};
        self.Borona4.node = Borona4XNode;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.Borona4#minRot"));
        self.Borona4.minRot = {};
        self.Borona4.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.Borona4.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.Borona4.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

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

        self.Borona4.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.Borona4#rotTime"), 2)*1000;
        self.Borona4.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.Borona4#touchRotLimit"), 10));
    end;
	
    self.groundParticleSystems = {};
    Utils.loadParticleSystem(xmlFile, self.groundParticleSystems, "vehicle.MiddleParticleSystem", self.components[1].node, false, nil, self.baseDirectory)
    Utils.loadParticleSystem(xmlFile, self.groundParticleSystems, "vehicle.Middle1ParticleSystem", self.components[1].node, false, nil, self.baseDirectory)	
    self.groundParticleSystemActive = false;
	
	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"));	
		if self.hydraulics[i].punch ~= nil then
			local ax, ay, az = getWorldTranslation(self.hydraulics[i].punch);
			local bx, by, bz = getWorldTranslation(self.hydraulics[i].translationPunch);
			self.hydraulics[i].punchDistance = Utils.vector3Length(ax-bx, ay-by, az-bz);
		end;
		self.hydraulics[i].doScale = Utils.getNoNil(getXMLBool(xmlFile, hydraulicName .. "#doScale"), false);
	end;
	
	local cultivatorSound = getXMLString(xmlFile, "vehicle.cultivatorSound#file");
    if cultivatorSound ~= nil and cultivatorSound ~= "" then
        cultivatorSound = Utils.getFilename(cultivatorSound, self.baseDirectory);
        self.cultivatorSound = createSample("cultivatorSound");
        loadSample(self.cultivatorSound, cultivatorSound, false);
        self.cultivatorSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.cultivatorSound#pitchOffset"), 0);
        self.cultivatorSoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.cultivatorSound#volume"), 1.5);
        self.cultivatorSoundEnabled = false;
    end;
	
	self.charIdAnim = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.animWorkingDiscs#Node"));
	self.clipIndexAnim = getXMLString(xmlFile, "vehicle.animWorkingDiscs#animationClip");	
	
	self.AIon=false;	
	self.isDown = false;
	self.safeMode = true;	
	self.Frame = true;
	self.Rama = true;	

end;

function KPS4:delete()
    if self.cultivatorSound ~= nil then
        delete(self.cultivatorSound);
    end;
    Utils.deleteParticleSystem(self.groundParticleSystems);	
end;

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

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

function KPS4:update(dt)
    if self.attacherVehicle then	

		if self.isActive then
		
		  if self.partsActive then
				for i=1, numparts do
					setVisibility(self.parts[i], self.partsActive);
				end;
					else
				for i=1, numparts do
					setVisibility(self.parts[i], self.partsActive, false);
				end;
			end;		
		---ai---
		if self.attacherVehicle.isAITractorActivated ~= nil then
			self.AIon = self.attacherVehicle.isAITractorActivated;
			
		end; 
		
	if self.attacherVehicle.isAITractorActivated and not self.Frame then				
    	self.attacherVehicle.turnStage3Timeout = 0;
		
			if self.attacherVehicle.turnStage == 0 then
			self.Rama=false;
			else
			self.Rama=true;

			end;
	else
		
		if self.attacherVehicle.isAITractorActivated ~= nil then
			self.attacherVehicle.turnStage3Timeout = 35000;
		end; 	
	end;

---------ai end----	
			
			if InputBinding.hasEvent(InputBinding.SAFE_MODE) then
				self.safeMode = not self.safeMode;
			end;		

			if InputBinding.hasEvent(InputBinding.LOWER_IMPLEMENT) and not self.Frame then
				self.Rama = not self.Rama;				
			end;
			if InputBinding.hasEvent(InputBinding.TRANSPORT_OK) then
				self.Frame = not self.Frame;
				self.partsActive = not self.partsActive;				
			end;			
			local doRotate = self.RamaLapMax or self.RamaLapMin
			if self.RamaLap ~= nil and doRotate then
				local x, y, z = getRotation(self.RamaLap.node);
				local rot = {x,y,z};
				local newRot = Utils.getMovedLimitedValues(rot, self.RamaLap.maxRot, self.RamaLap.minRot, 3, self.RamaLap.rotTime, dt, not self.RamaLapMax);
				setRotation(self.RamaLap.node,unpack(newRot));
			end;		

			local x, y, z = getRotation(self.RamaLap.node);
			local maxRot = self.RamaLap.maxRot;
			local eps = self.RamaLap.touchRotLimit;
			if  (math.abs (x) > eps) then
				self.isDown = false;
				setJointRotationLimit(self.componentJoints[2].jointIndex, 0, true, math.rad(-1.1), math.rad(1.1));	
				setJointRotationLimit(self.componentJoints[4].jointIndex, 0, true, math.rad(-1), math.rad(1));	
				setJointRotationLimit(self.componentJoints[6].jointIndex, 0, true, math.rad(-1.1), math.rad(1.1));
				setJointRotationLimit(self.componentJoints[8].jointIndex, 0, true, math.rad(-1.2), math.rad(1.2));				
			else
				self.isDown = true;
				setJointRotationLimit(self.componentJoints[2].jointIndex, 0, true, math.rad(-15), math.rad(10));
				setJointRotationLimit(self.componentJoints[4].jointIndex, 0, true, math.rad(-15), math.rad(10));
				setJointRotationLimit(self.componentJoints[6].jointIndex, 0, true, math.rad(-15), math.rad(10));
				setJointRotationLimit(self.componentJoints[8].jointIndex, 0, true, math.rad(-15), math.rad(10));				
			end;			
			if  self.Rama then
				self.RamaLapMax = true;
				self.RamaLapMin = false;				
				else
				self.RamaLapMax = false;
				self.RamaLapMin = true;				
			end;
			
			if  self.Frame then
				self.PlankaMax = true;
				self.PlankaMin = false;
				self.BoronaMax = true;
				self.BoronaMin = false;				
				setJointRotationLimit(self.componentJoints[1].jointIndex, 0, true, math.rad(-1), math.rad(3));	
				setJointRotationLimit(self.componentJoints[1].jointIndex, 2, true, math.rad(-0.8), math.rad(0.8));	
				self.Planka2Max = true;
				self.Planka2Min = false;
				self.Borona2Max = true;
				self.Borona2Min = false;				
				setJointRotationLimit(self.componentJoints[3].jointIndex, 0, true, math.rad(-1), math.rad(2));	
				setJointRotationLimit(self.componentJoints[3].jointIndex, 2, true, math.rad(-1), math.rad(1));	
				self.Planka3Max = true;
				self.Planka3Min = false;
				self.Borona3Max = true;
				self.Borona3Min = false;				
				setJointRotationLimit(self.componentJoints[5].jointIndex, 0, true, math.rad(-1), math.rad(2.5));	
				setJointRotationLimit(self.componentJoints[5].jointIndex, 2, true, math.rad(-0.6), math.rad(0.6));
				self.Planka4Max = true;
				self.Planka4Min = false;
				self.Borona4Max = true;
				self.Borona4Min = false;				
				setJointRotationLimit(self.componentJoints[7].jointIndex, 0, true, math.rad(-1), math.rad(1.5));	
				setJointRotationLimit(self.componentJoints[7].jointIndex, 2, true, math.rad(-1), math.rad(1));				
				else
				self.PlankaMax = false;
				self.PlankaMin = true;
				self.BoronaMax = false;
				self.BoronaMin = true;				
				setJointRotationLimit(self.componentJoints[1].jointIndex, 0, true, math.rad(-0), math.rad(25));	
				setJointRotationLimit(self.componentJoints[1].jointIndex, 2, true, math.rad(-1), math.rad(0.5));	
				self.Planka2Max = false;
				self.Planka2Min = true;
				self.Borona2Max = false;
				self.Borona2Min = true;				
				setJointRotationLimit(self.componentJoints[3].jointIndex, 0, true, math.rad(-0), math.rad(25));	
				setJointRotationLimit(self.componentJoints[3].jointIndex, 2, true, math.rad(-0.5), math.rad(0.9));
				self.Planka3Max = false;
				self.Planka3Min = true;
				self.Borona3Max = false;
				self.Borona3Min = true;				
				setJointRotationLimit(self.componentJoints[5].jointIndex, 0, true, math.rad(-0), math.rad(25));	
				setJointRotationLimit(self.componentJoints[5].jointIndex, 2, true, math.rad(-0.8), math.rad(0.8));
				self.Planka4Max = false;
				self.Planka4Min = true;
				self.Borona4Max = false;
				self.Borona4Min = true;				
				setJointRotationLimit(self.componentJoints[7].jointIndex, 0, true, math.rad(-0), math.rad(25));	
				setJointRotationLimit(self.componentJoints[7].jointIndex, 2, true, math.rad(-1), math.rad(1));				
			end;
			
			setJointFrame(self.componentJoints[1].jointIndex, 1,self.componentJoints[1].jointNode);	
			setJointFrame(self.componentJoints[2].jointIndex, 1,self.componentJoints[2].jointNode);	
			setJointFrame(self.componentJoints[3].jointIndex, 1,self.componentJoints[3].jointNode);	
			setJointFrame(self.componentJoints[4].jointIndex, 1,self.componentJoints[4].jointNode);	
			setJointFrame(self.componentJoints[5].jointIndex, 1,self.componentJoints[5].jointNode);	
			setJointFrame(self.componentJoints[6].jointIndex, 1,self.componentJoints[6].jointNode);	
			setJointFrame(self.componentJoints[7].jointIndex, 1,self.componentJoints[7].jointNode);	
			setJointFrame(self.componentJoints[8].jointIndex, 1,self.componentJoints[8].jointNode);			
			
			for i=1, table.getn(self.hydraulics) do
				local ax, ay, az = getWorldTranslation(self.hydraulics[i].node);
				local bx, by, bz = getWorldTranslation(self.hydraulics[i].fixPoint);
				local x, y, z = worldDirectionToLocal(getParent(self.hydraulics[i].node), bx-ax, by-ay, bz-az);
			
				setDirection(self.hydraulics[i].node, x, y, z, 0, 1, 0);
				local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
				if self.hydraulics[i].doScale then
					local xScale, yScale, zScale = getScale(self.hydraulics[i].punch);
					local newScale = yScale * (distance / self.hydraulics[i].punchDistance);
					setScale(self.hydraulics[i].punch, 1, 1, newScale);
				else
					if self.hydraulics[i].punch ~= nil then
						setTranslation(self.hydraulics[i].punch, 0, 0, distance-self.hydraulics[i].punchDistance);
					else
						setDirection(self.hydraulics[i].node, x, y, z, 0, 1, 0);
					end;
				end;
			end;
			
			local doRotate = self.PlankaMax or self.PlankaMin
			if self.Planka ~= nil and doRotate then
				local x, y, z = getRotation(self.componentJoints[1].jointNode);
				local rot = {x,y,z};
				local newRot = Utils.getMovedLimitedValues(rot, self.Planka.maxRot, self.Planka.minRot, 3, self.Planka.rotTime, dt, not self.PlankaMax);
				setRotation(self.componentJoints[1].jointNode,unpack(newRot));
			end;
			local doRotate = self.BoronaMax or self.BoronaMin
			if self.Borona ~= nil and doRotate then
				local x, y, z = getRotation(self.componentJoints[2].jointNode);
				local rot = {x,y,z};
				local newRot = Utils.getMovedLimitedValues(rot, self.Borona.maxRot, self.Borona.minRot, 3, self.Borona.rotTime, dt, not self.BoronaMax);
				setRotation(self.componentJoints[2].jointNode,unpack(newRot));
			end;

			local doRotate = self.Planka2Max or self.Planka2Min
			if self.Planka2 ~= nil and doRotate then
				local x, y, z = getRotation(self.componentJoints[3].jointNode);
				local rot = {x,y,z};
				local newRot = Utils.getMovedLimitedValues(rot, self.Planka2.maxRot, self.Planka2.minRot, 3, self.Planka2.rotTime, dt, not self.Planka2Max);
				setRotation(self.componentJoints[3].jointNode,unpack(newRot));
			end;
			local doRotate = self.Borona2Max or self.Borona2Min
			if self.Borona2 ~= nil and doRotate then
				local x, y, z = getRotation(self.componentJoints[4].jointNode);
				local rot = {x,y,z};
				local newRot = Utils.getMovedLimitedValues(rot, self.Borona2.maxRot, self.Borona2.minRot, 3, self.Borona2.rotTime, dt, not self.Borona2Max);
				setRotation(self.componentJoints[4].jointNode,unpack(newRot));
			end;
			
			local doRotate = self.Planka3Max or self.Planka3Min
			if self.Planka3 ~= nil and doRotate then
				local x, y, z = getRotation(self.componentJoints[5].jointNode);
				local rot = {x,y,z};
				local newRot = Utils.getMovedLimitedValues(rot, self.Planka3.maxRot, self.Planka3.minRot, 3, self.Planka3.rotTime, dt, not self.Planka3Max);
				setRotation(self.componentJoints[5].jointNode,unpack(newRot));
			end;
			local doRotate = self.Borona3Max or self.Borona3Min
			if self.Borona3 ~= nil and doRotate then
				local x, y, z = getRotation(self.componentJoints[6].jointNode);
				local rot = {x,y,z};
				local newRot = Utils.getMovedLimitedValues(rot, self.Borona3.maxRot, self.Borona3.minRot, 3, self.Borona3.rotTime, dt, not self.Borona3Max);
				setRotation(self.componentJoints[6].jointNode,unpack(newRot));
			end;
			
			local doRotate = self.Planka4Max or self.Planka4Min
			if self.Planka4 ~= nil and doRotate then
				local x, y, z = getRotation(self.componentJoints[7].jointNode);
				local rot = {x,y,z};
				local newRot = Utils.getMovedLimitedValues(rot, self.Planka4.maxRot, self.Planka4.minRot, 3, self.Planka4.rotTime, dt, not self.Planka4Max);
				setRotation(self.componentJoints[7].jointNode,unpack(newRot));
			end;
			local doRotate = self.Borona4Max or self.Borona4Min
			if self.Borona4 ~= nil and doRotate then
				local x, y, z = getRotation(self.componentJoints[8].jointNode);
				local rot = {x,y,z};
				local newRot = Utils.getMovedLimitedValues(rot, self.Borona4.maxRot, self.Borona4.minRot, 3, self.Borona4.rotTime, dt, not self.Borona4Max);
				setRotation(self.componentJoints[8].jointNode,unpack(newRot));
			end;			
			if self.isDown then
				for k, cuttingArea in pairs(self.cuttingAreas) do
					local x,y,z = getWorldTranslation(cuttingArea.start);
					local x1,y1,z1 = getWorldTranslation(cuttingArea.width);
					local x2,y2,z2 = getWorldTranslation(cuttingArea.height);
					if self.safeMode then
						KPS4.updateSafeArea(x, z, x1, z1, x2, z2);
					else
						Utils.updateCultivatorArea(x, z, x1, z1, x2, z2);
					end;
				end;
				local charId = getAnimCharacterSet(self.charIdAnim);
				local clipIndex = getAnimClipIndex(charId, self.clipIndexAnim);		
					if self.lastSpeed*3600 > 8 then
						assignAnimTrackClip(charId , 0, clipIndex);
						setAnimTrackLoopState(charId, 0, true);
						setAnimTrackSpeedScale(charId, 0, 6);
						enableAnimTrack(charId, 0);
						
			    else
				disableAnimTrack(charId, 0);
			end;		
				if self.cultivatorSound ~= nil and not self.cultivatorSoundEnabled and self:getIsActiveForSound() then
					if self.lastSpeed*3600 > 1 then
						playSample(self.cultivatorSound, 0, self.cultivatorSoundVolume, 0);
						setSamplePitch(self.cultivatorSound, self.cultivatorSoundPitchOffset);
						self.cultivatorSoundEnabled = true;
					end;
				end;
	            if self.lastSpeed*3600 > 5 and not self.groundParticleSystemActive then
					self.groundParticleSystemActive = true;
					Utils.setEmittingState(self.groundParticleSystems, true);
					Utils.setEmittingState(self.CarrierWorkingParticleSystems, true)
				end;
				if self.lastSpeed*3600 < 5 and self.groundParticleSystemActive then
					self.groundParticleSystemActive = false;
					Utils.setEmittingState(self.groundParticleSystems, false);
					Utils.setEmittingState(self.CarrierWorkingParticleSystems, false)
				end;				
			else
				if self.cultivatorSoundEnabled then
					stopSample(self.cultivatorSound);
					self.cultivatorSoundEnabled = false;
				end;
				if self.groundParticleSystemActive then
	                self.groundParticleSystemActive = false;
					Utils.setEmittingState(self.groundParticleSystems, false);
				end;				
			end;
			if self.cultivatorSoundEnabled then
				if self.lastSpeed*3600 < 1 then
					stopSample(self.cultivatorSound);
					self.cultivatorSoundEnabled = false;
				end;
			end;			
					
		end;
	end;	
end;

function KPS4:draw()

	if self.RamaLapMax then
		g_currentMission:addHelpButtonText(g_i18n:getText("LiftCultivator"), InputBinding.LOWER_IMPLEMENT);
	else
		g_currentMission:addHelpButtonText(g_i18n:getText("LowerCultivator"), InputBinding.LOWER_IMPLEMENT);
	end;
	if self.safeMode then
		g_currentMission:addHelpButtonText(g_i18n:getText("SafeModeOff"), InputBinding.SAFE_MODE);
	else
		g_currentMission:addHelpButtonText(g_i18n:getText("SafeModeOn"), InputBinding.SAFE_MODE);
	end;
	if self.Frame then
		g_currentMission:addHelpButtonText(g_i18n:getText("TransportOff"), InputBinding.TRANSPORT_OK);
	else
		g_currentMission:addHelpButtonText(g_i18n:getText("TransportOn"), InputBinding.TRANSPORT_OK);
	end;	
end;

function KPS4:onDetach()

end;

function KPS4:onAttach()
end; 
function KPS4:onLeave()

end;

function KPS4:onActivate()
end;

function KPS4:onDeactivate()

end;

function KPS4:CarrierWorkingTime(diffTime)

end; 
KPS4.updateSafeArea = function(l_18_0, l_18_1, l_18_2, l_18_3, l_18_4, l_18_5)
  local cultiId = g_currentMission.cultivatorChannel
  local sowingId = g_currentMission.sowingChannel
  local detailId = g_currentMission.terrainDetailId
  local ploughId = g_currentMission.ploughChannel
  local sprayId = g_currentMission.sprayChannel
  local x, z, widthX, widthZ, heightX, heightZ = Utils.getXZWidthAndHeight(detailId, l_18_0, l_18_1, l_18_2, l_18_3, l_18_4, l_18_5)
  Utils.updateDestroyCommonArea(l_18_0, l_18_1, l_18_2, l_18_3, l_18_4, l_18_5)
  setDensityMaskedParallelogram(detailId, x, z, widthX, widthZ, heightX, heightZ, cultiId, 1, detailId, sowingId, 1, 1)
  setDensityMaskedParallelogram(detailId, x, z, widthX, widthZ, heightX, heightZ, cultiId, 1, detailId, ploughId, 1, 1)
  setDensityParallelogram(detailId, x, z, widthX, widthZ, heightX, heightZ, sowingId, 1, 0)
  setDensityParallelogram(detailId, x, z, widthX, widthZ, heightX, heightZ, ploughId, 1, 0)
  setDensityParallelogram(detailId, x, z, widthX, widthZ, heightX, heightZ, sprayId, 1, 0)
end;

