-- Gameplay overlay.

-- PlayerOptions(pn)
-- Returns a text actor with the specified player options.
local function PlayerOptions(pn)
	return AutoText("frutiger")..{
		InitCommand=cmd(zoom,0.6;shadowlength,1;maxwidth,SCREEN_WIDTH/2;player,pn;NoStroke);
		BeginCommand=function(self)
			self:horizalign( (pn == PLAYER_1) and left or right );

			if GAMESTATE:IsSideJoined(pn) or GAMESTATE:IsPlayerEnabled(pn) or GAMESTATE:IsDemonstration() then
				self:visible(true);
			else self:visible(false);
			end;

			if GetUserPref("DisplayModsOption") == nil then
				-- write fallback
				SetUserPref("DisplayModsOption",true);
			end;

			self:visible( GetUserPrefB("DisplayModsOption") );
		end;
		OnCommand=function(self)
			if not self:GetVisible() then return; end;
			local proxy = SCREENMAN:GetTopScreen():GetChild( 'PlayerOptions' .. pname(pn) );
			if proxy then
				local modlist = proxy:GetText();
				self:settext(modlist);
			else
				self:settext("");
			end;
		end;
	};
end;

-- Difficulty(pn)
-- Returns a text actor with the specified difficulty.
-- xxx: update on course song change.
-- unc: shows for P2 still?
local function Difficulty(pn)
	local NumPlayers = GAMESTATE:GetNumPlayersEnabled();
	local NumSides = GAMESTATE:GetNumSidesJoined();
	local IsDoubles = (NumPlayers == 1 and NumSides == 2);

	local r = Def.ActorFrame{};

	r[#r+1] = Def.Quad{
		InitCommand=function(self)
			local fadeAmt = 0.25;

			if pn == PLAYER_1 then
				self:faderight(fadeAmt);
			else
				self:fadeleft(fadeAmt);
			end;

			self:addx( (pn == PLAYER_1) and -4 or 4 );
			self:addy(1);
			self:horizalign( (pn == PLAYER_1) and left or right );

			self:zoomto(96,18);
			if pn then
				if GAMESTATE:IsCourseMode() then
					local pm = GAMESTATE:GetPlayMode();
					if pm == "PlayMode_Nonstop" or pm == "PlayMode_Endless" or pm == "PlayMode_Oni" then
						if GAMESTATE:GetCurrentTrail(pn) then
							self:diffuse( DifficultyDarkColor( GAMESTATE:GetCurrentTrail(pn):GetDifficulty() ) );
						end;
					else
						if GAMESTATE:GetCurrentSteps(pn) then
							self:diffuse( DifficultyDarkColor( GAMESTATE:GetCurrentSteps(pn):GetDifficulty() ) );
						end;
					end;
				else
					if GAMESTATE:GetCurrentSteps(pn) then
						self:diffuse( DifficultyDarkColor( GAMESTATE:GetCurrentSteps(pn):GetDifficulty() ) );
					end;
				end;
			end;
			self:diffusealpha(0.5);
		end;
		BeginCommand=function(self)
			-- case 1: always show in demonstration
			if GAMESTATE:IsDemonstration() then self:visible(true); return; end;
			-- case 2: real gameplay.
			if IsDoubles then
				-- doubles
				if GAMESTATE:IsDemonstration() and pn == PLAYER_2 then
					self:visible(false);
				end;

				if pn ~= GAMESTATE:GetMasterPlayerNumber() then
					self:visible(false);
				end;
			else
				-- single
				self:visible( GAMESTATE:IsHumanPlayer(pn) and GAMESTATE:IsPlayerEnabled(pn) )
			end;
		end;
	};

	r[#r+1] = AutoText("frutiger")..{
		Name="Difficulty"..pn;
		InitCommand=cmd(zoom,0.6;shadowlength,1);
		BeginCommand=function(self)
			if GAMESTATE:IsSideJoined(pn) or GAMESTATE:IsPlayerEnabled(pn) then
				if IsDoubles then
					if GAMESTATE:IsDemonstration() then
						if pn == PLAYER_2 then self:visible(false); end;
					elseif GAMESTATE:GetMasterPlayerNumber() ~= pn then
						self:visible(false);
					end;
				end;
			else
				self:visible(false);
			end;

			self:horizalign( (pn == PLAYER_1) and left or right );
		end;
		OnCommand=function(self)
			if not self:GetVisible() then return; end;
			self:diffusetopedge( color("#FFFFFF") );
			self:queuecommand("Set");
		end;

		SetCommand=function(self)
			local diffString, steps, meter, difficulty;

			if GAMESTATE:IsCourseMode() then
				local course = GAMESTATE:GetCurrentCourse();
				local songEntry = course:GetCourseEntry( GAMESTATE:GetCourseSongIndex() );
				local song = songEntry:GetSong();

				steps = GAMESTATE:GetCurrentTrail(pn);
				if steps then
					difficulty = steps:GetDifficulty();
				end;
			else
				steps = GAMESTATE:GetCurrentSteps(pn);
				if steps then
					difficulty = steps:GetDifficulty();
				end;
			end;

			if steps then
				meter = steps:GetMeter();
				diffString = ( string.sub(difficulty,12) );

				self:diffuse( DifficultyColor(difficulty) );
				self:strokecolor( DifficultyDarkColor(difficulty) );

				self:settext(diffString .. " [" .. meter .."]");
			end;
		end;
		BeforeLoadingNextCourseSongMessageCommand=cmd(queuecommand,"Set");
		CurrentSongChangedMessageCommand=cmd(playcommand,"Set");

		CurrentStepsP1ChangedMessageCommand=function(self)
			if pn == PLAYER_1 then self:playcommand("Set"); end;
		end;
		CurrentTrailP1ChangedMessageCommand=function(self)
			if pn == PLAYER_1 then self:playcommand("Set"); end;
		end;
		CurrentStepsP2ChangedMessageCommand=function(self)
			if pn == PLAYER_2 then self:playcommand("Set"); end;
		end;
		CurrentTrailP2ChangedMessageCommand=function(self)
			if pn == PLAYER_2 then self:playcommand("Set"); end;
		end;
	};

	return r;
