--[[
	Implementation
]]


local singleton = nil

local GameStageHandler = {}
GameStageHandler.__index = GameStageHandler

function GameStageHandler.new()
	local self = setmetatable({
		currentStage = nil,
		currentStageClassName = nil,
		timeStageStarted = nil,
	}, GameStageHandler)

	self.gameStageChanged = Signal.new()

	getGameStage.OnServerInvoke = function(player)
		return self.currentStageClassName
	end

	singleton = self

	return self
end

function GameStageHandler.getInstance()
	return singleton
end

function GameStageHandler:nextStage()
	-- Destroy the previous stage
	self.currentStage:destroy()

	-- Figure out what the next stage will be
	local nextStageName = nil
	for index, value in ipairs(Conf.stages) do
		if value == self.currentStageClassName then
			nextStageName = Conf.stages[index + 1]
			break
		end
	end

	self:_initializeStage(nextStageName)
end

function GameStageHandler:start()
	self:_initializeStage(Conf.stages[1])
end

function GameStageHandler:destroy()
	self.gameStageChanged = nil

	if self.currentStage then
		self.currentStage:destroy()
	end
end

function GameStageHandler:_initializeStage(stageName)
	if not stageName then
		return
	end

	print(string.format("Initilizing Stage: %s", stageName))

	-- Initialize the next stage, if there is one
	local nextStage = stageFolder:FindFirstChild(stageName)

	assert(nextStage, string.format("Failed to initialize stage \"%s\", stage does not exist", stageName))

	self.currentStage = require(nextStage).new(self)
	self.currentStageClassName = stageName
	self.timeStageStarted = tick()

	self.currentStage:initialize()

	-- Fire local event
	self.gameStageChanged:fire(stageName)

	-- Notify clients of the stage change
	gameStageChanged:FireAllClients(stageName)
	Broadcast.fireRemote("GAME_STAGE_CHANGE", stageName)
end

return GameStageHandler
