--
-- PoettingerSynkro6003T
-- Specialization for PoettingerSynkro6003T
--
-- @author  Manuel Leithner
-- @modificated  Tobias F.(John Deere 6930)
-- @date  09/06/10

PoettingerSynkro6003T = {};

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

function PoettingerSynkro6003T:load(xmlFile)
	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"));	
		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);
		self.hydraulics[i].doScale = Utils.getNoNil(getXMLBool(xmlFile, hydraulicName .. "#doScale"), false);
	end;	
	local hydraulicSound = getXMLString(xmlFile, "vehicle.ctcHydraulicSound#file");
    if hydraulicSound ~= nil and hydraulicSound ~= "" then
		hydraulicSound = Utils.getFilename(hydraulicSound, self.baseDirectory);
        self.hydraulicSound = createSample("hydraulicSound");
        loadSample(self.hydraulicSound, hydraulicSound, false);
        self.hydraulicSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.ctcHydraulicSound#pitchOffset"), 1);
        self.hydraulicSoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.ctcHydraulicSound#pitchMax"), 2.0);
        self.hydraulicSoundEnabled = 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.0);
        self.cultivatorSoundEnabled = false;
    end;

	self.supportFeet = {};
	self.supportFeet.minTrans = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.supportFeet#minTrans"), 0);
	self.supportFeet.maxTrans = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.supportFeet#maxTrans"), 0);
	
	self.axis = {};	
	self.axis.minRot = {Utils.degToRad(getXMLFloat(xmlFile, "vehicle.axis#minRot"))};
	self.axis.maxRot = {Utils.degToRad(getXMLFloat(xmlFile, "vehicle.axis#maxRot"))};
	self.axis.rotTime = getXMLFloat(xmlFile, "vehicle.axis#rotTime")*1000;
	
	self.frame = {};
	self.frame.minRot = {Utils.degToRad(getXMLFloat(xmlFile, "vehicle.frame#minRot"))};
	self.frame.maxRot = {Utils.degToRad(getXMLFloat(xmlFile, "vehicle.frame#maxRot"))};
	self.frame.rotTime = getXMLFloat(xmlFile, "vehicle.frame#rotTime")*1000;
	self.frame.extensionLeft = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.frame#extensionLeft"));
	self.frame.extensionRight = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.frame#extensionRight"));
	self.frame.extensionMinRot = {Utils.degToRad(getXMLFloat(xmlFile, "vehicle.frame#extensionMinRot"))};
	self.frame.extensionMaxRot = {Utils.degToRad(getXMLFloat(xmlFile, "vehicle.frame#extensionMaxRot"))};
	
	self.groundParticleSystems = {};
    Utils.loadParticleSystem(xmlFile, self.groundParticleSystems, "vehicle.leftGroundParticleSystem", self.components[4].node, false, nil, self.baseDirectory);
    Utils.loadParticleSystem(xmlFile, self.groundParticleSystems, "vehicle.rightGroundParticleSystem", self.components[5].node, false, nil, self.baseDirectory);
    self.groundParticleSystemActive = false;	
	
	self.aiTerrainDetailChannel1 = g_currentMission.ploughChannel;
    self.aiTerrainDetailChannel2 = g_currentMission.sowingChannel;

    self.startActivationTimeout = 5000;
    self.startActivationTime = 0;
	self.frameIsDown = true;	
	self.isDown = true;
	self.isExpanded = true;
	self.doJointOrientation = false;
	self.attacherJointCopy = nil;
	self.TurnRadiusBackup = 0;
	self.attacherVehicleBackup = nil;
	self.AiLeftMarkerBackup = self.aiLeftMarker;
end;

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

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

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

