--
-- Map Function Scripts
-- by Blacky_BPG
--

---------- DEFINITIONS ----------
OpenTriggerManager = {};
OpenTriggerManager.savegamePath = getUserProfileAppPath() .. "savegame" .. g_careerScreen.selectedIndex;
OpenTriggerManager.savegameFilename = OpenTriggerManager.savegamePath .. "/OpenTrigger.xml";
OpenTrigger = {};
OpenTrigger.modDir = g_currentModDirectory;
OpenTriggerManagerRandomEvent = {};
OpenTriggerManagerRandomEvent_mt = Class(OpenTriggerManagerRandomEvent, Event);
OpenTriggerManagerEvent = {};
OpenTriggerManagerEvent_mt = Class(OpenTriggerManagerEvent, Event);
OpenTriggerRequestEvent = {};
OpenTriggerRequestEvent_mt = Class(OpenTriggerRequestEvent, Event);

---------- VARIABLES ----------

---------- OBJECT CLASSES ----------
InitEventClass(OpenTriggerManagerRandomEvent, "OpenTriggerManagerRandomEvent");
InitEventClass(OpenTriggerRequestEvent, "OpenTriggerRequestEvent");
InitEventClass(OpenTriggerManagerEvent, "OpenTriggerManagerEvent");

local CareerScreenSaveSelectedGame = CareerScreen.saveSelectedGame;
CareerScreen.saveSelectedGame = function(self)
	CareerScreenSaveSelectedGame(self);
	OpenTriggerManager:saveOpenStates();
end;

---------- ONCREATE FUNCTIONS ----------

---------- NEW FUNCTIONS ----------

---------- LOAD FUNCTIONS ----------
function OpenTrigger:load(xmlFile)
	self.canDrawOpen = false;
end;

---------- LOADMAP FUNCTIONS ----------
function OpenTriggerManager:loadMap(name)
	self.OTMmapName = name;
	self.filePath = nil;
	self.triggersLoaded = false;
	if self.baseDirectory ~= nil then
		self.filePath = self.baseDirectory;
	elseif g_currentModDirectory ~= nil then
		self.filePath = g_currentModDirectory;
	elseif g_currentMission.missionInfo.baseDirectory ~= nil then
		self.filePath = g_currentMission.missionInfo.baseDirectory;
	elseif g_currentMission.baseDirectory ~= nil then
		self.filePath = g_currentMission.baseDirectory;
	end;
	g_currentMission.hudTriggerOverlay = nil;
	if self.filePath ~= nil then
		g_currentMission.hudTriggerOverlay = Overlay:new("hudTriggerOverlay", Utils.getFilename("scripts/OpenDoorTrigger_hud.dds", self.filePath), 0.939, 0.28, 0.055, 0.073333333333);
	end;
	if g_currentMission ~= nil then
		if g_currentMission.barrierTriggers == nil then
			g_currentMission.barrierTriggers = {};
		end;
	end;
	g_currentMission.checkOpenStates = 0;
	self.oldNumTriggers = 0;
	self.syncGates = 100;
end;

---------- DELETE FUNCTIONS ----------

---------- DELETEMAP FUNCTIONS ----------
function OpenTriggerManager:deleteMap()
end;

---------- UPDATE FUNCTIONS ----------
function OpenTriggerManager:update(dt)
	if (not self.triggersLoaded) then
		if g_currentMission.barrierTriggers ~= nil and table.getn(g_currentMission.barrierTriggers) > 0 then
			if table.getn(g_currentMission.barrierTriggers) > self.oldNumTriggers then
				self.oldNumTriggers = table.getn(g_currentMission.barrierTriggers);
				self:loadOpenStates();
			end;
		end;
	else
		if g_currentMission.missionDynamicInfo.isMultiplayer then
			if not g_server then
				if self.syncGates == 0 then
					if g_currentMission.barrierTriggers ~= nil and table.getn(g_currentMission.barrierTriggers) > 0 then
						for i=1, table.getn(g_currentMission.barrierTriggers) do
							if g_currentMission.barrierTriggers[i] ~= nil then
								if g_currentMission.barrierTriggers[i].manualOpen then
									g_client:getServerConnection():sendEvent(OpenTriggerRequestEvent:new(g_currentMission.barrierTriggers[i].mpName));
								end;
							end;
						end;
					end;
				else
					self.syncGates = self.syncGates - 1;
				end;
			end;
		end;
	end;
	if self.isServer or g_server ~= nil then
		local usersActive = {};
		for k,v in pairs(g_currentMission.players) do
			table.insert(usersActive, v);
		end;
		if self.userCountActive ~= #usersActive then
			self.userCountActive = #usersActive;
			if g_currentMission.barrierTriggers ~= nil and table.getn(g_currentMission.barrierTriggers) > 0 then
				for i=1, table.getn(g_currentMission.barrierTriggers) do
					if g_currentMission.barrierTriggers[i] ~= nil then
						if g_currentMission.barrierTriggers[i].manualOpen then
							g_server:broadcastEvent(OpenTriggerManagerEvent:new(g_currentMission.barrierTriggers[i].mpName,g_currentMission.barrierTriggers[i].canBeOpen));
						end;
					end;
				end;
			end;
		end;
	end;
