--
-- Copyright � 2014 Joacim Sigfridsson <joxxer@msn.com>
-- This work is free. You can redistribute it and/or modify it under the
-- terms of the Do What The Fuck You Want To Public License, Version 2,
-- as published by Sam Hocevar. See http://www.wtfpl.net/ for more details.
--
--
-- BJR_MovingPartsInterior
-- Specialization for BJR_MovingPartsInterior 
--
-- @author  	JoXXer
-- @date  		27/03/13
--
-- @history	v1.0 - Initial implementation
--			v1.0.5 - 07/06/13 - All dependencies for ManualIgnition-specialization removed
--			v1.2 - 02/08/13 - General overhaul, fixed various bugs and implementation-issues. SpeedoMeter support added
--			v1.2.1 - 06/08/13 - RPMIndicator tweaked, now more configurable from the XML
--			v1.5 - 04/09/13 - Added support for MoreRealistic vehicles
--			v1.5.1 - 08/05/14 - Fixed issue where some parts would rotate incorrectly on OS X. 
--
-- <clutchPedal index="INDEX" minRot="FLOAT" maxRot="FLOAT" movementSpeed="FLOAT"/>
-- <brakePedalLeft index="INDEX" minRot="FLOAT" maxRot="FLOAT" movementSpeed="FLOAT"/>
-- <brakePedalRight index="INDEX" minRot="FLOAT" maxRot="FLOAT" movementSpeed="FLOAT"/>
-- <footThrottle index="INDEX"/>
-- <RPMIndicator index=INDEX" startRot="FLOAT" idleRot="FLOAT" maxRot="FLOAT" idleRPM="FLOAT" nomRPM="FLOAT" maxRPM="FLOAT"/>
-- <speedoMeter index="INDEX" startRot="FLOAT" maxRot="FLOAT" middleRot="FLOAT" firstRot="FLOAT" maxSpeed="FLOAT" middleSpeed="FLOAT" firstSpeed="FLOAT"/>
-- <fuelMeter index="INDEX" fullRot="FLOAT" modifier="INT (1 or -1)"/>
-- <tempMeter index="INDEX" maxRot="FLOAT" normalTemp="FLOAT" heatingUpModifier="FLOAT" modifier="INT (1 or -1)"/>
-- <shuttleLever index="INDEX" forwardRot="FLOAT" reverseRot="FLOAT" neutralRot="FLOAT" />
-- <gearLever index="INDEX" speed3Rot="FLOAT FLOAT FLOAT" speed2Rot="FLOAT FLOAT FLOAT" speed1Rot="FLOAT FLOAT FLOAT" />

BJR_MovingPartsInterior = {};

function BJR_MovingPartsInterior.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Motorized, specializations);
end;