function PoettingerSynkro6003T:update(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 = joint;	
				self.isDown = not joint.moveDown;
			end;
		end;
		self.doJointOrientation = false;
	end;
	if self:getIsActiveForInput() then
		if not self.frameIsDown then
			if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA2) then
				self.isExpanded = not self.isExpanded;
	        end;
		end;
    end;	
	if self:getIsActive() then
		self.wasToFast = false;	
		self.frameIsDown = false;		
		if self.attacherVehicle ~= nil then
			setJointRotationLimit(self.attacherJointCopy.jointIndex, 2, true, math.rad(-90), math.rad(90));
			self.isDown = not self.attacherJointCopy.moveDown;
		else
			self.isDown = false;
		end;	
		local x,y,z = getRotation(self.componentJoints[3].jointNode);
		if math.abs(self.axis.maxRot[1] - x) > 0.12 then
			self.frameIsDown = true;
		end;
		if self.frameIsDown and self.isExpanded then
		    local toFast = false;
			toFast = self:doCheckSpeedLimit() and self.lastSpeed*3600 > 30;
			if self.startActivationTime <= self.time and not toFast then
				self:unusualDirtIncrease(0.0004)
				if self.attacherVehicle ~= nil then
					if self.attacherVehicle.dirtComponents ~= nil then
						self.attacherVehicle:unusualDirtIncrease(0.0004)
					end;
				end;
				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);
					Utils.updateCultivatorArea(x, z, x1, z1, x2, z2);
				end;
			end;
			if self.cultivatorSound ~= nil and not self.cultivatorSoundEnabled and self:getIsActiveForSound() then
				if self.lastSpeed*3600 > 3 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);
			end;
			if self.lastSpeed*3600 < 5 and self.groundParticleSystemActive then
				self.groundParticleSystemActive = false;
				Utils.setEmittingState(self.groundParticleSystems, false);
			end;
			self.wasToFast = toFast;			
		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;
		
		-- Axis
		x,y,z = getRotation(self.componentJoints[3].jointNode);	
		local newRot = Utils.getMovedLimitedValues({x}, self.axis.maxRot, self.axis.minRot, 1, self.axis.rotTime, dt, not self.isDown);
		setRotation(self.componentJoints[3].jointNode, newRot[1],y,z);
	

		if math.abs(newRot[1] - x) > 0.001 then	
			setJointFrame(self.componentJoints[3].jointIndex, 1, self.componentJoints[3].jointNode);
			if not self.hydraulicSoundEnabled and self.hydraulicSound ~= nil and self:getIsActiveForSound() then
				playSample(self.hydraulicSound, 0, self.hydraulicSoundVolume, 0);
				setSamplePitch(self.hydraulicSound, self.hydraulicSoundPitchOffset-0.4);
				self.hydraulicSoundEnabled = true;  
				self.isAxixSoundActive = true;
			end;
		else
			if self.hydraulicSoundEnabled and not self.isFoldingSoundActive then
                stopSample(self.hydraulicSound);
                self.hydraulicSoundEnabled = false;  
				self.isAxixSoundActive = false;
            end;
		end;

		-- SideFrames
		x,y,z = getRotation(self.componentJoints[4].jointNode);	
		newRot = Utils.getMovedLimitedValues({z}, self.frame.maxRot, self.frame.minRot, 1, self.frame.rotTime, dt, self.isExpanded);
		setRotation(self.componentJoints[4].jointNode, x,y,newRot[1]);
		setRotation(self.componentJoints[5].jointNode, x,y,-newRot[1]);
		if math.abs(newRot[1] - z) > 0.001 then	
			setJointFrame(self.componentJoints[4].jointIndex, 1, self.componentJoints[4].jointNode);
			setJointFrame(self.componentJoints[5].jointIndex, 1, self.componentJoints[5].jointNode);
			if not self.hydraulicSoundEnabled and self.hydraulicSound ~= nil and self:getIsActiveForSound() then
				playSample(self.hydraulicSound, 0, self.hydraulicSoundVolume, 0);
				setSamplePitch(self.hydraulicSound, self.hydraulicSoundPitchOffset-0.4);
				self.hydraulicSoundEnabled = true; 
				self.isFoldingSoundActive = true;
			end;
		else
			if self.hydraulicSoundEnabled and not self.isAxixSoundActive then
                stopSample(self.hydraulicSound);
                self.hydraulicSoundEnabled = false; 
				self.isFoldingSoundActive = false;			
            end;
		end;	
		x,y,z = getRotation(self.frame.extensionLeft);	
		newRot = Utils.getMovedLimitedValues({z}, self.frame.extensionMaxRot, self.frame.extensionMinRot, 1, self.frame.rotTime, dt, self.isExpanded);
		setRotation(self.frame.extensionLeft, x,y,newRot[1]);
		setRotation(self.frame.extensionRight, x,y,-newRot[1]);	
	
		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);
				end;
			end;
		end;	
	else
		if self.groundParticleSystemActive then
			self.groundParticleSystemActive = false;
			Utils.setEmittingState(self.groundParticleSystems, false);
		end;
	end;

	if self.cultivatorSoundEnabled then
		if self.lastSpeed*3600 < 3 then
			stopSample(self.cultivatorSound);
			self.cultivatorSoundEnabled = false;
		end;
	end;
