--[[************************************************************************************************************************************************************
	
	extraRotatingParts v1.7.0 (compatible with MR)
	
	10/2014 © Saty MODS (Saty / http://forum.lsczech.cz)
	
****************************************************************************************************************************************************************
	
	(EN) INFO
	
	Free for use on mods. Modifications only with my permission !
	
	This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License (Attribution / NonCommercial / NoDerivatives)
	http://creativecommons.org/licenses/by-nc-nd/4.0/deed.en
	
****************************************************************************************************************************************************************
	
	(CZ) INFO
	
	Pro volne pouziti v modech. ZAKAZ modifikaci bez meho souhlasu !
	
	Toto dilo podleha licenci : Creative Commons 4.0 International - Uvedte autora / Neuzivejte dilo komercne / Nezasahujte do dila 
	http://creativecommons.org/licenses/by-nc-nd/4.0/deed.cs
	
	--------------------------------------------------------------------------------------------------------------------------------------------------------	
	
	Zapis do XML souboru stroje :
	*****************************
	
	<extraRotatingParts>
		<motorRotatingParts acceleration="0.03" deceleration="0.0125" >
			<part node="2|24" rotAxis="1" speedFixed="-500" speedByMotor="1" />
			<part node="2|25" rotAxis="2" speedFixed="900" speedByMotor="1" />
			<part node="2|26" rotAxis="3" speedFixed="0" speedByMotor="1.5" />
		</motorRotatingParts>
		<turnOnRotatingParts acceleration="0.03" deceleration="0.005" >
			<part node="8|0" rotAxis="1" speedFixed="-1000" />
			<part node="8|1" rotAxis="2" speedFixed="1000" />
		</turnOnRotatingParts>
		<threshingRotatingParts acceleration="0.03" deceleration="0.005" >
			<part node="6|8" rotAxis="1" speedFixed="-1100" />
			<part node="6|9" rotAxis="2" speedFixed="1100" />
		</threshingRotatingParts>
		<unloadingRotatingParts acceleration="0.03" deceleration="0.005" >
			<part node="7|2" rotAxis="1" speedFixed="-1000" />
			<part node="7|3" rotAxis="2" speedFixed="1000" />
		</unloadingRotatingParts>
		<driveRotatingParts>
			<part steeringNode="1>2" steeringFx="1" rotatingNode="1>2|0" fromWheel="1" rotatingFx="1" reverse="false" onlyAWD="false" />
		</driveRotatingParts>
	</extraRotatingParts>
	
	
	Vysvetlivky k funkcim:
	
	motorRotatingParts			- rotacni casti, ktere se toci pri nastartovanem motoru
	turnOnRotatingParts			- rotacni casti, ktere se toci pri zapnutem nastroji s funkci turnOn
	threshingRotatingParts			- rotacni casti, ktere se toci pri zapnutem drtici (funguje i pro listy kombajnu, atd.)
	unloadingRotatingParts			- rotacni casti, ktere se toci pri vypraznovani bunkru kombajnu
	driveRotatingParts			- rotacni casti, ktere se otaci pri jizde stejne s koly
	acceleration				- hodnota urcuje jak rychle se vsechny dane casti po zapnuti roztoci (pri nezadani defaultni hodnota "1" = okamzite roztoceni)
	deceleration				- hodnota urcuje jak rychle se vsechny dane casti po vypnuti zastavi (pri nezadani defaultni hodnota "1" = okamzite zastaveni)
	part					- jednotlive casti (neomezeny pocet)
	node					- index rotacni casti v GE
	rotAxis					- osa otaceni [1=X; 2=Y; 3=Z] (pri nezadani defaultni hodnota "2" = osa Y)
	speedFixed				- hodnota pevnych otacek (cca v RPM) [hodnota s - je reverzni otaceni]
	speedByMotor				- nasobek, ktery urcuje hodnotu otacek casti podle otacek motoru [1 = 1:1 s motorem] (funguje pouze s hodnotou speedFixed="0")
	steeringNode				- index casti v GE ktera zataci podle kola (osa Y)
	steeringFx					- nasobek zataceni casti oproti kolu (pri nezadani defaultni hodnota "1" = 1 : 1 s kolem)
	rotatingNode				- index casti v GE ktera se otaci podle kola (osa X)
	fromWheel				- kolo, podle ktereho se dana cast otaci (pri nezadani defaultni hodnota "1" = 1. kolo)
	rotatingFx				- nasobek otaceni casti oproti kolu (pri nezadani defaultni hodnota "1" = 1 : 1 s kolem)
	reverse					- opacny smer nez kolo (pri nezadani defaultni hodnota "false")
	onlyAWD					- dana cast se otaci pouze pri zapnutem AWD/4x4 (pri nezadani defaultni hodnota "false" = otaci se stale)
	
	--------------------------------------------------------------------------------------------------------------------------------------------------------	
	
	Zapis do souboru modDesc.xml :
	******************************
	
	vsadit do <specializations> :
		<specialization name="extraRotatingParts"  className="extraRotatingParts"  filename="scripts/extraRotatingParts.lua"/>
	
	vsadit do <vehicleTypes> :
		<specialization name="extraRotatingParts" /> 
	
************************************************************************************************************************************************************]]--

extraRotatingParts = {};

function extraRotatingParts.prerequisitesPresent(specializations)
    return true;
end;

function extraRotatingParts:load(xmlFile)
	-- motor rotating parts
	self.motorRotatingParts = {};
	self.accelerationMRP = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.extraRotatingParts.motorRotatingParts#acceleration"), 1);
	self.decelerationMRP = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.extraRotatingParts.motorRotatingParts#deceleration"), 1);
	local i = 0;
	while true do
		local key = string.format("vehicle.extraRotatingParts.motorRotatingParts.part(%d)", i);
		if not hasXMLProperty(xmlFile, key) then
			break;
		end;
		local node = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#node"));
		local rotAxis = Utils.getNoNil(getXMLInt(xmlFile, key.."#rotAxis"), 2);
		local speedFixed = Utils.getNoNil(getXMLFloat(xmlFile, key.."#speedFixed"), 0);
		if speedFixed ~= 0 then
			speedFixed = math.rad(speedFixed * 0.001);
		end;
		local speedByMotor = Utils.getNoNil(getXMLFloat(xmlFile, key.."#speedByMotor"), 1);
		if node ~= nil then
			table.insert(self.motorRotatingParts, {node=node, rotAxis=rotAxis, speedFixed=speedFixed, speedByMotor=speedByMotor});
		end;
		i = i + 1;
	end;
	
	-- turnOn rotating parts
	self.turnOnRotatingParts = {};
	self.accelerationORP = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.extraRotatingParts.turnOnRotatingParts#acceleration"), 1);
	self.decelerationORP = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.extraRotatingParts.turnOnRotatingParts#deceleration"), 1);
	local i = 0;
	while true do
		local key = string.format("vehicle.extraRotatingParts.turnOnRotatingParts.part(%d)", i);
		if not hasXMLProperty(xmlFile, key) then
			break;
		end;
		local node = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#node"));
		local rotAxis = Utils.getNoNil(getXMLInt(xmlFile, key.."#rotAxis"), 2);
		local speedFixed = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, key.."#speedFixed"), 0)*0.001);
		if node ~= nil then
			table.insert(self.turnOnRotatingParts, {node=node, rotAxis=rotAxis, speedFixed=speedFixed});
		end;
		i = i + 1;
	end;
	
	-- threshing rotating parts
	self.threshingRotatingParts = {};
	self.accelerationTRP = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.extraRotatingParts.threshingRotatingParts#acceleration"), 1);
	self.decelerationTRP = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.extraRotatingParts.threshingRotatingParts#deceleration"), 1);
	local i = 0;
	while true do
		local key = string.format("vehicle.extraRotatingParts.threshingRotatingParts.part(%d)", i);
		if not hasXMLProperty(xmlFile, key) then
			break;
		end;
		local node = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#node"));
		local rotAxis = Utils.getNoNil(getXMLInt(xmlFile, key.."#rotAxis"), 2);
		local speedFixed = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, key.."#speedFixed"), 0)*0.001);
		if node ~= nil then
			table.insert(self.threshingRotatingParts, {node=node, rotAxis=rotAxis, speedFixed=speedFixed});
		end;
		i = i + 1;
	end;
	
	-- unloading rotating parts
	self.unloadingRotatingParts = {};
	self.accelerationURP = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.extraRotatingParts.unloadingRotatingParts#acceleration"), 1);
	self.decelerationURP = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.extraRotatingParts.unloadingRotatingParts#deceleration"), 1);
	local i = 0;
	while true do
		local key = string.format("vehicle.extraRotatingParts.unloadingRotatingParts.part(%d)", i);
		if not hasXMLProperty(xmlFile, key) then
			break;
		end;
		local node = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#node"));
		local rotAxis = Utils.getNoNil(getXMLInt(xmlFile, key.."#rotAxis"), 2);
		local speedFixed = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, key.."#speedFixed"), 0)*0.001);
		if node ~= nil then
			table.insert(self.unloadingRotatingParts, {node=node, rotAxis=rotAxis, speedFixed=speedFixed});
		end;
		i = i + 1;
	end;
	
	-- drive rotating parts
	self.driveRotatingParts = {};
	local i = 0;
	while true do
		local key = string.format("vehicle.extraRotatingParts.driveRotatingParts.part(%d)", i);
		if not hasXMLProperty(xmlFile, key) then
			break;
		end;
		local steeringNode = Utils.indexToObject(self.components, Utils.getNoNil(getXMLString(xmlFile, key.."#steeringNode"), getXMLString(xmlFile, key.."#node")));
		local steeringFx = Utils.getNoNil(getXMLFloat(xmlFile, key.."#steeringFx"), 1);
		local rotatingNode = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#rotatingNode"));
		local reversion = Utils.getNoNil(getXMLBool(xmlFile, key .. "#reverse"), false);
		local rotatingFx = Utils.getNoNil(getXMLFloat(xmlFile, key.."#rotatingFx"), 1);
		local wheel = Utils.getNoNil(getXMLInt(xmlFile, key.."#fromWheel"), 1);
		local awd = Utils.getNoNil(getXMLBool(xmlFile, key .. "#onlyAWD"), false);
		if steeringNode ~= nil or rotatingNode ~= nil then
			table.insert(self.driveRotatingParts, {steeringNode=steeringNode, steeringFx=steeringFx, rotatingNode=rotatingNode, reversion=reversion, rotatingFx=rotatingFx, wheel=wheel, awd=awd});
		end;
		i = i + 1;
	end;
	
	self.regSpeedMRP = 0;
	self.regSpeedORP = 0;
	self.regSpeedTRP = 0;
	self.regSpeedURP = 0;
	
	self.cutterOverload = false;