end;

---------- TRIGGER CALLBACK FUNCTIONS ----------

---------- OTHER FUNCTIONS ----------
function OpenTriggerManager:setOpenState(triggerPos, mpName, canBeOpen)
	if triggerPos ~= nil and triggerPos > -1 then
		g_currentMission.barrierTriggers[triggerPos]:setOpenState(canBeOpen);
		if g_server == nil then
			g_client:getServerConnection():sendEvent(OpenTriggerManagerEvent:new(mpName, canBeOpen));
		else
			g_server:broadcastEvent(OpenTriggerManagerEvent:new(mpName, canBeOpen));
		end;
	end;
end;
function OpenTriggerManager:setRandomState(mpName, randomActive, randomStart, randomEnd, randomActiveText)
	g_server:broadcastEvent(OpenTriggerManagerRandomEvent:new(mpName, randomActive, randomStart, randomEnd, randomActiveText));
end;

---------- DRAW FUNCTIONS ----------
function OpenTriggerManager:draw()
end;
function OpenTrigger:draw()
	if self.isClient then
		if self.canDrawOpen == true then
			if self.isControlled then
				g_currentMission:addHelpButtonText(g_i18n:getText("OPEN_GATE"), InputBinding.OPEN_GATE);
				if g_currentMission.hudTriggerOverlay ~= nil then
					g_currentMission.hudTriggerOverlay:render();
				end;
			end;
		end;
	end;
end;
function OpenTrigger:drawPlayer()
	if self.isClient then
		if self.canDrawOpen == true then
			if self == g_currentMission.player then
				g_currentMission:addHelpButtonText(g_i18n:getText("OPEN_GATE"), InputBinding.OPEN_GATE);
				if g_currentMission.hudTriggerOverlay ~= nil then
					g_currentMission.hudTriggerOverlay:render();
				end;
			end;
		end;
	end;
end;

---------- SPECIFIC FUNCTIONS ----------
function OpenTriggerManager:getFilesCallback(filename)
	if filename == "OpenTrigger.xml" then
		self.fileFound = true;
	end;
end;
function OpenTriggerManager:saveOpenStates()
	local savegame = g_currentMission.missionInfo.savegameDirectory;
	if savegame ~= nil and ((g_server and g_currentMission.missionDynamicInfo.isMultiplayer) or (not g_currentMission.missionDynamicInfo.isMultiplayer)) then
		local xmlFile = createXMLFile("BarrierExtended", self.savegameFilename, "BarrierExtended");
		if xmlFile ~= nil then
			for _,barrierTrigger in pairs(g_currentMission.barrierTriggers) do
				if barrierTrigger.saveName ~= nil then
					local name = "BarrierExtended."..barrierTrigger.saveName;
					setXMLBool(xmlFile, name.."#isValid",barrierTrigger.manualOpen);
					setXMLInt(xmlFile, name.."#canBeOpen",barrierTrigger.canBeOpen);
				end;
			end;
		end;
		saveXMLFile(xmlFile);
		delete(xmlFile);
	end;
end;
function OpenTriggerManager:loadOpenStates()
	local savegame = g_currentMission.missionInfo.savegameDirectory;
	self.filename = savegame.."/OpenTrigger.xml";
	self.fileFound = false;
	getFiles(savegame, "getFilesCallback", self);
	if savegame ~= nil and self.fileFound then
		local xmlFile = loadXMLFile("BarrierExtended", self.savegameFilename);
		if xmlFile ~= nil and g_currentMission.barrierTriggers ~= nil then
			for _,barrierTrigger in pairs(g_currentMission.barrierTriggers) do
				if barrierTrigger.saveName ~= nil then
					local name = "BarrierExtended."..barrierTrigger.saveName;
					local sN = getXMLBool(xmlFile, name.."#isValid");
					if sN ~= nil and sN == true then
						barrierTrigger:setOpenState(Utils.getNoNil(getXMLInt(xmlFile, name.."#canBeOpen"),1));
					end;
				end;
			end;
			delete(xmlFile);
			self.triggersLoaded = true;
		end;
	end;
end;

---------- ALL OTHER FUNCTIONS ----------
function OpenTriggerManager:mouseEvent(posX, posY, isDown, isUp, button)
end;
function OpenTriggerManager:keyEvent(unicode, sym, modifier, isDown)
end;

---------- NETWORK FUNCTIONS ----------

---------- EVENT FUNCTIONS COMPLETE ----------
function OpenTriggerRequestEvent:emptyNew()
    local self = Event:new(OpenTriggerRequestEvent_mt);
    return self;
