--
-- BJR_Washable
-- Specialization for BJR_Washable functionality
--
-- @author  	Manuel Leithner (SFM-Modding)
-- @edit		v3.5 - JoXXer - BJR-Modding
-- @version 	v3.5
-- @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
--				v3.5 - Now only increases dirt on fields, and dirt "falls off" when not on a field. 
--

BJR_Washable = {};

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

function BJR_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 BJR_Washable:readStream(streamId, connection)
    local dirtScale = streamReadFloat32(streamId);
    self:unusualDirtIncrease(dirtScale);
end;

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

function BJR_Washable:delete()
end;

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

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

function BJR_Washable:update(dt)
end;

function BJR_Washable:updateTick(dt)
	if self:getIsActive() or self.isActive then
		local dens = 0; 
		local dens1; 
		local dens2; 
		local dens3;
		
		local x,y,z = getWorldTranslation(self.wheels[2].repr);
		local x1,y1,z1 = getWorldTranslation(self.wheels[1].repr);
		local x2,y2,z2 = getWorldTranslation(self.wheels[4].repr);
		local id = g_currentMission.terrainDetailId;
		local xx, zz, widthX, widthZ, heightX, heightZ = Utils.getXZWidthAndHeight(id, x, z, x1, z1, x2, z2);
		dens1 = getDensityParallelogram(id, xx, zz, widthX, widthZ, heightX, heightZ, g_currentMission.cultivatorChannel, 1);
		dens2 = getDensityParallelogram(id, xx, zz, widthX, widthZ, heightX, heightZ, g_currentMission.sowingChannel, 1);
		dens3 = getDensityParallelogram(id, xx, zz, widthX, widthZ, heightX, heightZ, g_currentMission.ploughChannel, 1);
		
		dens = dens1+dens2+dens3;
		
		if dens > 0 then
			self:increaseDirt(dt);
		elseif self.dirtScale > 0.7 then
			self:decreaseDirt(dt);
		end;
	end;
	
	if math.abs(self.dirtScale-self.oldDirtScale) > self.updateInterval then
		for i=1, table.getn(self.dirtComponents) do
			setShaderParameter(self.dirtComponents[i], "dirtScale", self.dirtScale, 0,0,0,false);
		end;
		self.oldDirtScale = self.dirtScale;
	end;
end;

function BJR_Washable:draw()
end;


function BJR_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 BJR_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 BJR_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 BJR_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 BJR_Washable:getSaveAttributesAndNodes(nodeIdent)	
    local attributes = 'dirtLevel="'.. tostring(self.dirtScale) .. '"';
    return attributes, nil;
end;