--[[************************************************************************************************************************************************************
	
	extraRotatingParts v1.3 (compatible with MR)
	
	10/2013 by Saty / http://forum.lsczech.cz
	
****************************************************************************************************************************************************************
	
	(EN) INFO
	
	Free for use on mods. Modifications only with my permission !
	
****************************************************************************************************************************************************************
	
	(CZ) INFO
	
	Pro volne pouziti v modech. ZAKAZ modifikaci bez meho souhlasu !
	
	--------------------------------------------------------------------------------------------------------------------------------------------------------	
	
	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>
		<threshingRotatingParts acceleration="0.03" deceleration="0.005" >
			<part node="6|8" rotAxis="1" speedFixed="-1100" />
			<part node="6|9" rotAxis="2" speedFixed="1100" />
		</threshingRotatingParts>
		<turnOnRotatingParts acceleration="0.03" deceleration="0.005" >
			<part node="8|0" rotAxis="1" speedFixed="-1000" />
			<part node="8|1" rotAxis="2" speedFixed="1000" />
		</turnOnRotatingParts>
		<driveRotatingParts>
			<part node="22|0" fromWheel="1" onlyAWD="false" />
		</driveRotatingParts>
	</extraRotatingParts>
	
	
	Vysvetlivky k funkcim:
	
	motorRotatingParts			- rotacni casti, ktere se toci pri nastartovanem motoru
	threshingRotatingParts			- rotacni casti, ktere se toci pri zapnutem drtici (funguje i pro listy kombajnu, atd.)
	turnOnRotatingParts			- rotacni casti, ktere se toci pri zapnutem nastroji s funkci turnOn
	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")
	fromWheel				- kolo, podle ktereho se dana cast otaci (pri nezadani defaultni hodnota "1" = 1. kolo)
	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;
	
	-- 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 node = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#node"));
		local wheel = Utils.getNoNil(getXMLInt(xmlFile, key.."#fromWheel"), 1);
		local awd = Utils.getNoNil(getXMLBool(xmlFile, key .. "#onlyAWD"), false);
		if node ~= nil then
			table.insert(self.driveRotatingParts, {node=node, wheel=wheel, awd=awd});
		end;
		i = i + 1;
	end;
	
	self.regSpeedMRP = 0;
	self.regSpeedORP = 0;
	self.regSpeedTRP = 0;
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 then
		if self.regSpeedORP < 1 then
			self.regSpeedORP = self.regSpeedORP + self.accelerationORP;
		else
			self.regSpeedORP = 1;
		end;
		for _, node in pairs(self.turnedOnRotatingParts) 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.turnedOnRotatingParts) 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 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;
	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.driveRotatingParts ~= nil and self.wheels ~= nil then
		for _, node in pairs(self.driveRotatingParts) do
			if not node.awd or self.AllradV4Active or self.realAWDModeOn then
				local x1, y1, z1 = getRotation(self.wheels[node.wheel].driveNode);
				local x2, y2, z2 = getRotation(node.node);
				setRotation(node.node, x1, y2, z2);
			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;