end;

function extraRotatingParts:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)	
	if not resetVehicles then

	end; 
    return BaseMission.VEHICLE_LOAD_OK;
end;

function extraRotatingParts:getSaveAttributesAndNodes(nodeIdent)
	local attributes = "";
	return attributes, nil;
end;

function extraRotatingParts:update(dt)
end;

function extraRotatingParts:updateTick(dt)
	if self.motor ~= nil and self.isMotorStarted then
		if self.regSpeedMRP < 1 then
			self.regSpeedMRP = self.regSpeedMRP + self.accelerationMRP;
		else
			self.regSpeedMRP = 1;
		end;
		for _, node in pairs(self.motorRotatingParts) do
			if node.speedFixed ~= 0 then
				if node.rotAxis == 3 then
					rotate(node.node, 0, 0, dt * (node.speedFixed * self.regSpeedMRP));
				elseif node.rotAxis == 1 then
					rotate(node.node, dt * (node.speedFixed * self.regSpeedMRP), 0, 0);
				else
					rotate(node.node, 0, dt * (node.speedFixed * self.regSpeedMRP), 0);
				end;
			else
				local speed = {};
				if self.motor.isRealistic then
					speed = math.rad(RealisticUtils.linearFx(self.realLastMotorFx^0.5, 300, 2300) * node.speedByMotor * 0.001);
				else
					speed = math.rad(self.motor.lastMotorRpm * node.speedByMotor * 0.001);
				end;
				if node.rotAxis == 3 then
					rotate(node.node, 0, 0, dt * (speed * self.regSpeedMRP));
				elseif node.rotAxis == 1 then
					rotate(node.node, dt * (speed * self.regSpeedMRP), 0, 0);
				else
					rotate(node.node, 0, dt * (speed * self.regSpeedMRP), 0);
				end;
			end;
		end;
	else
		if self.regSpeedMRP > 0 then
			self.regSpeedMRP = self.regSpeedMRP - self.decelerationMRP;
			for _, node in pairs(self.motorRotatingParts) do
				if node.speedFixed ~= 0 then
					if node.rotAxis == 3 then
						rotate(node.node, 0, 0, dt * (node.speedFixed * self.regSpeedMRP));
					elseif node.rotAxis == 1 then
						rotate(node.node, dt * (node.speedFixed * self.regSpeedMRP), 0, 0);
					else
						rotate(node.node, 0, dt * (node.speedFixed * self.regSpeedMRP), 0);
					end;
				else
					local speed = {};
					if self.motor.isRealistic then
						speed = math.rad(RealisticUtils.linearFx(self.realLastMotorFx^0.5, 300, 2300) * node.speedByMotor * 0.001);
					else
						speed = math.rad(self.motor.lastMotorRpm * node.speedByMotor * 0.001);
					end;
					if node.rotAxis == 3 then
						rotate(node.node, 0, 0, dt * (speed * self.regSpeedMRP));
					elseif node.rotAxis == 1 then
						rotate(node.node, dt * (speed * self.regSpeedMRP), 0, 0);
					else
						rotate(node.node, 0, dt * (speed * self.regSpeedMRP), 0);
					end;
				end;
			end;
		else
			self.regSpeedMRP = 0;
		end;
	end;

	if self.isTurnedOn or self.isRefillTurnOn or self.isBackSaleTurnOn then
		if self.regSpeedORP < 1 then
			self.regSpeedORP = self.regSpeedORP + self.accelerationORP;
		else
			self.regSpeedORP = 1;
		end;
		for _, node in pairs(self.turnOnRotatingParts) do
			if node.rotAxis == 3 then
				rotate(node.node, 0, 0, dt * (node.speedFixed * self.regSpeedORP));
			elseif node.rotAxis == 1 then
				rotate(node.node, dt * (node.speedFixed * self.regSpeedORP), 0, 0);
			else
				rotate(node.node, 0, dt * (node.speedFixed * self.regSpeedORP), 0);
			end;
		end;
	else
		if self.regSpeedORP > 0 then
			self.regSpeedORP = self.regSpeedORP - self.decelerationORP;
			for _, node in pairs(self.turnOnRotatingParts) do
				if node.rotAxis == 3 then
					rotate(node.node, 0, 0, dt * (node.speedFixed * self.regSpeedORP));
				elseif node.rotAxis == 1 then
					rotate(node.node, dt * (node.speedFixed * self.regSpeedORP), 0, 0);
				else
					rotate(node.node, 0, dt * (node.speedFixed * self.regSpeedORP), 0);
				end;
			end;
		else
			self.regSpeedORP = 0;
		end;
	end;
	
	if not self.cutterOverload and (self.isThreshing or self.reelStarted) then
		if self.regSpeedTRP < 1 then
			self.regSpeedTRP = self.regSpeedTRP + self.accelerationTRP;
		else
			self.regSpeedTRP = 1;
		end;
		for _, node in pairs(self.threshingRotatingParts) do
			if node.rotAxis == 3 then
				rotate(node.node, 0, 0, dt * (node.speedFixed * self.regSpeedTRP));
			elseif node.rotAxis == 1 then
				rotate(node.node, dt * (node.speedFixed * self.regSpeedTRP), 0, 0);
			else
				rotate(node.node, 0, dt * (node.speedFixed * self.regSpeedTRP), 0);
			end;
		end;
	elseif self.cutterOverload then
		local regSpeed = math.random(0, 70) * 0.01;
		for _, node in pairs(self.threshingRotatingParts) do
			if node.rotAxis == 3 then
				rotate(node.node, 0, 0, dt * (node.speedFixed * regSpeed));
			elseif node.rotAxis == 1 then
				rotate(node.node, dt * (node.speedFixed * regSpeed), 0, 0);
			else
				rotate(node.node, 0, dt * (node.speedFixed * regSpeed), 0);
			end;
		end;
		self.regSpeedTRP = 0;
	else
		if self.regSpeedTRP > 0 then
			self.regSpeedTRP = self.regSpeedTRP - self.decelerationTRP;
			for _, node in pairs(self.threshingRotatingParts) do
				if node.rotAxis == 3 then
					rotate(node.node, 0, 0, dt * (node.speedFixed * self.regSpeedTRP));
				elseif node.rotAxis == 1 then
					rotate(node.node, dt * (node.speedFixed * self.regSpeedTRP), 0, 0);
				else
					rotate(node.node, 0, dt * (node.speedFixed * self.regSpeedTRP), 0);
				end;
			end;
		else
			self.regSpeedTRP = 0;
		end;
	end;
	
	if self.pipeIsUnloading then
		if self.regSpeedURP < 1 then
			self.regSpeedURP = self.regSpeedURP + self.accelerationURP;
		else
			self.regSpeedURP = 1;
		end;
		for _, node in pairs(self.unloadingRotatingParts) do
			if node.rotAxis == 3 then
				rotate(node.node, 0, 0, dt * (node.speedFixed * self.regSpeedURP));
			elseif node.rotAxis == 1 then
				rotate(node.node, dt * (node.speedFixed * self.regSpeedURP), 0, 0);
			else
				rotate(node.node, 0, dt * (node.speedFixed * self.regSpeedURP), 0);
			end;
		end;
	else
		if self.regSpeedURP > 0 then
			self.regSpeedURP = self.regSpeedURP - self.decelerationURP;
			for _, node in pairs(self.unloadingRotatingParts) do
				if node.rotAxis == 3 then
					rotate(node.node, 0, 0, dt * (node.speedFixed * self.regSpeedURP));
				elseif node.rotAxis == 1 then
					rotate(node.node, dt * (node.speedFixed * self.regSpeedURP), 0, 0);
				else
					rotate(node.node, 0, dt * (node.speedFixed * self.regSpeedURP), 0);
				end;
			end;
		else
			self.regSpeedURP = 0;
		end;
	end;
	
	if self.driveRotatingParts ~= nil and self.wheels ~= nil then
		for _, node in pairs(self.driveRotatingParts) do
			if self.wheels[node.wheel] ~= nil then
				if not node.awd or self.AllradV4Active or self.realAWDModeOn then
					if node.steeringNode ~= nil then
						local Sx1, Sy1, Sz1 = getRotation(self.wheels[node.wheel].repr);
						local Sx2, Sy2, Sz2 = getRotation(node.steeringNode);
						setRotation(node.steeringNode, Sx2, Sy1 * node.steeringFx, Sz2);
					end;
					if node.rotatingNode ~= nil then
						local Rx1, Ry1, Rz1 = getRotation(self.wheels[node.wheel].driveNode);
						local Rx2, Ry2, Rz2 = getRotation(node.rotatingNode);
						if node.reversion then Rx1 = -Rx1 end;
						setRotation(node.rotatingNode, Rx1*node.rotatingFx, Ry2, Rz2);
					end;
				end;
			end;
		end;
	end;
end;

function extraRotatingParts:delete()
end;

function extraRotatingParts:readStream(streamId, connection)
end;

function extraRotatingParts:writeStream(streamId, connection)
end;

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

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

function extraRotatingParts:draw()
end;

function extraRotatingParts:onDeactivate()
end;