--
-- ESLimiter
-- Specialization for ESLimiter
--
-- SFM-Modding
-- @author      Manuel Leithner
-- @date:		04/10/11
-- @version:	v2.2
--
-- @history:	v1.0 - initial implementation
--				v2.0 - convert to LS2011 and some bugfixes
--				v2.1 - Network-Fixes
--              v2.2 - fixed localization of disabled text, now reads from i10 table
--
-- @Modified-by: Robert Hostens
-- @Modified-date: 2011/04/10
--
-- Notes:  Add the following constants to your localization table
--
-- ESLIMIT_DISABLED - Text displayed when script is disabled
-- ESLIMIT_DECREASE - text displayed to decrease cruise RPM
-- ESLIMIT_INCREASE - text displayed to increase cruise RPM
-- ESLIMIT_LEVEL    - Ex 'Level n: x%'
-- ESLIMIT_CONTROLS - text prepended to additional help text displaying keybinds
--
-- Add the following keybinds to your modDesc xml
--
-- ESLIMIT_INCREASE - key to increase current cruise RPM Limit
-- ESLIMIT_DECREASE - key to increase current cruise RPM Limit
--


ESLimiter = {};

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

function ESLimiter:load(xmlFile)
	self.setNewLimit = SpecializationUtil.callSpecializationsFunction("setNewLimit");

	self.ESLimiter = {};
	self.ESLimiter.xPos = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.ESLimiter#posX"), 0.7543);
	self.ESLimiter.yPos = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.ESLimiter#posY"), 0.1715);
	self.ESLimiter.maxRPM = {};
	self.ESLimiter.percentage = {};
	
	for k, v in pairs(self.motor.maxRpm) do
		local percentage = string.format("%d",(self.motor.maxRpm[k] * 100 / self.motor.maxRpm[3]));
		self.ESLimiter.maxRPM[k] = self.motor.maxRpm[3];
		self.ESLimiter.percentage[k] = tonumber(percentage);
	end;

	self.lastButtonDown = nil;
	self.isLimiterActive = false;
end;

function ESLimiter:delete()
end;

function ESLimiter:readStream(streamId, connection)
	for level, _ in pairs(self.ESLimiter.percentage) do
		local percentage = streamReadInt8(streamId);
		self:setNewLimit(level, percentage, false, true);
	end;
end;

function ESLimiter:writeStream(streamId, connection)
	for _, percentage in pairs(self.ESLimiter.percentage) do
		streamWriteInt8(streamId, percentage);
	end;
end;

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

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

function ESLimiter:update(dt)
	if self:getIsActive() then
		if self:getIsActiveForInput() then
			local currentLevel = self.motor.speedLevel;
		
			if self.movingDirection < 0 then
				currentLevel = 1;
			end;

			if currentLevel ~= 0 then
				local percentage = self.ESLimiter.percentage;
				if Input.isKeyPressed(Input.KEY_pageup) and percentage[currentLevel] < 100 then
					self.lastButtonDown = Input.KEY_pageup;
					percentage[currentLevel] = percentage[currentLevel] + 0.1;
					-- don't send event to other players
					self:setNewLimit(currentLevel, percentage[currentLevel], false, true);
				elseif Input.isKeyPressed(Input.KEY_pagedown) and percentage[currentLevel] > 10 then
					percentage[currentLevel] = percentage[currentLevel] - 0.1;
					self.lastButtonDown = Input.KEY_pagedown;
					-- don't send event to other players
					self:setNewLimit(currentLevel, percentage[currentLevel], false, true);
				else
					if self.lastButtonDown ~= nil then
						-- only send event to other players if key was released -> performance issue
						self:setNewLimit(currentLevel, percentage[currentLevel], false);
						self.lastButtonDown = nil;
					end;	
				end;
				
				self.isLimiterActive = true;
			else
				if self.isLimiterActive then
					self:setNewLimit(3, 100, true);
					self.isLimiterActive = false;
				end;
				
				self.motor.maxRpm[3] = self.ESLimiter.maxRPM[3];
			end;
		end;
	end;
end;

function ESLimiter:draw()
    if self:getIsActive() then
    	if self.isMotorStarted and self.motor.speedLevel ~= 0 then
    		g_currentMission:addExtraPrintText("PAGE UP/DOWN:   "..string.format("%d RPM",self.motor.maxRpm[self.motor.speedLevel]).."");
	end;
    end;

end;

function ESLimiter:setNewLimit(level, percentage, doRestoreLimit, noEventSend)	
	ESLimiterEvent.sendEvent(self, level, percentage, doRestoreLimit, noEventSend);	
	local currentRPM = self.ESLimiter.maxRPM;

	if not doRestoreLimit then
		self.ESLimiter.percentage[level] = percentage;
	
		if self.movingDirection > 0 then
			self.motor.maxRpm[level] = tonumber(string.format("%d",(percentage * currentRPM[level] / 100)));
		else
			self.motor.maxRpm[3] = tonumber(string.format("%d",(percentage * currentRPM[level] / 100)));
		end;
	else
		self.motor.maxRpm[3] = self.ESLimiter.maxRPM[3];
	end;
end;


function ESLimiter:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	if not resetVehicles then
		local valueStr = getXMLString(xmlFile, key.."#limiterValues");		
		if valueStr ~= nil then
			local found = string.find(valueStr, ";");
			local index = 1;
	
			while found ~= nil do
				local value = string.sub(valueStr, 0, found-1);
				valueStr = string.sub(valueStr, found+1);
				found = string.find(valueStr, ";");
				self.ESLimiter.percentage[index] = tonumber(value);
			
				if found == nil then
					self.ESLimiter.percentage[index+1] = tonumber(valueStr);
				end;
				
				index = index + 1;	
			end;
		end;
	end; 

    return BaseMission.VEHICLE_LOAD_OK;
end;

function ESLimiter:getSaveAttributesAndNodes(nodeIdent)
	local values = "";	
	
	for k, v in pairs(self.ESLimiter.percentage) do
		if k ~= 1 then
			values = values .. ";";
		end;
		
		values = values .. string.format("%d", v);
	end;
	
    local attributes = 'limiterValues="'.. values .. '"';
    return attributes, nil;
end;