Text GetId() {
	return "Nsgr_TwitchPlaysTimer";
}

CUILayer::EUILayerType GetType() {
	return CUILayer::EUILayerType::Normal;
}

Text GetManialink() {
	return """<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
	<manialink version="3" name="{{{GetId()}}}">
	<label size="60 10" pos="0 -80" halign="center" valign="center" textsize="10" text="--:--.--" id="label-chrono"  textfont="RajdhaniMono" textcolor="FFF"/>
	<script><!--
		#Include "TextLib" as TL

		CSmPlayer GetOwner() {
			if (GUIPlayer != Null) return GUIPlayer;
			return InputPlayer;
		}

		main() {
			// Init
			declare CMlLabel Label_Chrono;

			declare netread Integer Net_TwitchPlaysRoundStart for Teams[0] = 0;
			declare netread Integer Net_TwitchPlaysTotalOffset for UI = 0;
			declare netread Boolean Net_TwitchPlaysTimerRunning for UI = True;
			declare netread Boolean Net_TwitchPlaysTimerIsFinal for Teams[0] = False;

			declare netread Boolean Net_TwitchPlaysTimerShowRaceTime for Teams[0] = False;

			declare Boolean IsFinal;

			// Start
			IsFinal = False;

			Label_Chrono <=> (Page.GetFirstChild("label-chrono") as CMlLabel);

			while (True) {
				yield;

				//Loop
				declare Owner <=> GetOwner();
				if (Net_TwitchPlaysTimerShowRaceTime && Owner != Null) {
					Label_Chrono.Value = TL::TimeToText(Owner.CurrentRaceTime, True, True);
					continue;
				}

				if (IsFinal != Net_TwitchPlaysTimerIsFinal) {
					AnimMgr.Flush(Label_Chrono);
					if (Net_TwitchPlaysTimerIsFinal) {
						AnimMgr.Add(Label_Chrono, "<anim pos=\"0 0\" scale=\"3\" />", 1000, CAnimManager::EAnimManagerEasing::QuadInOut);
					} else {
						AnimMgr.Add(Label_Chrono, "<anim pos=\"0 -80\" scale=\"1\" />", 1000, CAnimManager::EAnimManagerEasing::QuadInOut);
					}
					IsFinal = !IsFinal;
				}
				if (Net_TwitchPlaysTimerRunning && GameTime > Net_TwitchPlaysRoundStart) {
					Label_Chrono.Value = TL::TimeToText(Net_TwitchPlaysTotalOffset + (GameTime - Net_TwitchPlaysRoundStart), True);
				} else {
					Label_Chrono.Value = TL::TimeToText(Net_TwitchPlaysTotalOffset, True, True);
				}
			}
		}
	--></script>
	</manialink>
	""";
}

// Global: When this round started
Void SetRoundStart(Integer _RoundStart) {
	declare netwrite Integer Net_TwitchPlaysRoundStart for Teams[0];
	Net_TwitchPlaysRoundStart = _RoundStart;
}

Integer GetRoundStart() {
	declare netwrite Integer Net_TwitchPlaysRoundStart for Teams[0];
	return Net_TwitchPlaysRoundStart;
}

// Personal: Timer Offset
Void SetTimerOffset(CSmPlayer _Player, Integer _Offset) {
	declare UI <=> UIManager.GetUI(_Player);
	if (UI == Null) return;
	declare netwrite Integer Net_TwitchPlaysTotalOffset for UI;
	Net_TwitchPlaysTotalOffset = _Offset;
}

Integer GetTimerOffset(CSmPlayer _Player) {
	declare UI <=> UIManager.GetUI(_Player);
	if (UI == Null) return -1;
	declare netwrite Integer Net_TwitchPlaysTotalOffset for UI;
	return Net_TwitchPlaysTotalOffset;
}

// Global Timer offset (for new "match")
Void SetTimerOffsetAll(Integer _Offset) {
	foreach (Player in AllPlayers) {
		SetTimerOffset(Player, _Offset);
	}
}

// Personal: Is Timer running?
Void SetTimerRunning(CSmPlayer _Player, Boolean _Running) {
	declare UI <=> UIManager.GetUI(_Player);
	if (UI == Null) return;
	declare netwrite Boolean Net_TwitchPlaysTimerRunning for UI;
	Net_TwitchPlaysTimerRunning = _Running;
}

Void SetTimerRunningAll(Boolean _Running) {
	foreach (Player in AllPlayers) {
		SetTimerRunning(Player, _Running);
	}
}

// RMC: Timer mode
Void SetTimerShowRaceTime(Boolean _DisplayCurrentRaceTime) {
	declare netwrite Boolean Net_TwitchPlaysTimerShowRaceTime for Teams[0];
	Net_TwitchPlaysTimerShowRaceTime = _DisplayCurrentRaceTime;
}

// Global: Timer big
Void SetTimerIsFinal(Boolean _IsFinal) {
	declare netwrite Boolean Net_TwitchPlaysTimerIsFinal for Teams[0];
	Net_TwitchPlaysTimerIsFinal = _IsFinal;
}

Void StartMatch() {
	SetTimerOffsetAll(0);
	SetTimerIsFinal(False);
}

Void StartRound(Integer _StartTime) {
	SetRoundStart(_StartTime);
	SetTimerRunningAll(True);
}

Void Finish(CSmPlayer _Player) {
	SetTimerOffset(_Player, GetTimerOffset(_Player) + (Now - GetRoundStart()));
	SetTimerRunning(_Player, False);
}

Void EndRound() {
	SetTimerRunningAll(False);
}