end;

function PoettingerSynkro6003T:draw()
	if not self.frameIsDown then
		if self.isExpanded then
			g_currentMission:addHelpButtonText(g_i18n:getText("SynkroT_CollapseFrame"), InputBinding.IMPLEMENT_EXTRA2);
		else
			g_currentMission:addHelpButtonText(g_i18n:getText("SynkroT_ExpandFrame"), InputBinding.IMPLEMENT_EXTRA2);
		end;
	end;
	if self.wasToFast then
        g_currentMission:addWarning(g_i18n:getText("Dont_drive_to_fast") .. "\n" .. string.format(g_i18n:getText("Cruise_control_levelN"), "2", InputBinding.getButtonKeyName(InputBinding.SPEED_LEVEL1)), 0.07+0.022, 0.019+0.029);
    end;
end;

function PoettingerSynkro6003T:onAttach(attacherVehicle)			
	setJointRotationLimit(self.componentJoints[2].jointIndex, 0, true, math.rad(-8), math.rad(8));
	setJointRotationLimit(self.componentJoints[2].jointIndex, 1, true, math.rad(-95), math.rad(95));
	self.doJointOrientation = true;
	self.startActivationTime = self.time + self.startActivationTimeout;
	local x,y,z = getTranslation(self.componentJoints[1].jointNode)
	setTranslation(self.componentJoints[1].jointNode, x, self.supportFeet.maxTrans, z);
	setJointFrame(self.componentJoints[1].jointIndex, 1, self.componentJoints[1].jointNode);
	self.attacherVehicleBackup = attacherVehicle;
	self.TurnRadiusBackup = self.attacherVehicleBackup.aiTractorTurnRadius;
	self.attacherVehicleBackup.aiTractorTurnRadius = 0;
end;

function PoettingerSynkro6003T:onDetach()
	setJointRotationLimit(self.componentJoints[2].jointIndex, 0, true, 0, 0);
	setJointRotationLimit(self.componentJoints[2].jointIndex, 1, true, 0, 0);
	setJointRotationLimit(self.componentJoints[2].jointIndex, 2, true, 0, 0);
	if self.attacherJointCopy ~= nil then
		self.attacherJointCopy = nil;
	end;
	if self.deactivateOnDetach then
        PoettingerSynkro6003T.onDeactivate(self);
    else
        PoettingerSynkro6003T.onDeactivateSounds(self);
    end;
	local x,y,z = getTranslation(self.componentJoints[1].jointNode)
	setTranslation(self.componentJoints[1].jointNode, x, self.supportFeet.minTrans, z);
	setJointFrame(self.componentJoints[1].jointIndex, 1, self.componentJoints[1].jointNode);	
	self.attacherVehicleBackup.aiTractorTurnRadius = self.TurnRadiusBackup;
	self.attacherVehicleBackup = nil;
end;

function PoettingerSynkro6003T:onLeave()
    if self.deactivateOnLeave then
        PoettingerSynkro6003T.onDeactivate(self);
    else
        PoettingerSynkro6003T.onDeactivateSounds(self);
    end;
end;

function PoettingerSynkro6003T:onDeactivate()
    PoettingerSynkro6003T.onDeactivateSounds(self);
    if self.groundParticleSystemActive then
        self.groundParticleSystemActive = false;
        Utils.setEmittingState(self.groundParticleSystems, false);
    end;
end;

function PoettingerSynkro6003T:onDeactivateSounds()
    if self.hydraulicSoundEnabled then
        stopSample(self.hydraulicSound);
        self.hydraulicSoundEnabled = false;   
    end;
	 if self.cultivatorSoundEnabled then
        stopSample(self.cultivatorSound);
        self.cultivatorSoundEnabled = false;
    end;
end;