end;

-- uses Def.StepsDisplay, which I am not too much of a fan of :s
local function Difficulty2(pn)
	local function set(self, player)
		self:SetFromGameState( player );
	end

	local ret = Def.StepsDisplay{
		InitCommand=cmd(Load,"StepsDisplayMicro",GAMESTATE:GetPlayerState(pn););
		CurrentSongChangedMessageCommand=function(self) set(self, pn); end
	};

	if pn == PLAYER_1 then
		ret.CurrentStepsP1ChangedMessageCommand=function(self) set(self, pn); end;
		ret.CurrentTrailP1ChangedMessageCommand=function(self) set(self, pn); end;
	else
		ret.CurrentStepsP2ChangedMessageCommand=function(self) set(self, pn); end;
		ret.CurrentTrailP2ChangedMessageCommand=function(self) set(self, pn); end;
	end;

	return ret;
end;

-- SongNumber(pn)
-- Returns a text actor with the current song number.
local function SongNumber(pn)
	return AutoText("frutiger")..{
		InitCommand=cmd(shadowlength,1;NoStroke);
		BeginCommand=function(self)
			self:horizalign( pn == PLAYER_1 and right or left );

			-- [d1 v1.4] make the number a different color in endless
			local pm = GAMESTATE:GetPlayMode();
			if pm == "PlayMode_Endless" then
				self:diffuse( color("1,0.796,0.398,1") );	-- gold
			else
				self:diffuse( color("1,1,1,1") );			-- white
			end;

			self:visible( GAMESTATE:IsSideJoined(pn) or GAMESTATE:IsPlayerEnabled(pn) );
			self:playcommand("Update");
		end;

		UpdateCommand=function(self)
			if not GAMESTATE:IsCourseMode() then return; end;
			local proxy = SCREENMAN:GetTopScreen():GetChild('SongNumber'..pname(pn));
			if proxy then self:settext( proxy:GetText() ); end;
		end;

		CurrentSongChangedMessageCommand=cmd(playcommand,"Update");

		PlayerFailedMessageCommand=function(self,params)
			if params.PlayerNumber == pn then
				--[[
				-- UpdateCommand will always reset the count;
				-- This command only runs once.
				local stages;
				local proxy = SCREENMAN:GetTopScreen():GetChild('SongNumber'..pname(pn));
				if proxy then
					stages = proxy:GetText();
					self:settext( stages-1 );
				end;
				]]

				self:accelerate(1);
				self:diffuse( color("1,0,0,1") );
			end;
		end;
	};
end;

