-- Keeps track of the style/mode selected in ScreenSelectPlayMode.
-- TODO: to env or not to env?
THEME_EKSDGameMode = "Freestyle"
-- default (Mimic/Mirrored) - Default background video display.
-- stan_default (Performance/Standard) - Default background video display, but ParaPara charts will appear mirrored from their respective videos.
-- parapara (Mimic/Mirrored) - Always display the ParaPara BG video. Player motions are symmetrical with those that appear on screen.
-- stan_parapara (Performance/Standard) - Always display the ParaPara BG video. Player motions will appear mirrored from those in the video.
-- arcade (freestyle BG) - Always display the Freestyle BG video, if available.
-- static (song BG only) - Only the song's background graphic will be displayed in gameplay.
THEME_EKSDBGVidMode = "default"

-- Basic check for force-mirroring the background video.
function CheckShouldMirrorBG(ignoreCurDif)
	if not GAMESTATE:GetCurrentSteps(GAMESTATE:GetMasterPlayerNumber()) then return false end --failsafe
	local check = string.find(THEME_EKSDBGVidMode, "stan_")
	-- Never mirror freestyle BGs.
	if ignoreCurDif then
		return check ~= nil
	end
	return check ~= nil and Enum.Compare(Difficulty, GAMESTATE:GetEasiestStepsDifficulty(), Difficulty[2]) <= 0
end

-- GameCommand-friendly functions, for the metrics.
function SwitchToParapara()
	THEME_EKSDGameMode = "Parapara"
	THEME:ReloadMetrics()
end

function SwitchToFreestyle()
	THEME_EKSDGameMode = "Freestyle"
	THEME:ReloadMetrics()
end

function CurGameModeString()
	return GAMESTATE:IsCourseMode() and THEME:GetString("Misc", "ModeNonstop") or THEME:GetString("Misc", "Mode" .. THEME_EKSDGameMode)
end

-- todo: look into this.
function GetAvailableDifficulties()
	return THEME_EKSDGameMode == "Parapara" and "beginner,easy" or "beginner,easy,medium,hard,challenge"
	--return "beginner,easy"
end

-- Experimental for now. Toggle for whether or not ScreenGameplay should use the alternate "neon" graphics.
function ShouldUseEXGraphics()
	local song = GAMESTATE:GetCurrentSong()
	if not song then return false end
	
	if GAMESTATE:GetCurrentGame():GetName() == "para" then
		local UnreasonableGenres = {"hardstyle", "hardcore"}
		for i, genre in ipairs(UnreasonableGenres) do
			if string.lower(song:GetGenre()) == genre then return true end
		end
	end
	
	return false
end

function UIScaling()
	local dispHeight = PREFSMAN:GetPreference("DisplayHeight")
	local useSmallerUI = dispHeight > 599
	return useSmallerUI and scale(dispHeight, 600, 800, 0.75, 0.9) or 1
end

-- I didn't learn from MusicWheelItem sort, and once again weird hard-coded string handling returns!
-- Colors moved here because I wanna keep this handling grouped together
local ParaSegmentColors = {
	Fallback = LocalBlueColor(0.5),
	["leadin"] = LocalBlueColor(0.9),	-- blu
	["intro"] = NeonColor.Blue,	-- pure blue
	["amelo"] = NeonColor.Green,	-- pure green
	["bmelo"] = NeonColor.Yellow,	-- yallow
	["cmelo"] = color("#99FF00"),	-- Lime?!
	["dmelo"] = color("#CCFF00"),	-- D:
	["sabi"] = NeonColor.Pink,	-- magenta
	["freestyle"] = NeonColor.Red, -- pure red
	["bridge"] = LocalGoldColor(1), -- ???
	["leadout"] = LocalBlueColor(0.9), -- same as lead-in lol
	["songstart"] = LocalBlueColor(0.25), -- fallback but darker
	["songend"] = LocalBlueColor(0.25), -- fallback but darker
}

-- Secondary table.
local NonParaSegmentEqu = {
	{"preverse", "intro"},
	{"verse", "amelo"},
	{"prechorus", "bmelo"},
	{"postchorus", "intro"},
	{"chorus", "sabi"},
	{"riff", "cmelo"},
	{"hook", "cmelo"},
	{"buildup", "bridge"}, 
	{"bridge", "bridge"}, --LUL
	{"outro", "leadout"}
}

function SongLabelColor(str)
	-- Squish down a given string, and try to color it based on the ParaSegmentColors table.
	local theString = string.lower(string.gsub(str, "%A", ""))
	if ParaSegmentColors[theString] then
		return ParaSegmentColors[theString]
	end
	-- Failing that, scour through NonParaSegmentEqu for equivalents.
	for i, str in ipairs(NonParaSegmentEqu) do
		if string.find(theString, str[1]) then return ParaSegmentColors[str[2]] end
	end
	return ParaSegmentColors.Fallback
end
-- this might seem redundant but, I want the song label strings to be translatable
-- especially for languages that don't use the roman alphabet ok
function SongLabelString(str, inGameplay)
	local theString = string.lower(string.gsub(str, "%A", ""))
	-- If this label has an assigned color as seen above, assume it has a corresponding string.
	if ParaSegmentColors[theString] then
		return (inGameplay and theString == "freestyle") and THEME:GetString("Misc", "freestyle_alt") or THEME:GetString("Misc", theString)
	end
	return str
end

function AnyPlayerHasSplitTiming()
	if not GAMESTATE:GetCurrentSong() then return false end
	for pn in ivalues(GAMESTATE:GetHumanPlayers()) do
		if GAMESTATE:GetCurrentSteps(pn) and GAMESTATE:GetCurrentSong():IsStepsUsingDifferentTiming(GAMESTATE:GetCurrentSteps(pn)) then return true end
	end
	return false
end

---
-- Currently unused "secrets" start here.
-- Although, since you're reading this, they're not really that secret anymore, are they?
---
local ShinyDates = {
	["21/09"] = "ppp1"
}

function MusicSetHasTrack(set, track)
	return FILEMAN:DoesFileExist("Appearance/Themes/"..THEME:GetCurThemeName().."/Sounds/music-"..set.."/"..track.." (loop).ogg")
end

function GetMusicTrack(set, track)
	local actual = MusicSetHasTrack(set, track) and set or "default"
	return THEME:GetPathS("", "music-" .. actual .. "/" .. track)
end

function GetMusicSetToUse()
	--local todayString = DayOfMonth() .. "/" .. tostring(MonthOfYear() + 1)
	--if ShinyDates[todayString] then return ShinyDates[todayString] end
	return "default"
end