function BJR_MovingPartsInterior:load(xmlFile)
	self.clutchPedal = {};
	self.clutchPedal.index = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.clutchPedal#index"));
	self.clutchPedal.maxRot = math.rad(Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.clutchPedal#maxRot"), 0));
	self.clutchPedal.minRot = math.rad(Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.clutchPedal#minRot"), 0));
	self.clutchPedal.movementSpeed = Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.clutchPedal#movementSpeed"), 0)/1000;
	
	self.brakePedalLeft = {};
	self.brakePedalLeft.index = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.brakePedalLeft#index"));
	self.brakePedalLeft.maxRot = math.rad(Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.brakePedalLeft#maxRot"), 0));
	self.brakePedalLeft.minRot = math.rad(Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.brakePedalLeft#minRot"), 0));
	self.brakePedalLeft.movementSpeed = Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.brakePedalLeft#movementSpeed"), 0)/1000;
	
	self.brakePedalRight = {};
	self.brakePedalRight.index = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.brakePedalRight#index"));
	self.brakePedalRight.maxRot = math.rad(Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.brakePedalRight#maxRot"), 0));
	self.brakePedalRight.minRot = math.rad(Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.brakePedalRight#minRot"), 0));
	self.brakePedalRight.movementSpeed = Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.brakePedalRight#movementSpeed"), 0)/1000;
	
	self.footThrottle = {};
	self.footThrottle.index = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.footThrottle#index"));
	self.footThrottle.movementSpeed = Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.footThrottle#movementSpeed"), 0)/1000;
	
	self.RPMIndicator = {};
	self.RPMIndicator.index = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.RPMIndicator#index"));
	self.RPMIndicator.startRot = math.rad(Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.RPMIndicator#startRot"), 0));
	self.RPMIndicator.idleRot = Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.RPMIndicator#idleRot"), 0);
	self.RPMIndicator.maxRot = Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.RPMIndicator#maxRot"), 0);
	self.RPMIndicator.idleRPM = Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.RPMIndicator#idleRPM"), 800);
	self.RPMIndicator.nomRPM = Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.RPMIndicator#nomRPM"), 2200);
	self.RPMIndicator.maxRPM = Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.RPMIndicator#maxRPM"), 2600);
	self.RPMIndicator.RPMDeg = (self.RPMIndicator.maxRot - self.RPMIndicator.idleRot) / self.RPMIndicator.maxRPM;
	
	self.speedoMeter = {};
	self.speedoMeter.index = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.speedoMeter#index"));
	self.speedoMeter.startRot = math.rad(Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.speedoMeter#startRot"), 0));
	self.speedoMeter.maxRot = math.rad(Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.speedoMeter#maxRot"), 0));
	self.speedoMeter.middleRot = math.rad(Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.speedoMeter#middleRot"), 0));
	self.speedoMeter.firstRot = math.rad(Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.speedoMeter#firstRot"), 0));
	self.speedoMeter.maxSpeed = Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.speedoMeter#maxSpeed"), 0);
	self.speedoMeter.middleSpeed = Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.speedoMeter#middleSpeed"), 0);
	self.speedoMeter.firstSpeed = Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.speedoMeter#firstSpeed"), 0);
	self.speedoMeter.speedPercentageMax = math.deg(self.speedoMeter.maxRot - self.speedoMeter.middleRot)/(self.speedoMeter.maxSpeed - self.speedoMeter.middleSpeed);
	self.speedoMeter.speedPercentageMiddle = math.deg(self.speedoMeter.middleRot - self.speedoMeter.firstRot)/(self.speedoMeter.middleSpeed - self.speedoMeter.firstSpeed);
	self.speedoMeter.speedPercentageFirst = math.deg(self.speedoMeter.firstRot)/self.speedoMeter.firstSpeed;
	
	self.fuelMeter = {};
	self.fuelMeter.index = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.fuelMeter#index"));
	if self.fuelMeter.index ~= nil then
		self.fuelMeter.fullRot = math.rad(Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.fuelMeter#fullRot"), 0));
		self.fuelMeter.modifier = Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.fuelMeter#modifier"), 0);
		local fuelX, fuelY, fuelZ = getRotation(self.fuelMeter.index);
		self.fuelMeter.startRot = fuelY;
		self.fuelMeter.totalRot = (self.fuelMeter.fullRot - self.fuelMeter.startRot) * self.fuelMeter.modifier;
		if self.fuelMeter.modifier == 1 then
			self.fuelMeter.fuelPercentage = self.fuelCapacity/100;
		else
			self.fuelMeter.fuelPercentage = math.deg(self.fuelMeter.totalRot)/self.fuelCapacity;
		end;
		self.fuelMeter.hasMovedUp = false;
	end;
	
	self.tempMeter = {};
	self.tempMeter.index = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.tempMeter#index"));
	local tempX, tempY, tempZ = getRotation(self.tempMeter.index);
	self.tempMeter.startRot = tempY;
	self.tempMeter.maxRot = math.rad(Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.tempMeter#maxRot"), 0));
	self.tempMeter.modifier = Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.tempMeter#modifier"), 0);
	self.tempMeter.normalTemp = Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.tempMeter#normalTemp"), 0);
	self.tempMeter.tempPercentage = math.deg(self.tempMeter.maxRot)/self.tempMeter.normalTemp;
	self.tempMeter.heatingUpModifier = Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.tempMeter#heatingUpModifier"), 0)/1000000;
	self.tempMeter.hasMovedUp = false;
	self.tempMeter.motorTemp = 0;
	
	self.shuttleLever = {};
	self.shuttleLever.index = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.shuttleLever#index"));
	if self.shuttleLever.index ~= nil then
		self.shuttleLever.origRot = {getRotation(self.shuttleLever.index)};
	end;
	self.shuttleLever.forwardRot = math.rad(Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.shuttleLever#forwardRot"), 0));
	self.shuttleLever.reverseRot = math.rad(Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.shuttleLever#reverseRot"), 0));
	self.shuttleLever.neutralRot = math.rad(Utils.getNoNil(getXMLFloat(xmlFile,  "vehicle.shuttleLever#neutralRot"), 0));
	self.shuttleLever.currentDirection = 0;
	
	self.gearLever = {};
	self.gearLever.index = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.gearLever#index"));
	if self.gearLever.index ~= nil then
		self.gearLever.origRot = {getRotation(self.gearLever.index)};
		self.gearLever.speed1Rot = Utils.getRadiansFromString(getXMLString(xmlFile,  "vehicle.gearLever#speed1Rot"), 3);
		self.gearLever.speed2Rot = Utils.getRadiansFromString(getXMLString(xmlFile,  "vehicle.gearLever#speed2Rot"), 3);
		self.gearLever.speed3Rot = Utils.getRadiansFromString(getXMLString(xmlFile,  "vehicle.gearLever#speed3Rot"), 3);
	end;
end;

function BJR_MovingPartsInterior:delete()

end;

function BJR_MovingPartsInterior:readStream(streamId, connection)
end;

function BJR_MovingPartsInterior:writeStream(streamId, connection)
end;

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

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

function BJR_MovingPartsInterior:update(dt)
	if self.ignitionMode == nil or self.ignitionMode == 2 then
		if self.tempMeter.motorTemp < self.tempMeter.normalTemp then
			if self.isRealistic then
				local currentRpm = 0;
				if self.realManualGearSet then
					currentRPM = RealisticUtils.linearFx(self.realSoundEngineRevFx^0.5, 800, 2300);
				else
					currentRPM = RealisticUtils.linearFx(self.realLastMotorFx^0.5, 800, 2300);
				end;
				if currentRPM < 810 and currentRPM > 790 then
					self.tempMeter.motorTemp = self.tempMeter.motorTemp + (self.tempMeter.heatingUpModifier * 1000);
				else
					self.tempMeter.motorTemp = self.tempMeter.motorTemp + (currentRPM * self.tempMeter.heatingUpModifier);
				end;
			else
				if self.motor.lastMotorRpm  == self.motor.minRpm then 
					self.tempMeter.motorTemp = self.tempMeter.motorTemp + (self.tempMeter.heatingUpModifier * 1000);
				else
					self.tempMeter.motorTemp = self.tempMeter.motorTemp + (self.motor.lastMotorRpm * self.tempMeter.heatingUpModifier);
				end;
			end;
		end;
	else
		if self.tempMeter.motorTemp > 0 then
			self.tempMeter.motorTemp = self.tempMeter.motorTemp - (self.tempMeter.heatingUpModifier * 1000);
		end;
	end;

	if self:getIsActive() then
		if self.gearLever.index ~= nil then
			if self.motor.speedLevel == 1 then
				setRotation(self.gearLever.index, unpack(self.gearLever.speed1Rot));
			elseif self.motor.speedLevel == 2 then
				setRotation(self.gearLever.index, unpack(self.gearLever.speed2Rot));
			elseif self.motor.speedLevel == 3 then
				setRotation(self.gearLever.index, unpack(self.gearLever.speed3Rot));
			else
				if self.lastAcceleration ~= 0 then
					setRotation(self.gearLever.index, unpack(self.gearLever.speed3Rot));
				else
					setRotation(self.gearLever.index, unpack(self.gearLever.origRot));
				end;
			end;
		end;
		
		if self.ignitionMode == nil or self.ignitionMode >= 1 then
		
			if (self.ignitionMode == nil or self.ignitionMode >= 2) and self.speedoMeter.index ~= nil then
				local rotX, rotY, rotZ = getRotation(self.speedoMeter.index);
				
				-- Thanks dural! <3 http://fs-uk.com/forum/index.php?topic=138368.msg927294#msg927294
				local kmh = math.min(100, math.max(0, self.lastSpeed*self.speedDisplayScale*3600)) - 0.00008 *dt;
				
				
				if kmh < self.speedoMeter.firstSpeed then
					local speedRot = math.rad(kmh * self.speedoMeter.speedPercentageFirst);
					setRotation(self.speedoMeter.index, rotX, speedRot, rotZ);
				elseif kmh < self.speedoMeter.middleSpeed then
					local speedRot = math.rad((kmh - self.speedoMeter.firstSpeed) * self.speedoMeter.speedPercentageMiddle) + math.rad(self.speedoMeter.firstSpeed * self.speedoMeter.speedPercentageFirst);
					setRotation(self.speedoMeter.index, rotX, speedRot, rotZ);
				elseif kmh < self.speedoMeter.maxSpeed then
					local speedRot = math.rad((kmh - self.speedoMeter.middleSpeed) * self.speedoMeter.speedPercentageMax) + math.rad((self.speedoMeter.middleSpeed - self.speedoMeter.firstSpeed) * self.speedoMeter.speedPercentageMiddle) + math.rad(self.speedoMeter.firstSpeed * self.speedoMeter.speedPercentageFirst);
					setRotation(self.speedoMeter.index, rotX, speedRot, rotZ);
				else
				end;
					
			end;
			
			if (self.ignitionMode == nil or self.ignitionMode >= 2) and self.RPMIndicator.index ~= nil then
				local rpmRotation = self.RPMIndicator.idleRot;
				if self.isRealistic then
					local currentRpm = 0;
					if self.realManualGearSet then
						currentRPM = RealisticUtils.linearFx(self.realSoundEngineRevFx^0.5, self.RPMIndicator.idleRPM , self.RPMIndicator.nomRPM);
					else
						currentRPM = RealisticUtils.linearFx(self.realLastMotorFx^0.5, self.RPMIndicator.idleRPM , self.RPMIndicator.nomRPM);
					end;
					if currentRPM < self.RPMIndicator.idleRPM+10 then
						rpmRotation = (currentRPM * self.RPMIndicator.RPMDeg) + math.random(self.RPMIndicator.idleRot-2, self.RPMIndicator.idleRot+2);
					else
						rpmRotation = (currentRPM * self.RPMIndicator.RPMDeg) + self.RPMIndicator.idleRot;
					end;
				else
					if self.motor.lastMotorRpm == self.motor.minRpm then
						rpmRotation = math.random(self.RPMIndicator.idleRot-2, self.RPMIndicator.idleRot+2);
					else
						rpmRotation = (self.motor.lastMotorRpm * self.RPMIndicator.RPMDeg) + self.RPMIndicator.idleRot;
					end;
				end;
				setRotation(self.RPMIndicator.index, 0, math.rad(rpmRotation), 0);
			end;
			
			if self.fuelMeter.index ~= nil then
				local rotX, rotY, rotZ = getRotation(self.fuelMeter.index);
				if self.fuelMeter.modifier == 1 then
					local fuelDifference = self.fuelCapacity - self.fuelFillLevel;
					local fuelMeterRot = math.rad(fuelDifference/100)*self.fuelMeter.fuelPercentage*10;
					if rotY < -fuelMeterRot and self.fuelMeter.hasMovedUp ~= true then
						setRotation(self.fuelMeter.index, 0, rotY + dt * 0.001 , 0);
					else
						self.fuelMeter.hasMovedUp = true;
						setRotation(self.fuelMeter.index, 0, -fuelMeterRot , 0);
					end;
				elseif self.fuelMeter.modifier == -1 then
					local fuelMeterRot = math.rad(self.fuelFillLevel*self.fuelMeter.fuelPercentage);
					if rotY > -fuelMeterRot and self.fuelMeter.hasMovedUp ~= true then
						setRotation(self.fuelMeter.index, 0, rotY - dt * 0.001 , 0);
					else
						self.fuelMeter.hasMovedUp = true;
						setRotation(self.fuelMeter.index, 0, -fuelMeterRot , 0);
					end;
				end;
			end;
	
			if self.tempMeter.index ~= nil then
				local rotX, rotY, rotZ = getRotation(self.tempMeter.index);
				if self.tempMeter.modifier == 1 then
					local tempMeterRot = math.rad(self.tempMeter.motorTemp/1.4);
					tempMeterRot = self.tempMeter.startRot - tempMeterRot;
					
					if rotY > tempMeterRot and self.tempMeter.hasMovedUp ~= true then
						setRotation(self.tempMeter.index, 0, rotY - dt * 0.001 , 0);
					else
						self.tempMeter.hasMovedUp = true;
						setRotation(self.tempMeter.index, 0, tempMeterRot , 0);
					end;
				else
					local tempMeterRot = math.rad(self.tempMeter.motorTemp * self.tempMeter.tempPercentage);
					if rotY < tempMeterRot and self.tempMeter.hasMovedUp ~= true then
						setRotation(self.tempMeter.index, 0, rotY + dt * 0.001 , 0);
					else
						self.tempMeter.hasMovedUp = true;
						setRotation(self.tempMeter.index, 0, tempMeterRot , 0);
					end;
				end;
			end;
	
		else
			if self.clutchPedal.index ~= nil then
				local rotX, rotY, rotZ = getRotation(self.clutchPedal.index);
				if rotX < self.clutchPedal.minRot then
					setRotation(self.clutchPedal.index, rotX + dt * self.clutchPedal.movementSpeed, rotY, rotZ);
				end;
			end;
			--[[if self.movingDirection == 1 and self.lastAcceleration <= 0 or self.movingDirection == -1 and self.lastAcceleration >= 0 or self.lastAcceleration == 0 then
				if self.clutchPedal.index ~= nil then
					local rotX, rotY, rotZ = getRotation(self.clutchPedal.index);
					if rotX > self.clutchPedal.maxRot then
						setRotation(self.clutchPedal.index, rotX - dt * self.clutchPedal.movementSpeed, rotY, rotZ);
					end;
				end;
			else
				if self.clutchPedal.index ~= nil then
					local rotX, rotY, rotZ = getRotation(self.clutchPedal.index);
					if rotX < self.clutchPedal.minRot then
						setRotation(self.clutchPedal.index, rotX + dt * self.clutchPedal.movementSpeed, rotY, rotZ);
					end;
				end;
			end;]]--
			
			if self.brakePedalLeft.index ~= nil then
				local rotX, rotY, rotZ = getRotation(self.brakePedalLeft.index);
				if rotX < self.brakePedalLeft.minRot then
					setRotation(self.brakePedalLeft.index, rotX + dt * self.brakePedalLeft.movementSpeed, rotY, rotZ);
				end;
			end;
			
			if self.brakePedalRight.index ~= nil then
				local rotX, rotY, rotZ = getRotation(self.brakePedalRight.index);
				if rotX < self.brakePedalRight.minRot then
					setRotation(self.brakePedalRight.index, rotX + dt * self.brakePedalRight.movementSpeed, rotY, rotZ);
				end;
			end;
			
			if self.RPMIndicator.index ~= nil then
				setRotation(self.RPMIndicator.index, 0, self.RPMIndicator.startRot, 0);
			end;
	
			if self.fuelMeter.index ~= nil then
				local rotX, rotY, rotZ = getRotation(self.fuelMeter.index);
				if self.fuelMeter.modifier == 1 then
					if rotY > self.fuelMeter.startRot and self.fuelMeter.hasMovedUp == true then
						setRotation(self.fuelMeter.index, 0, rotY - dt * 0.001 , 0);
					else
						self.fuelMeter.hasMovedUp = false;
					end;
				elseif self.fuelMeter.modifier == -1 then
					if rotY < self.fuelMeter.startRot and self.fuelMeter.hasMovedUp == true then
						setRotation(self.fuelMeter.index, 0, rotY + dt * 0.001 , 0);
					else
						self.fuelMeter.hasMovedUp = false;
					end;
				end;
			end;
	
			if self.tempMeter.index ~= nil then
				local rotX, rotY, rotZ = getRotation(self.tempMeter.index);
				if self.tempMeter.modifier == 1 then
					if rotY < self.tempMeter.startRot and self.tempMeter.hasMovedUp == true then
						setRotation(self.tempMeter.index, 0, rotY + dt * 0.001 , 0);
					else
						self.tempMeter.hasMovedUp = false;
					end;
				else
					if rotY > self.tempMeter.startRot and self.tempMeter.hasMovedUp == true then
						setRotation(self.tempMeter.index, 0, rotY - dt * 0.001 , 0);
					else
						self.tempMeter.hasMovedUp = false;
					end;
				end;
			end;
	
		end;
	end;
end;

function BJR_MovingPartsInterior:updateTick(dt)

end;

function BJR_MovingPartsInterior:draw()

end;