--
-- SilageAdditives
-- Specialization for SilageAdditives
--
-- @author  Stefan Maurus
-- @date  04/06/14

-- Copyright © Stefan Maurus, www.stefanmaurus.de

--[[
	<silageAdditives capacity="LITERS" litersPerSecond="LITERS" increase="PERCENT" usedForFillType="FRUITTYPE" />
		<particleSystem node="INDEX" position="0 0 0" rotation="0 0 0" file="PATH"/>
	</silageAdditives>
]]

SilageAdditives = {};

function SilageAdditives.prerequisitesPresent(specializations)
	return SpecializationUtil.hasSpecialization(Pickup, specializations); -- for self.actLoad_IntSend in line 124
end;

function SilageAdditives:load(savegame)
	self.setTankIsFilling = SpecializationUtil.callSpecializationsFunction("setTankIsFilling");
	self.setTankFillLevel = SpecializationUtil.callSpecializationsFunction("setTankFillLevel");
	self.setSilageAdditivesActiv = SpecializationUtil.callSpecializationsFunction("setSilageAdditivesActiv");

	self.silageAdditives = {};
	self.silageAdditivesFillLevel = 0;
	self.silageAdditives.capacity = getXMLFloat(self.xmlFile, "vehicle.silageAdditives#capacity");
	self.silageAdditives.litersPerSecond = getXMLFloat(self.xmlFile, "vehicle.silageAdditives#litersPerSecond");
	self.silageAdditives.increase = getXMLFloat(self.xmlFile, "vehicle.silageAdditives#increase");
	self.silageAdditives.usedForFillType = FillUtil.fillTypeNameToInt[getXMLString(self.xmlFile, "vehicle.silageAdditives#usedForFillType")];

	psPath = string.format("vehicle.silageAdditives.particleSystem");
	local silageAdditivesPS = {};
	local particleNode = Utils.loadParticleSystem(self.xmlFile, silageAdditivesPS, psPath, self.components, false, "$data/vehicles/particleSystems/trailerDischargeParticleSystem.i3d", self.baseDirectory);
	self.silageAdditives.particleSystem = silageAdditivesPS;

	self.silageAdditivesIsActiv = false;
	self.silageAdditivesTankIsFilling = false;
	self.silageAdditivesTankAllowsFilling = false;

	self.timer = 0;
	self.interval = 1000; --ms

	self.hud = {};
    local uiScale = g_uiScale;
    if g_gameSettings ~= nil then
        uiScale = g_gameSettings:getValue("uiScale")
    end
	local width, height = getNormalizedScreenValues(225*uiScale, 20*uiScale);
	local w, h = getNormalizedScreenValues(0, 165*uiScale);
	self.hud.xPos = 1-g_safeFrameOffsetX-width;
	self.hud.yPos = h+g_safeFrameOffsetY;
	self.hud.hudWidth = width;
	self.hud.overlay_hud 	= Overlay:new("loadHUD_hud", 	Utils.getFilename("hud/hud_block.dds", self.baseDirectory), self.hud.xPos, self.hud.yPos, width, height);
	self.hud.overlay_bar 	= Overlay:new("loadHUD_bar", 	Utils.getFilename("hud/hud_barY.dds", self.baseDirectory), self.hud.xPos, self.hud.yPos, width, height);

	self.fillScaleFix = self.forageWagon.fillScale;
end;

function SilageAdditives:delete()
	Utils.deleteParticleSystem(self.silageAdditives.particleSystem);
end;

function SilageAdditives:readStream(streamId, connection)
	self:setSilageAdditivesActiv(streamReadBool(streamId), true);
	self:setTankIsFilling(streamReadBool(streamId), true);
	self:setTankFillLevel(streamReadFloat32(streamId), true);
end;

function SilageAdditives:writeStream(streamId, connection)
	streamWriteBool(streamId, self.silageAdditivesIsActiv);
	streamWriteBool(streamId, self.silageAdditivesTankIsFilling);
	streamWriteFloat32(streamId, self.silageAdditivesFillLevel);