end;
function OpenTriggerRequestEvent:new(mpName)
    local self = OpenTriggerRequestEvent:emptyNew()
    self.mpName = mpName;
    return self;
end;
function OpenTriggerRequestEvent:readStream(streamId, connection)
    self.mpName = streamReadInt32(streamId);
    self:run(connection);
end;
function OpenTriggerRequestEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, self.mpName);
end;
function OpenTriggerRequestEvent:run(connection)
	if connection:getIsServer() then
		if g_currentMission.barrierTriggers ~= nil and table.getn(g_currentMission.barrierTriggers) > 0 then
			for i=1, table.getn(g_currentMission.barrierTriggers) do
				if g_currentMission.barrierTriggers[i] ~= nil and self.mpName ~= nil and g_currentMission.barrierTriggers[i].mpName == self.mpName then
					g_server:broadcastEvent(OpenTriggerManagerEvent:new(self.mpName, g_currentMission.barrierTriggers[i].canBeOpen));
				end;
			end;
		end;
	end;
end;
function OpenTriggerManagerRandomEvent:emptyNew()
    local self = Event:new(OpenTriggerManagerRandomEvent_mt);
	self.className = "OpenTrigger";
    return self;
end;
function OpenTriggerManagerRandomEvent:new(mpName, randomActive, randomStart, randomEnd, randomActiveText)
	local self = OpenTriggerManagerRandomEvent:emptyNew();
	self.mpName = mpName;
	self.randomActive = randomActive;
	self.randomStart = randomStart;
	self.randomEnd = randomEnd;
	self.randomActiveText = randomActiveText;
	return self;
end;
function OpenTriggerManagerRandomEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, self.mpName);
    streamWriteBool(streamId, self.randomActive);
    streamWriteFloat32(streamId, self.randomStart);
    streamWriteFloat32(streamId, self.randomEnd);
    streamWriteString(streamId, self.randomActiveText);
end;
function OpenTriggerManagerRandomEvent:readStream(streamId, connection)
    self.mpName = streamReadInt32(streamId);
    self.randomActive = streamReadBool(streamId);
    self.randomStart = streamReadFloat32(streamId);
    self.randomEnd = streamReadFloat32(streamId);
    self.randomActiveText = streamReadString(streamId);
    self:run(connection);
end;
function OpenTriggerManagerRandomEvent:run(connection)
	if g_currentMission.barrierTriggers ~= nil and table.getn(g_currentMission.barrierTriggers) > 0 then
		for i=1, table.getn(g_currentMission.barrierTriggers) do
			if g_currentMission.barrierTriggers[i].mpName == self.mpName then
				g_currentMission.barrierTriggers[i].randomActive = self.randomActive;
				g_currentMission.barrierTriggers[i].randomStart = tonumber(self.randomStart);
				g_currentMission.barrierTriggers[i].randomEnd = tonumber(self.randomEnd);
				g_currentMission.barrierTriggers[i].randomActiveText = self.randomActiveText;
			end;
		end;
	end;
end;
function OpenTriggerManagerEvent:emptyNew()
    local self = Event:new(OpenTriggerManagerEvent_mt);
	self.className = "OpenTrigger";
    return self;
end;
function OpenTriggerManagerEvent:new(mpName, canBeOpen)
	local self = OpenTriggerManagerEvent:emptyNew();
	self.mpName = mpName;
	self.canBeOpen = canBeOpen;
	return self;
end;
function OpenTriggerManagerEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, self.mpName);
    streamWriteInt8(streamId, self.canBeOpen);
end;
function OpenTriggerManagerEvent:readStream(streamId, connection)
    self.mpName = streamReadInt32(streamId);
    self.canBeOpen = streamReadInt8(streamId);
    self:run(connection);
end;
function OpenTriggerManagerEvent:run(connection)
	if g_currentMission.barrierTriggers ~= nil and table.getn(g_currentMission.barrierTriggers) > 0 then
		for i=1, table.getn(g_currentMission.barrierTriggers) do
			if g_currentMission.barrierTriggers[i].mpName == self.mpName then
				g_currentMission.barrierTriggers[i]:setOpenState(self.canBeOpen);
			end;
		end;
	end;
	if not connection:getIsServer() then
		g_server:broadcastEvent(OpenTriggerManagerEvent:new(self.mpName, self.canBeOpen));
	end;
end;

---------- APPEND FUNCTIONS PROCEDURES ----------
Steerable.load = Utils.appendedFunction(Steerable.load, OpenTrigger.load);
Steerable.draw = Utils.appendedFunction(Steerable.draw, OpenTrigger.draw);
Player.load = Utils.appendedFunction(Player.load, OpenTrigger.load);
Player.draw = Utils.appendedFunction(Player.draw, OpenTrigger.drawPlayer);

---------- CREATE AND LISTENER CALLS ----------
addModEventListener(OpenTriggerManager);
