--
-- Washable
-- Specialization for Washable functionality
--
-- @author  	Manuel Leithner (SFM-Modding)
-- @version 	v3.0
-- @date  		15/10/10
-- @history:	v1.0 - Initial version
--				v2.0 - Changed xml-reading, added updateInterval to define updating interval for vehicles with many dirtComponents (performance issue)
--				v3.0 - added network support, changed update to updateTick
--
-- free for noncommerical-usage
--

Washable = {};

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

function Washable:load(xmlFile)

	self.increaseDirt = SpecializationUtil.callSpecializationsFunction("increaseDirt");
	self.decreaseDirt = SpecializationUtil.callSpecializationsFunction("decreaseDirt");
	self.unusualDirtIncrease = SpecializationUtil.callSpecializationsFunction("unusualDirtIncrease");
	
	local i = 0;
	self.dirtComponents = {};
	while true do
		local path = string.format("vehicle.dirt.dirtComponent(%d)", i);
		local component = Utils.indexToObject(self.components, getXMLString(xmlFile, path .. "#index"));	
		if component == nil then
			break;
		end;
		table.insert(self.dirtComponents, component);
		i = i + 1;
	end;	
	
	self.updateInterval = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.dirt#updateInterval"), 0.05);
	self.dirtInterval = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.dirt#dirtInterval"), 1) * 60 * 60 * 1000;
	self.cleaningInterval = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.dirt#cleaningInterval"), 30) * 1000;

	self.dirtScale = 0;
	self.oldDirtScale = self.dirtScale;
	self.timeScale = 1;

end;

function Washable:readStream(streamId, connection)
    local dirtScale = streamReadFloat32(streamId);
    self:unusualDirtIncrease(dirtScale);
end;

function Washable:writeStream(streamId, connection)
    streamWriteFloat32(streamId, self.dirtScale);
end;

function Washable:delete()
end;

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

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

function Washable:update(dt)
end;

function Washable:updateTick(dt)
	if g_currentMission.environment.lastRainScale > 0.1 and g_currentMission.environment.timeSinceLastRain < 30 then
		self:decreaseDirt(dt);
	else
		if self:getIsActive() or self.isActive then
			self:increaseDirt(dt);
		end;
	end;	
	
	if math.abs(self.dirtScale-self.oldDirtScale) > self.updateInterval then
		for _, component in pairs(self.dirtComponents) do
			setShaderParameter(component, "dirtScale", self.dirtScale, 0,0,0,false);
		end;
		self.oldDirtScale = self.dirtScale;
	end;
end;

function Washable:draw()
end;


function Washable:unusualDirtIncrease(increase)
	if self.dirtScale < 1 then
		self.dirtScale = self.dirtScale + increase;
		if self.dirtScale > 1 then
			self.dirtScale = 1;
		end;
	end;
end;

function Washable:increaseDirt(dt)
	if self.dirtScale > 1 then
		self.dirtScale = 1;
	end;
	if self.dirtScale < 1 then
		local scale = Utils.getMovedLimitedValues({self.dirtScale}, {1}, {0}, 1, self.dirtInterval*self.timeScale, dt, false);
		self.dirtScale = scale[1];
	end;
end;

function Washable:decreaseDirt(dt)
	if self.dirtScale < 0 then
		self.dirtScale = 0;
	end;
	if self.dirtScale > 0 then
		local scale = Utils.getMovedLimitedValues({self.dirtScale}, {1}, {0}, 1, self.cleaningInterval*self.timeScale, dt, true);
		self.dirtScale = scale[1];
	end;
end;

function Washable:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	if not resetVehicles then
		self.dirtScale = Utils.getNoNil(getXMLFloat(xmlFile, key.."#dirtLevel"),0);
	end; 
    return BaseMission.VEHICLE_LOAD_OK;
end;

function Washable:getSaveAttributesAndNodes(nodeIdent)	
    local attributes = 'dirtLevel="'.. tostring(self.dirtScale) .. '"';
    return attributes, nil;
end;