end;

function SilageAdditives:setSilageAdditivesActiv(bool, noEventSend)
	self.silageAdditivesIsActiv = bool;
	SetSilageAdditivesActivEvent.sendEvent(self, bool, noEventSend);
end;

function SilageAdditives:setTankIsFilling(bool, noEventSend)
	self.silageAdditivesTankIsFilling = bool;
	SetTankIsFillingEvent.sendEvent(self, bool, noEventSend);
end;

function SilageAdditives:setTankFillLevel(fillLevel, noEventSend)
	self.silageAdditivesFillLevel = fillLevel;
	if fillLevel == self.silageAdditives.capacity then
		self.silageAdditivesTankAllowsFilling = false;
		self:setTankIsFilling(false);
	end;
	SetTankFillLevelEvent.sendEvent(self, fillLevel, noEventSend);
end;

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

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

function SilageAdditives:postLoad(savegame)
    if savegame ~= nil and not savegame.resetVehicles then
        self:setTankFillLevel(Utils.getNoNil(getXMLFloat(savegame.xmlFile, savegame.key.."#silageAdditivesFillLevel"),0));
        self:setSilageAdditivesActiv(Utils.getNoNil(getXMLBool(savegame.xmlFile, savegame.key.."#silageAdditivesIsActiv"),false));
    end;
end

function SilageAdditives:getSaveAttributesAndNodes(nodeIdent)
	local attributes = 'silageAdditivesFillLevel="' ..tostring(self.silageAdditivesFillLevel).. '" silageAdditivesIsActiv="' ..tostring(self.silageAdditivesIsActiv).. '"';
	return attributes, nil;
end;

function SilageAdditives:update(dt)
	if self:getIsActiveForInput() and self.silageAdditivesTankAllowsFilling then
		if InputBinding.hasEvent(InputBinding.ACTIVATE_OBJECT) then
			self:setTankIsFilling(not self.silageAdditivesTankIsFilling);
		end;
	end;

	if self:getIsActiveForInput() and self.silageAdditivesFillLevel > 0 then
		if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA4) then
			self:setSilageAdditivesActiv(not self.silageAdditivesIsActiv);
		end;
	end;

	if self.silageAdditivesIsActiv and self.silageAdditivesFillLevel == 0 then
		self:setSilageAdditivesActiv(false);
	end;

	if self.blades == nil then
		if self.silageAdditivesIsActiv and self:getUnitFillType(self.forageWagon.fillUnitIndex) == self.silageAdditives.usedForFillType then
			self.forageWagon.fillScale = self.fillScaleFix+(self.fillScaleFix*self.silageAdditives.increase/100);

		else
			self.forageWagon.fillScale = self.fillScaleFix;
		end;
	end;

	if self:getIsTurnedOn() and self:getUnitFillType(self.forageWagon.fillUnitIndex) == self.silageAdditives.usedForFillType and self.lastSpeed*3600 > 2 and self.silageAdditivesFillLevel > 0 and self.silageAdditivesIsActiv then
		if self.isServer then
			--self.timer=self.timer+dt;
			--if self.timer >= self.interval then
				--self.timer = 0;
				self:setTankFillLevel(math.max(0,self.silageAdditivesFillLevel-self.silageAdditives.litersPerSecond/1000*dt));
			--end;
		end;
		Utils.setEmittingState(self.silageAdditives.particleSystem, true);
	else
		self.timer = 0;
		Utils.setEmittingState(self.silageAdditives.particleSystem, false);
	end;
end;

