--
-- KuhnGA8121
--
-- @author  	Manuel Leithner (SFM-Modding)
-- @date  		11/10/10
-- edit hanslanzmanns: changed InputBindings, g_i18n:getTexts and added two rowerFoldingParts. Thanks for the flexible script @ Face

KuhnGA8121 = {};

function KuhnGA8121.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Windrower, specializations);
end;                                            

function KuhnGA8121:load(xmlFile)

	self.getIsAreaActive = Utils.overwrittenFunction(self.getIsAreaActive, KuhnGA8121.getIsAreaActive);	
	self.setIsArmDown = SpecializationUtil.callSpecializationsFunction("setIsArmDown");
	self.setTransport = SpecializationUtil.callSpecializationsFunction("setTransport");
	
	self.doJointOrientation = false;
	self.attacherJointCopy = nil;
	self.updateJoint = false;
	
	
	_=[[self.steeringAnimations = {};
	self.steeringAnimations.axes = {};
	local i = 0;
    while true do
        local partName = string.format("vehicle.steeringAnimation.axis(%d)", i);
		local axis = {};
        local index = getXMLString(xmlFile, partName .. "#index");
        if index == nil then
            break;
        end;
		axis.node = Utils.indexToObject(self.components, index);
		axis.wheel = self.wheels[getXMLInt(xmlFile, partName .. "#wheelIndex")];
		if axis.wheel ~= nil then
			table.insert(self.steeringAnimations.axes, axis);
		else
			print("Error: Could not found wheel index!");
		end;		
        i = i+1;
	end;
	self.steeringAnimations.middleController = {};
	self.steeringAnimations.middleController.node = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.steeringAnimation#middleController"));
	self.steeringAnimations.middleController.minTrans = getXMLFloat(xmlFile, "vehicle.steeringAnimation#minTrans");
	self.steeringAnimations.middleController.maxTrans = getXMLFloat(xmlFile, "vehicle.steeringAnimation#maxTrans");]]
	
	
	self.rowerFoldingParts = {};
	local i = 0;
    while true do
        local partName = string.format("vehicle.rowerFoldingParts.part(%d)", i);
		local part = {};
        local joint = getXMLInt(xmlFile, partName .. ".mainPart#joint");
        if joint == nil then
            break;
        end;
		local mainPart = {};
		mainPart.joint = self.componentJoints[joint];
		mainPart.minRot = {};
		local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, partName .. ".mainPart#minRot"));
        mainPart.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        mainPart.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        mainPart.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
		
		mainPart.maxRot = {};
		x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, partName .. ".mainPart#maxRot"));
        mainPart.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        mainPart.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        mainPart.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
		mainPart.depHydr = {Utils.getVectorFromString(getXMLString(xmlFile, partName .. ".mainPart#dependingHydraulic"))};		
		mainPart.maxLimit = {};
		x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, partName .. ".mainPart#maxLimit"));
        mainPart.maxLimit[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        mainPart.maxLimit[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        mainPart.maxLimit[3] = Utils.degToRad(Utils.getNoNil(z, 0));
		mainPart.currentLimit = {0, 0, 0};
		mainPart.isDown = false;
		mainPart.transNode = Utils.indexToObject(self.components, getXMLString(xmlFile, partName .. ".mainPart#transNode"));
		mainPart.minTrans = {getXMLFloat(xmlFile, partName .. ".mainPart#minTrans")};
		mainPart.maxTrans = {getXMLFloat(xmlFile, partName .. ".mainPart#maxTrans")};
		mainPart.widthRotNode = Utils.indexToObject(self.components, getXMLString(xmlFile, partName .. ".mainPart#widthRotNode"));
		mainPart.widthMinRot = {Utils.degToRad(Utils.getNoNil(getXMLFloat(xmlFile, partName .. ".mainPart#widthMinRot"), 0))};
		mainPart.widthMaxRot = {Utils.degToRad(Utils.getNoNil(getXMLFloat(xmlFile, partName .. ".mainPart#widthMaxRot"), 0))};
		local bar = {};
		bar.node = Utils.indexToObject(self.components, getXMLString(xmlFile, partName .. ".bar#node"));
		bar.minRot = {};
		x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, partName .. ".bar#minRot"));
        bar.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        bar.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        bar.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
		bar.maxRot = {};
		x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, partName .. ".bar#maxRot"));
        bar.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        bar.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        bar.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
		
		local rower = {};
		rower.joint = self.componentJoints[getXMLInt(xmlFile, partName .. ".rower#joint")];
		rower.maxLimit = {};
		x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, partName .. ".rower#maxLimit"));
        rower.maxLimit[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        rower.maxLimit[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        rower.maxLimit[3] = Utils.degToRad(Utils.getNoNil(z, 0));
		rower.cuttingArea = self.cuttingAreas[getXMLInt(xmlFile, partName .. ".rower#cuttingArea")];
		rower.currentLimit = {0, 0, 0};
		
		part.rower = rower;
		part.bar = bar;
		part.mainPart = mainPart;
		part.moveTime = Utils.getNoNil(getXMLFloat(xmlFile, partName .. "#moveTime"),5)*1000;
		part.workingTime = Utils.getNoNil(getXMLFloat(xmlFile, partName .. "#workingTime"),2)*1000;
		part.isDown = false;
		table.insert(self.rowerFoldingParts, part);		
        i = i+1;
	end;


	self.animationSpeed = 0;
	self.animation.offsetTime = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.animation#offsetTime"), 3) * 1000;
	
    local windrowerStartSound = getXMLString(xmlFile, "vehicle.windrowerStartSound#file");
    if windrowerStartSound ~= nil and windrowerStartSound ~= "" then
        windrowerStartSound = Utils.getFilename(windrowerStartSound, self.baseDirectory);
        self.windrowerStartSound = createSample("windrowerStartSound");
        loadSample(self.windrowerStartSound, windrowerStartSound, false);
        self.windrowerStartSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.windrowerStartSound#pitchOffset"), 1);
        self.windrowerStartSoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.windrowerStartSound#volume"), 1.0);
    end;
	
    local windrowerStopSound = getXMLString(xmlFile, "vehicle.windrowerStopSound#file");
    if windrowerStopSound ~= nil and windrowerStopSound ~= "" then
        windrowerStopSound = Utils.getFilename(windrowerStopSound, self.baseDirectory);
        self.windrowerStopSound = createSample("windrowerStopSound");
        loadSample(self.windrowerStopSound, windrowerStopSound, false);
        self.windrowerStopSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehiclewindrowerStopSound#pitchOffset"), 1);
        self.windrowerStopSoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.windrowerSound#volume"), 1.0);
    end;
	
	local clientSoundFile = getXMLString(xmlFile, "vehicle.windrowerAISound#file");	
	if clientSoundFile ~= nil then
		clientSoundFile = Utils.getFilename(clientSoundFile, self.baseDirectory);
		self.windowerAISoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.windrowerAISound#volume"), 1.0);
        self.windowerAISoundRadius = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.windrowerAISound#radius"), 50);
        self.windowerAISoundInnerRadius = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.windrowerAISound#innerRadius"), 10);
        self.windrowerAISound = createAudioSource("windrowerAISound", clientSoundFile, self.windowerAISoundRadius, self.windowerAISoundInnerRadius, self.windowerAISoundVolume, 0);
        link(self.components[1].node, self.windrowerAISound);
        setVisibility(self.windrowerAISound, false);
	end;
	

	local i=0;
	local invisible = 0;
	self.tines = {};
	self.transportTime = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.tines#transportTime"), 3) * 1000;
	while true do
		local tineName = string.format("vehicle.tines.tine(%d)", i);
		
		local nodeString = getXMLString(xmlFile, tineName .. "#index");
		if nodeString ==  nil then
			break;
		end;	
		local tine = {};		
		tine.node = Utils.indexToObject(self.components, nodeString);	
		tine.marker = Utils.getNoNil(getXMLInt(xmlFile, tineName .. "#marker"), 1);
		if getXMLBool(xmlFile, tineName .. "#isVisible") ~= nil then
			invisible = invisible + 1;
		end;
		
		table.insert(self.tines, tine);
		i = i + 1;
	end;
	
	self.invisibleTineCount = invisible;
	self.timePerTine = self.transportTime / (table.getn(self.tines)-self.invisibleTineCount);
	self.timeToNextTine = self.timePerTine;
	self.tinePositions = {};
	i=0;
	while true do
		local positionName =  string.format("vehicle.tines.transportPositions.position(%d)", i);
		local position = getXMLString(xmlFile, positionName .. "#node");
		if position == nil then
			break;
		end;
		position = Utils.indexToObject(self.components, position);
		table.insert(self.tinePositions, position);
		i = i + 1;
	end;
	self.markers = {};
	i=0;
	while true do
		local markerName =  string.format("vehicle.tines.markers.marker(%d)", i);
		local markerNode = getXMLString(xmlFile, markerName .. "#node");
		if markerNode == nil then
			break;
		end;
		marker = {};
		marker.node = Utils.indexToObject(self.components, markerNode);
		local width, _, _ = getTranslation(marker.node);
		marker.width = width;
		marker.scale = Utils.getNoNil(getXMLInt(xmlFile, markerName .. "#scale"), 1);
		table.insert(self.markers, marker);
		i = i + 1;
	end;

	self.doTransportCheck = false;
	self.doChangesForTransport = false;
	self.isTransport = true;
	self.attacherVehicleJoint = nil;
	self.isReadyToTransport = true;
	self.soundOffset = 0;
	self.isLoading = true;
	
	--self.updateSteeringAxleAngle = false;
end;

function KuhnGA8121:delete()
	if self.windrowerStartSound ~= nil then
        delete(self.windrowerStartSound);
		self.windrowerStartSound = nil;
    end;
	if self.windrowerStopSound ~= nil then
        delete(self.windrowerStopSound);
		self.windrowerStopSound = nil;
    end;
end;

function KuhnGA8121:readStream(streamId, connection)
	self.isLoading = true;
	local isTransport = streamReadBool(streamId);
	self:setTransport(isTransport, true);
	for k, foldingPart in pairs(self.rowerFoldingParts) do
		local isDown = streamReadBool(streamId);
		self:setIsArmDown(isDown, k, true);
	end;
	
end;

function KuhnGA8121:writeStream(streamId, connection)
	streamWriteBool(streamId, self.isTransport);
	for k, foldingPart in pairs(self.rowerFoldingParts) do	
		streamWriteBool(streamId, foldingPart.mainPart.isDown);
	end;
	
end;

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

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

end;

function KuhnGA8121:update(dt)

		
    if self:getIsActiveForInput() then
        if self.isReadyToTransport then
			if InputBinding.hasEvent(InputBinding.CLAASLINER4000_TRANSPORT) then
				local isTransport = false;
				for k, part in pairs(self.rowerFoldingParts) do
					isTransport = part.isDown;
					break;
				end;	
				self:setTransport(isTransport);
			end;
		end;
		if not self.isTransport then
			if InputBinding.hasEvent(InputBinding.CLAASLINER4000_LOWER_LEFT_BACK) then
				local foldingArm = self.rowerFoldingParts[2].mainPart;
				self:setIsArmDown(2, not foldingArm.isDown);
			end;
			if InputBinding.hasEvent(InputBinding.CLAASLINER4000_LOWER_RIGHT_BACK) then
				local foldingArm = self.rowerFoldingParts[1].mainPart;
				self:setIsArmDown(1, not foldingArm.isDown);
			end;
			
			if InputBinding.hasEvent(InputBinding.CLAASLINER4000_LOWER_LEFT_FRONT) then
				local foldingArm = self.rowerFoldingParts[4].mainPart;
				self:setIsArmDown(4, not foldingArm.isDown);
			end;
			if InputBinding.hasEvent(InputBinding.CLAASLINER4000_LOWER_RIGHT_FRONT) then
				local foldingArm = self.rowerFoldingParts[3].mainPart;
				self:setIsArmDown(3, not foldingArm.isDown);
			end;
			
			if InputBinding.hasEvent(InputBinding.CLAASLINER4000_LOWER_ALL) then
				local isDown = self.rowerFoldingParts[1].mainPart.isDown or self.rowerFoldingParts[2].mainPart.isDown or self.rowerFoldingParts[3].mainPart.isDown or self.rowerFoldingParts[4].mainPart.isDown;
				for k, part in pairs(self.rowerFoldingParts) do             
					self:setIsArmDown(k, not isDown);
				end;	
			end;
		end;
	end;
end;

function KuhnGA8121:updateTick(dt)

	if self.doJointOrientation and self.attacherVehicle ~= nil then
		for k,v in pairs(self.attacherVehicle.attachedImplements) do
			if v.object == self then
				local joint = self.attacherVehicle.attacherJoints[v.jointDescIndex];
				self.attacherJointCopy = {};
				self.attacherJointCopy.joint = joint;	
				self.attacherJointCopy.minRotCopy = joint.minRot;
				self.attacherJointCopy.maxRotCopy = joint.maxRot;
				joint.minRot = joint.maxRot;
			end;
		end;
		self.doJointOrientation = false;
	end;

	if self:getIsActive() then
		self.isReadyToTransport = true;
		for _, part in pairs(self.rowerFoldingParts) do
			self.isReadyToTransport = self.isReadyToTransport and not part.mainPart.isDown;
		end;
		
		if self.doChangesForTransport then
			self.timeToNextTine = self.timeToNextTine - dt;
			
			if self.timeToNextTine < 0 then	
				
				self.timeToNextTine = self.timePerTine;
				if self.isTransport then
					local isCheckComplete = true;
					local tineCount = table.getn(self.tines);
					local positionCount = table.getn(self.tinePositions);
					for k, tine in pairs(self.tines) do						
						-- calculate distance to max height
						local x,y,z = getWorldTranslation(tine.node);
						local marker = self.markers[tine.marker];
						width,_,_ = worldToLocal(getParent(marker.node), x,y,z);
						local isVisible = getVisibility(tine.node);						
						if (marker.width * marker.scale) > (width * marker.scale)  and isVisible then
							if self.invisibleTineCount <= positionCount then
								if (k > tineCount/2) or (k <= tineCount/2 and self.invisibleTineCount < positionCount/2) then
									setVisibility(tine.node, false);
									self.invisibleTineCount = self.invisibleTineCount + 1;
									setVisibility(self.tinePositions[self.invisibleTineCount], true);
									isCheckComplete = false;
									break;
								end;
							end;
						end;						
					end;
					
					if isCheckComplete then
						self.doChangesForTransport = false;
					end;
				else
					local isCheckComplete = true;
					for k, tine in pairs(self.tines) do							
						local isVisible = getVisibility(tine.node);		
						if not isVisible then								
							setVisibility(tine.node, true);	
							setVisibility(self.tinePositions[self.invisibleTineCount], false);
							self.invisibleTineCount = self.invisibleTineCount - 1;
							isCheckComplete = false;
							break;
						end;						
					end;	
					if isCheckComplete then
						self.doChangesForTransport = false;
					end;
				end;
			end;
		end;	

		if self.doTransportCheck then
			-- check if rower animation stopped
			if self.animationSpeed < 0.01 then
				self.doChangesForTransport = true;
				self.doTransportCheck = false;
			end;			
		end;		

		if self.isTurnedOn then	
            if not self.animationEnabled then
                enableAnimTrack(self.animation.animCharSet, 0);
                self.animationEnabled = true;
			else
				if self.animationSpeed < (self.animation.speedScale - 0.01) then
					local newSpeed = Utils.getMovedLimitedValues({self.animationSpeed}, {self.animation.speedScale}, {0}, 1, self.animation.offsetTime, dt, false);
					self.animationSpeed = newSpeed[1];
					setAnimTrackSpeedScale(self.animation.animCharSet, 0, self.animationSpeed);
				end;
            end;		
			if self:getIsActiveForSound() then		
				if self.time > self.soundOffset then
					if not self.windrowerSoundEnabled then
						playSample(self.windrowerSound, 0, self.windrowerSoundVolume, 0);
						self.windrowerSoundEnabled = true;
					end;
				else
					stopSample(self.windrowerSound);
					self.windrowerSoundEnabled = false;
				end;
			end;			
        else
			if self.animationEnabled then
				if self.animationSpeed < 0.01 then
					disableAnimTrack(self.animation.animCharSet, 0);
					self.animationEnabled = false;
				else
					enableAnimTrack(self.animation.animCharSet, 0);
					local newSpeed = Utils.getMovedLimitedValues({self.animationSpeed}, {self.animation.speedScale}, {0}, 1, self.animation.offsetTime, dt, true);
					self.animationSpeed = newSpeed[1];
					setAnimTrackSpeedScale(self.animation.animCharSet, 0, self.animationSpeed);
				end;
			end;
        end;
		
		if self.attacherVehicle ~= nil then	
			_=[[local x,y,z = worldDirectionToLocal(self.steeringAxleNode, localDirectionToWorld(self.attacherVehicle.steeringAxleNode, 0, 0, 1));
			local dot = z; -- 0*x + z*1;
			dot = dot / Utils.vector2Length(x,z);
			local angle = math.acos(dot);
			if x < 0 then
				angle = -angle;
			end;
			local startSpeed = self.steeringAxleAngleScaleStart;
			local endSpeed = self.steeringAxleAngleScaleEnd;
			local scale = Utils.clamp(1 + (self.lastSpeed*3600-startSpeed) * 1.0/(startSpeed-endSpeed), 0, 1);
			self.steeringAxleAngle = angle*scale;

			for _, axis in pairs(self.steeringAnimations.axes) do
				setRotation(axis.node, getRotation(axis.wheel.repr));
			end;
			
			local x,y,z = getRotation(self.wheels[1].repr);
			local maxAngle = self.wheels[1].steeringAxleRotMax;
			local minAngle = self.wheels[1].steeringAxleRotMin;
			local percentage = (y - minAngle) / (maxAngle + math.abs(minAngle));
			local a,b,c = getTranslation(self.steeringAnimations.middleController.node);
			c = self.steeringAnimations.middleController.minTrans + percentage * (self.steeringAnimations.middleController.maxTrans - self.steeringAnimations.middleController.minTrans);
			setTranslation(self.steeringAnimations.middleController.node, a, b, c);]]
		
			local jointDesc = self.attacherJointCopy.joint;
			setJointRotationLimit(jointDesc.jointIndex, 2, true, math.rad(-50), math.rad(50));
			jointDesc.moveDown = false;
			
			for _, foldingPart in pairs(self.rowerFoldingParts) do
				local mainPart = foldingPart.mainPart;
				local x, y, z = getRotation(mainPart.joint.jointNode);
				local rot = {x,y,z};
				local newRot = Utils.getMovedLimitedValues(rot, mainPart.maxRot, mainPart.minRot, 3, foldingPart.moveTime, dt, not foldingPart.isDown);
				setRotation(mainPart.joint.jointNode, unpack(newRot));
				setJointFrame(mainPart.joint.jointIndex, 0, mainPart.joint.jointNode);
				local bar = foldingPart.bar;
				x, y, z = getRotation(bar.node);
				rot = {x,y,z};
				newRot = Utils.getMovedLimitedValues(rot, bar.maxRot, bar.minRot, 3, foldingPart.moveTime, dt, not foldingPart.isDown);
				setRotation(bar.node, unpack(newRot));
				
				x, y, z = getTranslation(mainPart.transNode);
				x = Utils.getMovedLimitedValues({x}, mainPart.maxTrans, mainPart.minTrans, 1, foldingPart.moveTime, dt, not foldingPart.isDown);
				setTranslation(mainPart.transNode, x[1],y,z);
				x, y, z = getRotation(mainPart.widthRotNode);
				x = Utils.getMovedLimitedValues({x}, mainPart.widthMaxRot, mainPart.widthMinRot, 1, foldingPart.moveTime, dt, not foldingPart.isDown);
				setRotation(mainPart.widthRotNode, x[1],y,z);
				
				local rower = foldingPart.rower;
				setJointFrame(rower.joint.jointIndex, 0, rower.joint.jointNode);

				local newArmLimit = Utils.getMovedLimitedValues(mainPart.currentLimit, mainPart.maxLimit, {0,0,0}, 3, foldingPart.workingTime, dt, not mainPart.isDown);
				local newRowerLimit = Utils.getMovedLimitedValues(rower.currentLimit, rower.maxLimit, {0,0,0}, 3, foldingPart.workingTime, dt, not mainPart.isDown);
				for i=1, 3 do
					setJointRotationLimit(mainPart.joint.jointIndex, i-1, true, -newArmLimit[i], newArmLimit[i]);
					setJointRotationLimit(rower.joint.jointIndex, i-1, true, -newRowerLimit[i], newRowerLimit[i]);
				end;
				mainPart.currentLimit = newArmLimit;
				rower.currentLimit = newRowerLimit;

				local isExpanded = true;
                for i=1, 3 do
					isExpanded = isExpanded and newRowerLimit[i] >= rower.maxLimit[i] * 0.5;
                end;	
				
				for _, part in pairs(self.movingParts) do
					part.isDirty = true;
				end;
			end;
		else
			--self.steeringAxleAngle = 0;
		end;	
	end;
end;


function KuhnGA8121:draw()	
    if self.isTransport then
        g_currentMission:addHelpButtonText(string.format(g_i18n:getText("CLAASLINER4000_TRANSPORT_OFF"), self.typeDesc), InputBinding.CLAASLINER4000_TRANSPORT);
    else
		if self.isReadyToTransport then
			g_currentMission:addHelpButtonText(string.format(g_i18n:getText("CLAASLINER4000_TRANSPORT_ON"), self.typeDesc), InputBinding.CLAASLINER4000_TRANSPORT);
		end;
		g_currentMission:addExtraPrintText(string.format(g_i18n:getText("CLAASLINER4000_CONTROL"), self.typeDesc) .. " " .. (g_i18n:getText("CLAASLINER4000_LEFT_BACK")) .. InputBinding.getKeyNamesOfDigitalAction(InputBinding.CLAASLINER4000_LOWER_LEFT_BACK) .. " / " .. (g_i18n:getText("CLAASLINER4000_RIGHT_BACK")) .. InputBinding.getKeyNamesOfDigitalAction(InputBinding.CLAASLINER4000_LOWER_RIGHT_BACK));
        
		g_currentMission:addExtraPrintText(string.format(g_i18n:getText("CLAASLINER4000_LEFT_FRONT")) .. InputBinding.getKeyNamesOfDigitalAction(InputBinding.CLAASLINER4000_LOWER_LEFT_FRONT) .. "/ " .. (g_i18n:getText("CLAASLINER4000_RIGHT_FRONT")) .. InputBinding.getKeyNamesOfDigitalAction(InputBinding.CLAASLINER4000_LOWER_RIGHT_FRONT) .. "/ " .. (g_i18n:getText("CLAASLINER4000_ALL")) .. InputBinding.getKeyNamesOfDigitalAction(InputBinding.CLAASLINER4000_LOWER_ALL));
		
	end;
	
end;

function KuhnGA8121:onAttach(attacherVehicle)
	self.doJointOrientation = true;	
	setJointRotationLimit(self.componentJoints[1].jointIndex, 1, true, math.rad(-90), math.rad(90));
	setJointRotationLimit(self.componentJoints[1].jointIndex, 2, true, math.rad(-2), math.rad(2));
end;

function KuhnGA8121:onDetach()
	if self.windrowerStartSound ~= nil then
		stopSample(self.windrowerStartSound);
	end;
	if self.windrowerStopSound ~= nil then
		stopSample(self.windrowerStopSound);
	end;
	if self.windrowerAISound ~= nil then
		setVisibility(self.windrowerAISound, false);
	end;
	if self.attacherJointCopy ~= nil then
		local jointDesc = self.attacherJointCopy.joint;
		jointDesc.maxRot = self.attacherJointCopy.maxRotCopy;
		jointDesc.minRot = self.attacherJointCopy.minRotCopy;
	end;
	setJointRotationLimit(self.componentJoints[1].jointIndex, 1, true, math.rad(-20), math.rad(20));
	setJointRotationLimit(self.componentJoints[1].jointIndex, 2, true, math.rad(0), math.rad(0));
end;

function KuhnGA8121:onLeave()
	-- disable sounds if player left vehicle
	if self.windrowerStartSound ~= nil then
		stopSample(self.windrowerStartSound);
	end;
	if self.windrowerStopSound ~= nil then
		stopSample(self.windrowerStopSound);
	end;
	if self.windrowerAISound ~= nil then
		setVisibility(self.windrowerAISound, false);
	end;
end;

function KuhnGA8121:setTransport(isTransport, noEventSend)
    SetTransportEvent.sendEvent(self, isTransport, noEventSend);
	for _, foldingPart in pairs(self.rowerFoldingParts) do			
		foldingPart.isDown = not isTransport;
	end;
	self.isTransport = isTransport;
	
	if not isTransport then
		self.doChangesForTransport = true;
	else
		-- wait for rower animation stop before checking tines
		self.doTransportCheck = true;	
		if self.isTurnedOn then
			self:setIsTurnedOn(false);-- self:setIsTurnedOn(false, true);
		end;						
	end;	

end;

function KuhnGA8121:setIsArmDown(arm, isDown, noEventSend)
	local foldingArm = self.rowerFoldingParts[arm];
	if foldingArm ~= nil then
		SetIsArmDownEvent.sendEvent(self, arm, isDown, noEventSend);
		foldingArm.mainPart.isDown = isDown;
	end;
end;

function KuhnGA8121:setIsTurnedOn(isTurnedOn, noEventSend)
	
	local soundOffset = 0;
	if not isTurnedOn then
		if self.windrowerAISound ~= nil then
			setVisibility(self.windrowerAISound, false);
		end;
		self.animationEnabled = true;
		if self:getIsActive() then
			if self:getIsActiveForSound() then	
				if self.time < self.soundOffset then
					stopSample(self.windrowerStartSound);
				else
					if self.windrowerStopSound ~= nil then
						playSample(self.windrowerStopSound, 1, self.windrowerStopSoundVolume, 0);
						soundOffset = getSampleDuration(self.windrowerStopSound);
					end;
				end;
			end;
		end;
	else
		if self:getIsActive() then
			if self:getIsActiveForSound() then					
				self.windrowerSoundEnabled = false;
				stopSample(self.windrowerSound);
				
				if self.time < self.soundOffset then
					stopSample(self.windrowerStopSound);
				end;
				playSample(self.windrowerStartSound, 1, self.windrowerStartSoundVolume, 0);
				soundOffset = getSampleDuration(self.windrowerStartSound);		
			elseif self.attacherVehicle.isControlled then
				if self.windrowerAISound ~= nil then
					setVisibility(self.windrowerAISound, true);
				end;
			end;
		end;
	end;
	self.soundOffset = self.time + soundOffset;
end;


function KuhnGA8121:getIsAreaActive(superFunc, area)
	local isActive = false;
	local rowerByArea = nil;
	for _, foldingPart in pairs(self.rowerFoldingParts) do
		if foldingPart.rower.cuttingArea == area then
			rowerByArea = foldingPart;
			break;
		end;
	end;
	if rowerByArea ~= nil then
		isActive = true;
		for i=1, 3 do
			isActive = isActive and rowerByArea.rower.currentLimit[i] >= rowerByArea.rower.maxLimit[i] * 0.5;  --0.5
		end;	
	end;
    if superFunc ~= nil then
        return superFunc(self, area) and isActive;
    end;
	return isActive;	
end;