----------------------------------------------------------------------------
--------------"The simplest design is the best design." --------------
----------------------------------------------------------------------------
----------------------------------------------------------------------------
-- Copyright (C)ViperGTS96--------------------------------------------
----------------------------------------------------------------------------

mudFieldSinkUpdater = {};

function mudFieldSinkUpdater:loadMap(name)
    g_currentMission.mudFieldSinkUpdater = {};
    g_currentMission.mudFieldSinkUpdater.fieldSinkAmount = 0;
	g_currentMission.mudFieldSinkUpdater.maxRainTime = 10.0; --minutes
	g_currentMission.mudFieldSinkUpdater.maxRainTime = g_currentMission.mudFieldSinkUpdater.maxRainTime * 60;
	g_currentMission.mudFieldSinkUpdater.sendSinkAmount = mudFieldSinkUpdater.sendSinkAmount;
end;

function mudFieldSinkUpdater:deleteMap()
    g_currentMission.mudFieldSinkUpdater = nil;
end;

function mudFieldSinkUpdater:update(dt)
	local mfsu = g_currentMission.mudFieldSinkUpdater;
	if g_currentMission:getIsServer() then
		if mudSystem:getIsGroundWet(true) and mfsu.fieldSinkAmount < 1.0 then
			local gameTime = (g_time/1000);
			
			if mfsu.timeSinceRainStart == nil then
				mfsu.timeSinceRainEnd = nil;
				mfsu.timeSinceRainStart = gameTime;
				mfsu.rainStartSinkAmount = mfsu.fieldSinkAmount;
			end;

			local increment = (gameTime - mfsu.timeSinceRainStart) / mfsu.maxRainTime;
			increment = increment - (mfsu.fieldSinkAmount-mfsu.rainStartSinkAmount);
			mfsu.fieldSinkAmount = mfsu.fieldSinkAmount + increment;

			if mfsu.fieldSinkAmount > 0.999 then mfsu.fieldSinkAmount = 1.0; end;
			mfsu:sendSinkAmount(mfsu.fieldSinkAmount);
		elseif mfsu.fieldSinkAmount > 0 then
			local gameTime = (g_time/1000);
			
			if mfsu.timeSinceRainEnd == nil then
				mfsu.timeSinceRainStart = nil;
				mfsu.timeSinceRainEnd = gameTime;
				mfsu.rainEndSinkAmount = mfsu.fieldSinkAmount;
			end;

			local decrement = (gameTime - mfsu.timeSinceRainEnd) / mfsu.maxRainTime;
			decrement = decrement - (mfsu.rainEndSinkAmount-mfsu.fieldSinkAmount);
			mfsu.fieldSinkAmount = mfsu.fieldSinkAmount - decrement;

			if mfsu.fieldSinkAmount < 0 then mfsu.fieldSinkAmount = 0; mfsu.rainEndSinkAmount = 0; end;
			mfsu:sendSinkAmount(mfsu.fieldSinkAmount);	
		end;
	end;
end;


 function mudFieldSinkUpdater:sendSinkAmount(sinkAmount, noEventSend)
	if g_currentMission.missionDynamicInfo.isMultiplayer then
		mudSystemSinkEvent.sendEvent(g_currentMission.mudFieldSinkUpdater, sinkAmount, noEventSend);
		g_currentMission.mudFieldSinkUpdater.fieldSinkAmount = sinkAmount;
	end;
end;

addModEventListener(mudFieldSinkUpdater);

mudFieldSinkUpdaterEvent = {};
mudFieldSinkUpdaterEvent_mt = Class(mudFieldSinkUpdaterEvent, Event);
InitEventClass(mudFieldSinkUpdaterEvent,"mudFieldSinkUpdaterEvent");

function mudFieldSinkUpdaterEvent:emptyNew()
    local self = Event.new(mudFieldSinkUpdaterEvent_mt);
    self.className = "mudFieldSinkUpdaterEvent";
    return self;