function SilageAdditives:draw()
	if self.silageAdditivesTankAllowsFilling then
		if self.silageAdditivesTankIsFilling then
			g_currentMission:addHelpButtonText(string.format(g_i18n:getText("SILAGEADD_STOP_FILLING")), InputBinding.ACTIVATE_OBJECT, nil, GS_PRIO_NORMAL)
		else
			g_currentMission:addHelpButtonText(string.format(g_i18n:getText("SILAGEADD_START_FILLING")), InputBinding.ACTIVATE_OBJECT, nil, GS_PRIO_NORMAL)
		end;
	end;

	if self.silageAdditivesFillLevel > 0 and (self:getUnitFillType(self.forageWagon.fillUnitIndex) == self.silageAdditives.usedForFillType or self:getUnitFillType(self.forageWagon.fillUnitIndex) == FillUtil.FILLTYPE_UNKNOWN) then
		if self.silageAdditivesIsActiv then
			g_currentMission:addHelpButtonText(string.format(g_i18n:getText("SILAGEADD_TURNOFF")), InputBinding.IMPLEMENT_EXTRA4, nil, GS_PRIO_HIGH)
		else
			g_currentMission:addHelpButtonText(string.format(g_i18n:getText("SILAGEADD_TURNON")), InputBinding.IMPLEMENT_EXTRA4, nil, GS_PRIO_HIGH)
		end;
	end;

	setTextColor(1.0, 1.0, 1.0, 1.0);
	setTextBold(false);
	setTextAlignment(RenderText.ALIGN_CENTER);

	local percent = self.silageAdditivesFillLevel/self.silageAdditives.capacity;

	self.hud.overlay_bar.width = self.hud.hudWidth * percent;
    setOverlayUVs(self.hud.overlay_bar.overlayId, 0, 0.05, 0, 1, percent, 0.05, percent, 1);
	setOverlayColor(self.hud.overlay_bar.overlayId, 156/255, 150/255, 0, 1);

	self.hud.overlay_bar:render();
	self.hud.overlay_hud:render();

    local uiScale = g_uiScale;
    if g_gameSettings ~= nil then
        uiScale = g_gameSettings:getValue("uiScale")
    end
	local x, y = getNormalizedScreenValues(225*uiScale/2, 7);
	renderText(self.hud.xPos+x, self.hud.yPos+y, 0.012*uiScale, string.format(g_i18n:getText("SILAGE_ADDITIVES").." %5.2f l", self.silageAdditivesFillLevel));
	setTextAlignment(RenderText.ALIGN_LEFT);
end;

function SilageAdditives:onAttach(attacherVehicle)
end;

function SilageAdditives:onDetach()
end

----isActiv Event----

SetSilageAdditivesActivEvent = {};
SetSilageAdditivesActivEvent_mt = Class(SetSilageAdditivesActivEvent, Event);

InitEventClass(SetSilageAdditivesActivEvent, "SetSilageAdditivesActivEvent");

function SetSilageAdditivesActivEvent:emptyNew()
    local self = Event:new(SetSilageAdditivesActivEvent_mt);
    self.className="SetSilageAdditivesActivEvent";
    return self;
end;

function SetSilageAdditivesActivEvent:new(vehicle, silageAdditivesIsActiv)
    local self = SetSilageAdditivesActivEvent:emptyNew()
    self.vehicle = vehicle;
	self.silageAdditivesIsActiv = silageAdditivesIsActiv;
    return self;
end;

function SetSilageAdditivesActivEvent:readStream(streamId, connection)
    local id = streamReadInt32(streamId);
    self.vehicle = networkGetObject(id);

	self.silageAdditivesIsActiv = streamReadBool(streamId);
	if self.vehicle ~= nil then
		self.vehicle:setSilageAdditivesActiv(self.silageAdditivesIsActiv, true);
	end;
	if not connection:getIsServer() then
        g_server:broadcastEvent(SetSilageAdditivesActivEvent:new(self.vehicle, self.silageAdditivesIsActiv), nil, connection, self.vehicle);
    end;
end;

function SetSilageAdditivesActivEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));
	streamWriteBool(streamId, self.silageAdditivesIsActiv);
end;

function SetSilageAdditivesActivEvent.sendEvent(vehicle, silageAdditivesIsActiv, noEventSend)
	if noEventSend == nil or noEventSend == false then
		if g_server ~= nil then
			g_server:broadcastEvent(SetSilageAdditivesActivEvent:new(vehicle, silageAdditivesIsActiv), nil, nil, vehicle);
		else
			g_client:getServerConnection():sendEvent(SetSilageAdditivesActivEvent:new(vehicle, silageAdditivesIsActiv));
		end;
	end;
