--
-- smokeParticles
--
-- @author:    	Xentro (www.fs-uk.com)(Marcus@Xentro.se)
-- @version:    v1.0
-- @date:       2013-11-29
-- 
--[[
<smokeParticles fillTypes="FILLTYPE FILLTYPE" cooldown="MINUTES" moveableNode="INDEX" minY="FLOAT" maxY="FLOAT">
	<particle node="INDEX" position="0 0 0" rotation="0 0 0" file="FILE" />
</smokeParticles>
]]--

smokeParticles = {};

function smokeParticles.prerequisitesPresent(specializations)
    if not SpecializationUtil.hasSpecialization(Fillable, specializations) then print("Warning: Specialization smokeParticles needs the specialization Fillable."); end;
	
	return SpecializationUtil.hasSpecialization(Fillable, specializations);
end;

function smokeParticles:load(xmlFile)
	self.setParticles = SpecializationUtil.callSpecializationsFunction("setParticles");
	self.setFillLevel = Utils.prependedFunction(self.setFillLevel, smokeParticles.setFillLevel);
	
	self.smokeP = {};
	self.smokeP.isEmitting = false;
	self.smokeP.lastFillLevel = 0;
	self.smokeP.curTime = 0;
	self.smokeP.lastTime = 0;
	self.smokeP.cooldown = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.smokeParticles#cooldown"), 10);
	self.smokeP.bcts = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.smokeParticles#baseCooldownOnTimeScale"), true);
	
	local moveableNode = getXMLString(xmlFile, "vehicle.smokeParticles#moveableNode");
	if moveableNode ~= nil then
		self.smokeP.moveable = {};
		self.smokeP.moveable.node = Utils.indexToObject(self.components, moveableNode);
		
		self.smokeP.moveable.min = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.smokeParticles#minY"), 0);
		self.smokeP.moveable.max = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.smokeParticles#maxY"), 3);
		local trans = {getTranslation(self.smokeP.moveable.node)};
		setTranslation(self.smokeP.moveable.node, trans[1], self.smokeP.moveable.min, trans[3]);
	end;
	
	self.smokeP.allowedFillTypes = {};
	local fillTypes = getXMLString(xmlFile, "vehicle.smokeParticles#fillTypes");
	if fillTypes ~= nil then
		local types = Utils.splitString(" ", fillTypes);
		
		for k, v in pairs(types) do
			local fillTypeInt = Fillable.fillTypeNameToInt[v];
			if fillTypeInt ~= nil then
				self.smokeP.allowedFillTypes[fillTypeInt] = true;
			end;
		end;
	end;
	
	if self.isClient then
		self.smokeP.nodes = {};
		local i = 0;
		while true do 
			local key = string.format("vehicle.smokeParticles.particle(%d)", i);
			if not hasXMLProperty(xmlFile, key) then break;	end;
			local currentPS = {};
			local particleNode = Utils.loadParticleSystem(xmlFile, currentPS, key, self.components, false, "$data/vehicles/particleSystems/trailerDischargeParticleSystem.i3d", self.baseDirectory);

			table.insert(self.smokeP.nodes, currentPS);
			i = i + 1;
		end;
	end;
end;

function smokeParticles:delete()
	if self.isClient then
		for _, particleSystem in pairs(self.smokeP.nodes) do
			Utils.deleteParticleSystem(particleSystem);
		end;
	end;
end;

function smokeParticles:readStream(streamId, connection)
end;

function smokeParticles:writeStream(streamId, connection)
end;

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

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

function smokeParticles:update(dt)
end;

function smokeParticles:updateTick(dt)
	if self.smokeP.curTime > 0 and self.fillLevel > 0 then
		if not self.smokeP.isEmitting then
			self:setParticles(true);
		else
			local dtMinutes = dt / 60000;
			
			if self.smokeP.bcts then
				dtMinutes = dtMinutes * g_currentMission.environment.timeScale;
			end;
			
			self.smokeP.curTime = self.smokeP.curTime - dtMinutes;
			
			if self.smokeP.lastTime ~= self.smokeP.curTime then
				local scale = math.max(self.smokeP.curTime, 0) / self.smokeP.cooldown;
				if self.isClient then
					for _, particleSystem in pairs(self.smokeP.nodes) do
						Utils.setEmitCountScale(particleSystem, scale);
					end;
				end;
				
				if self.smokeP.moveable ~= nil then
					local trans = {getTranslation(self.smokeP.moveable.node)};
					trans[2] = self.smokeP.moveable.min + (self.smokeP.moveable.max - self.smokeP.moveable.min) * Utils.clamp(self.fillLevel, 0, self.capacity) / (self.capacity);
					setTranslation(self.smokeP.moveable.node, unpack(trans));
				end;
				
				self.smokeP.lastTime = self.smokeP.curTime;
			end;
		end;
	else
		if self.smokeP.isEmitting then
			self:setParticles(false);
		end;
	end;
end;

function smokeParticles:draw()
end;

function smokeParticles:setParticles(state)
	if self.isClient then
		for _, particleSystem in pairs(self.smokeP.nodes) do
			Utils.setEmittingState(particleSystem, state);
		end;
	end;
	
	self.smokeP.isEmitting = state;
	
	if not state then
		self.smokeP.curTime = 0;
	end;
end;

function smokeParticles:setFillLevel(fillLevel, fillType, force)
	if self.smokeP.allowedFillTypes[fillType] ~= nil and self.smokeP.allowedFillTypes[fillType] then
		if fillLevel > self.smokeP.lastFillLevel then
			self.smokeP.curTime = self.smokeP.cooldown;
		end;
		
		self.smokeP.lastFillLevel = fillLevel;
	end;
end;