end;
function mudFieldSinkUpdaterEvent:new(table,sinkAmount)
	local self = mudFieldSinkUpdaterEvent.emptyNew()
    self.table = table;
    self.sinkAmount = sinkAmount;
    return self;
end;
function mudFieldSinkUpdaterEvent:readStream(streamId,connection)
    self.table = NetworkUtil.readNodeObject(streamId);
    self.sinkAmount = streamReadFloat16(streamId);
    self:run(connection);
end;
function mudFieldSinkUpdaterEvent:writeStream(streamId,connection)
    NetworkUtil.writeNodeObject(streamId,self.table);
    streamWriteFloat16(streamId,self.sinkAmount);
end;
function mudFieldSinkUpdaterEvent:run(connection)
    --self.table:sendSinkAmount(self.sinkAmount, true);
	g_currentMission.mudFieldSinkUpdater.fieldSinkAmount = self.sinkAmount;
    if not connection:getIsServer() then
        g_server:broadcastEvent(mudFieldSinkUpdaterEvent:new(self.table,self.sinkAmount),nil,connection,self.table);
    end;
end;
function mudFieldSinkUpdaterEvent.sendEvent(table,sinkAmount,noEventSend)
    if noEventSend == nil or noEventSend == false then
        if g_server ~= nil then
            g_server:broadcastEvent(mudFieldSinkUpdaterEvent:new(table,sinkAmount),nil,nil,table);
        else
            g_client:getServerConnection():sendEvent(mudFieldSinkUpdaterEvent:new(table,sinkAmount));
        end;
    end;
end;

function mudFieldSinkUpdater:saveSettings()
	if g_currentMission:getIsServer() then
		local savegameFolderPath = g_currentMission.missionInfo.savegameDirectory;
		if savegameFolderPath == nil then
			savegameFolderPath = ('%ssavegame%d'):format(getUserProfileAppPath(), g_currentMission.missionInfo.savegameIndex);
		end;
		local xmlFileName = savegameFolderPath.."/mudSystemFieldSink.xml";
		local mudSystemRainXML = createXMLFile("mudSystemRainXML", xmlFileName, "mudSystem");
		setXMLFloat(mudSystemRainXML, "mudSystem.rain#fieldSinkAmount", g_currentMission.mudFieldSinkUpdater.fieldSinkAmount);
		saveXMLFile(mudSystemRainXML);
		delete(mudSystemRainXML);
	end;
end;

function mudFieldSinkUpdater:loadMapFinished()
	if g_currentMission:getIsServer() then
		local savegameFolderPath = g_currentMission.missionInfo.savegameDirectory;
		if savegameFolderPath == nil then
			savegameFolderPath = ('%ssavegame%d'):format(getUserProfileAppPath(), g_currentMission.missionInfo.savegameIndex);
		end;

		local xmlFileName = savegameFolderPath.."/mudSystemFieldSink.xml";
		if fileExists(xmlFileName) then
			local mfsu = g_currentMission.mudFieldSinkUpdater;
			local mudSystemRainXML = loadXMLFile("mudSystemRainXML", xmlFileName, "mudSystem");
			mfsu.fieldSinkAmount = Utils.getNoNil(getXMLFloat(mudSystemRainXML, "mudSystem.rain#fieldSinkAmount"), mfsu.fieldSinkAmount);
			if mfsu.fieldSinkAmount < 0 then mfsu.fieldSinkAmount = 0; end;
			delete(mudSystemRainXML);
			--deleteFile(xmlFileName);
		end;
	end;
end;

FSBaseMission.saveSavegame = Utils.appendedFunction(FSBaseMission.saveSavegame, mudFieldSinkUpdater.saveSettings);
FSBaseMission.loadMapFinished = Utils.appendedFunction(FSBaseMission.loadMapFinished, mudFieldSinkUpdater.loadMapFinished);