end;

----Filling Event----

SetTankIsFillingEvent = {};
SetTankIsFillingEvent_mt = Class(SetTankIsFillingEvent, Event);

InitEventClass(SetTankIsFillingEvent, "SetTankIsFillingEvent");

function SetTankIsFillingEvent:emptyNew()
    local self = Event:new(SetTankIsFillingEvent_mt);
    self.className="SetTankIsFillingEvent";
    return self;
end;

function SetTankIsFillingEvent:new(vehicle, silageAdditivesTankIsFilling)
    local self = SetTankIsFillingEvent:emptyNew()
    self.vehicle = vehicle;
	self.silageAdditivesTankIsFilling = silageAdditivesTankIsFilling;
    return self;
end;

function SetTankIsFillingEvent:readStream(streamId, connection)
    local id = streamReadInt32(streamId);
    self.vehicle = networkGetObject(id);

	self.silageAdditivesTankIsFilling = streamReadBool(streamId);
	if self.vehicle ~= nil then
		self.vehicle:setTankIsFilling(self.silageAdditivesTankIsFilling, true);
	end;

	if not connection:getIsServer() then
        g_server:broadcastEvent(SetTankIsFillingEvent:new(self.vehicle, self.silageAdditivesTankIsFilling), nil, connection, self.vehicle);
    end;
end;

function SetTankIsFillingEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));
	streamWriteBool(streamId, self.silageAdditivesTankIsFilling);
end;

function SetTankIsFillingEvent.sendEvent(vehicle, silageAdditivesTankIsFilling, noEventSend)
	if noEventSend == nil or noEventSend == false then
		if g_server ~= nil then
			g_server:broadcastEvent(SetTankIsFillingEvent:new(vehicle, silageAdditivesTankIsFilling), nil, nil, vehicle);
		else
			g_client:getServerConnection():sendEvent(SetTankIsFillingEvent:new(vehicle, silageAdditivesTankIsFilling));
		end;
	end;
end;

----FillLevel Event----

SetTankFillLevelEvent = {};
SetTankFillLevelEvent_mt = Class(SetTankFillLevelEvent, Event);

InitEventClass(SetTankFillLevelEvent, "SetTankFillLevelEvent");

function SetTankFillLevelEvent:emptyNew()
    local self = Event:new(SetTankFillLevelEvent_mt);
    self.className="SetTankFillLevelEvent";
    return self;
end;

function SetTankFillLevelEvent:new(vehicle, silageAdditivesFillLevel)
    local self = SetTankFillLevelEvent:emptyNew()
    self.vehicle = vehicle;
	self.silageAdditivesFillLevel = silageAdditivesFillLevel;
    return self;
end;

function SetTankFillLevelEvent:readStream(streamId, connection)
    local id = streamReadInt32(streamId);
    self.vehicle = networkGetObject(id);

	self.silageAdditivesFillLevel = streamReadFloat32(streamId);
	if self.vehicle ~= nil then
		self.vehicle:setTankFillLevel(self.silageAdditivesFillLevel, true);
	end;
	if not connection:getIsServer() then
        g_server:broadcastEvent(SetTankFillLevelEvent:new(self.vehicle, self.silageAdditivesFillLevel), nil, connection, self.vehicle);
    end;
end;

function SetTankFillLevelEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));
	streamWriteFloat32(streamId, self.silageAdditivesFillLevel);
end;

function SetTankFillLevelEvent.sendEvent(vehicle, silageAdditivesFillLevel, noEventSend)
	if noEventSend == nil or noEventSend == false then
		if g_server ~= nil then
			g_server:broadcastEvent(SetTankFillLevelEvent:new(vehicle, silageAdditivesFillLevel), nil, nil, vehicle);
		else
			g_client:getServerConnection():sendEvent(SetTankFillLevelEvent:new(vehicle, silageAdditivesFillLevel));
		end;
	end;
end;
-- converted