package Minigame
import public SeqWorker
import PlayerData
import SoundUtils
import ReviveManager
import initlater MinigameTeleporter

public constant minigames = new LinkedList<Minigame>()
constant minigames_live = new LinkedList<Minigame>()
public constant MAX_TIME = 1.75 * 60.
constant BEGIN_SOUND = new SoundDefinition(Sounds.arrangedTeamInvitation, false)

public function getNextMinigame() returns Minigame
	if minigames_live.size() == 0
		minigames_live.addAll(minigames)
		minigames_live.shuffle()

	return minigames_live.pop()

public abstract class Minigame
	timer tim
	timerdialog window

	function start()
		if tim == null
			tim = getTimer()
			tim..setData(this castTo int)
			..start(MAX_TIME, () -> onEndEvt())
			window = CreateTimerDialog(tim) //maximum time
			TimerDialogSetTitle(window, "Minigame")
			TimerDialogDisplay(window, true)
			changeRevMode(ReviveMode.WAIT_FOR_ALL)
			waitForListener = () ->
				for pd from escaperPlayers.staticItr()
					if pd.escaper != null
						pd.escaper.getCurrentRegion().hideRegion(pd.p)
					printTimedToPlayer("All Escapers have died!", 10, pd.p)
				doAfter(2., () -> reset())
				waitForListener = null
			for pd from escaperPlayers.staticItr()
				if pd.escaper != null
					if not pd.escaper.alive
						pd.escaper.revive()

					pd.escaper..setPos(getStartPosition().withZ(0))
					.setCurrentRegion()
					.revealRegion(pd.p)

					if not pd.escaper.camlock
						pd.p.panCamToTimed(pd.escaper.actor, 0)

					pd.p.select(pd.escaper.actor)

				printTimedToPlayer("Minigame started: " + getName(), 20, pd.p)

				if localPlayer == pd.p
					SetCameraBoundsToRect(getCamBounds())
				BEGIN_SOUND.playForPlayer(pd.p)

			onBegin()


	abstract function onBegin()

	abstract function onEnd()

	abstract function getStartPosition() returns vec2

	abstract function getGameRect() returns rect

	abstract function getCamBounds() returns rect

	abstract function getName() returns string

	function reset()
		if tim != null
			tim.release()
			tim = null
			DestroyTimerDialog(window)
			for pd from escaperPlayers.staticItr()
				if pd.escaper != null
					if not pd.escaper.alive
						pd.escaper.revive()
					pd.escaper.setPos(LOUNGE.toVec3())
					pd.escaper.setCurrentRegion()

				SetCameraBoundsToRectForPlayerBJ(pd.p, gg_rct_Region_023)

				doAfter(1.) ->
					if not pd.escaper.camlock
						pd.p.panCamToTimed(pd.escaper.actor, 0)
					pd.p.select(pd.escaper.actor)
				if not pd.escaper.camlock
					ResetToGameCameraForPlayer(pd.p, 1.)
				printTimedToPlayer("Minigame ended!", 10, pd.p)
			changeRevMode(ReviveMode.TIMED)
			onEnd()
			MINI_TP.reset()

	static function onEndEvt()
		(GetExpiredTimer().getData() castTo Minigame).reset()