local t = Def.ActorFrame{
	-- cover (handles itself; draw before everything else.)
	LoadActor("cover")..{ InitCommand=cmd(draworder,90); };

	-- thanks shake
	Def.ActorFrame{
		Name="SongMeter";
		InitCommand=cmd(x,SCREEN_CENTER_X;y,SCREEN_TOP-10;draworder,95);
		OnCommand=cmd(decelerate,0.2;addy,15);
		OffCommand=cmd(accelerate,0.2;addy,-15);

		LoadActor( THEME:GetPathB("","_frame 3x1"), "_progress", SCREEN_WIDTH-8);

		Def.SongMeterDisplay {
			StreamWidth=SCREEN_WIDTH;
			Stream=Def.Quad{ InitCommand=cmd(zoomy,6;diffuse,color("#fff226");diffusebottomedge,color("#ffcc00")); };
			Tip=Def.Quad{ InitCommand=cmd(zoomto,2,6;diffusebottomedge,color("#cccccc")); };
		};
	};

	-- song info
	Def.ActorFrame{
		Name="SongInfoFrame";
		--InitCommand=cmd(x,SCREEN_CENTER_X;y,SCREEN_TOP+54;draworder,95;playcommand,"Update");
		InitCommand=cmd(x,SCREEN_CENTER_X;y,SCREEN_TOP+54;draworder,95;);

		AutoText("frutiger")..{
			Name="TheInfo";
			InitCommand=cmd(zoom,0.6;shadowlength,1;maxwidth,WideScale(SCREEN_WIDTH-32,SCREEN_WIDTH-72);NoStroke);

			BeginCommand=function(self)
				if GetUserPref("GameplayTitle") == nil then
					-- write fallback
					SetUserPref("GameplayTitle",true);
				end;

				self:visible( GetUserPrefB("GameplayTitle") );
			end;

			OffCommand=cmd(linear,0.2;diffusealpha,0);
			CurrentSongChangedMessageCommand=cmd(playcommand,"Update");
			UpdateCommand=function(self)
				local title;
				local artist;
				local song = GAMESTATE:GetCurrentSong();

				if song then
					if GAMESTATE:IsCourseMode() then
						title = GAMESTATE:GetCurrentCourse():GetDisplayFullTitle();
						artist = song:GetDisplayFullTitle();
					else
						title = song:GetDisplayFullTitle();
						artist = song:GetDisplayArtist();
					end;
				else
					title = "???";
					artist = "???";
				end;

				-- DVNO is four capital letters printed in gold.
				if title == "DVNO" then
					local attribDVNO = {
						Length = 4;
						Diffuse = color("1,0.8,0,1");
					};
					self:AddAttribute(0,attribDVNO);
				end;

				self:settext(title .." / ".. artist);
			end;
		};
	};

	--[[ begin p1 ]]
	-- p1 life
	LoadActor("lifemeter",PLAYER_1)..{
		InitCommand=cmd(x,SCREEN_CENTER_X*0.5;y,SCREEN_TOP+28;draworder,98);
		OffCommand=cmd(linear,1;x,SCREEN_WIDTH*-2);
	};
	-- p1 mods
	PlayerOptions(PLAYER_1)..{
		Name="P1Mods";
		InitCommand=cmd(x,SCREEN_LEFT+4;y,SCREEN_BOTTOM-42;draworder,98);
		OffCommand=cmd(linear,0.2;diffusealpha,0);
	};
	-- p1 difficulty
	Difficulty(PLAYER_1)..{
		Name="P1Difficulty";
		OnCommand=cmd(x,SCREEN_LEFT+4;y,SCREEN_TOP+54;draworder,98);
		OffCommand=cmd(linear,0.2;diffusealpha,0);
	};
	-- p1 song number
	SongNumber(PLAYER_1)..{
		Name="P1SongNum";
		InitCommand=cmd(x,SCREEN_CENTER_X-12;y,SCREEN_TOP+26;draworder,99);
		OffCommand=cmd(linear,0.2;diffusealpha,0);
	};
	--[[ end p1 ]]

	--[[ begin p2 ]]
	-- p2 life
	LoadActor("lifemeter",PLAYER_2)..{
		InitCommand=cmd(x,SCREEN_CENTER_X*1.5;y,SCREEN_TOP+28;draworder,98);
		OffCommand=cmd(linear,1;x,SCREEN_WIDTH*2);
	};
	-- p2 mods
	PlayerOptions(PLAYER_2)..{
		Name="P2Mods";
		InitCommand=cmd(x,SCREEN_RIGHT-4;y,SCREEN_BOTTOM-42;draworder,98);
		OffCommand=cmd(linear,0.2;diffusealpha,0);
	};
	-- p2 difficulty
	Difficulty(PLAYER_2)..{
		Name="P2Difficulty";
		OnCommand=cmd(x,SCREEN_RIGHT-4;y,SCREEN_TOP+54;draworder,98);
		OffCommand=cmd(linear,0.2;diffusealpha,0);
	};
	-- p2 song number
	SongNumber(PLAYER_2)..{
		Name="P2SongNum";
		InitCommand=cmd(x,SCREEN_CENTER_X+12;y,SCREEN_TOP+26;draworder,99);
		OffCommand=cmd(linear,0.2;diffusealpha,0);
	};
	--[[ end p2 ]]
};

for pn in ivalues(GAMESTATE:GetHumanPlayers()) do
	t[#t+1] = LoadActor("FullCombo", pn);
end;

t[#t+1] = LoadActor("BPMDisplay");

return t;
-- minimal is bliss. -aj, dubaiOne
-- yeah well why is this so long then -aj, moonlight