local PopularColors = {
	Gold	= HSV(48,0.9,0.95),	 -- was color("1,0.95,0,1")
	Silver	= HSV(0,0,0.75),	 -- was color("0.95,0.9,0.9,1")
	Bronze	= HSV(32,0.75,0.85), -- was color("0.95,0.5,0,1")
	Normal	= HSV(0,0,1)		 -- was color("#FFFFFF")
};

local t = Def.ActorFrame{
	InitCommand=cmd(fov,90);

	LoadActor( THEME:GetPathB("","_frame 3x3"), "_rounded blackinset transparent normal", 256, 24)..{
		Name="SongItemBG";
		SetMessageCommand=function(self,params)
			local song = params.Song;
			if not song then return end;

			-- most popular songs
			if GAMESTATE:GetSortOrder() == 'SortOrder_Popularity' then
				local colorName = "Normal";
				-- gold, silver, bronze
				if params.Index == 0 then
					colorName = "Gold";
				elseif params.Index == 1 then
					colorName = "Silver";
				elseif params.Index == 2 then
					colorName = "Bronze";
				end;
				self:diffuse( PopularColors[colorName] );
			-- any other sort
			else
				local hue = 0;
				local longHue = 0;
				local maraHue = 240;
				local modifierSat = 0.35; -- was 0.13

				if song:IsLong() then
					hue = longHue;
				elseif song:IsMarathon() then
					hue = maraHue;
				else -- normal length
					modifierSat = 0;
				end;

				self:diffuse( HSV(hue, modifierSat, 1) );
			end;
		end;
	};

	Def.ActorFrame{
		InitCommand=cmd(x,-125);

		-- todo: redo this graphic?
		LoadActor( "_stages frame" )..{
			SetMessageCommand=function(self,params)
				local song = params.Song;
				if not song then
					self:visible(false);
					return;
				end;

				-- most popular songs
				if GAMESTATE:GetSortOrder() == 'SortOrder_Popularity' then
					if params.Index > 2 then
						self:visible(false);
						return;
					end;
					local colorName = "Normal";
					-- gold, silver, bronze
					if params.Index == 0 then
						colorName = "Gold";
					elseif params.Index == 1 then
						colorName = "Silver";
					elseif params.Index == 2 then
						colorName = "Bronze";
					end;
					self:diffuse( PopularColors[colorName] );
				-- any other sort
				else
					local hue = 0;
					local longHue = 0;
					local maraHue = 240;
					local modifierSat = 0.35; -- was 0.13
					local alpha = 1;

					if song:IsLong() then
						hue = longHue;
						alpha = 1;
					elseif song:IsMarathon() then
						hue = maraHue;
						alpha = 1;
					else -- normal length
						modifierSat = 0;
						alpha = 0;
					end;

					self:diffuse( HSVA(hue, modifierSat, 1, alpha) );
				end;
				self:visible(true);
			end;
		};
		Def.Sprite{
			SetMessageCommand=function(self,params)
				local song = params.Song;
				if not song then
					self:Load( THEME:GetPathG("","_blank") );
					return;
				end;

				if GAMESTATE:GetSortOrder() ~= 'SortOrder_Popularity' then
					local numStages = 1;
					if song:IsLong() then numStages = 2;
					elseif song:IsMarathon() then numStages = 3;
					else
						self:Load( THEME:GetPathG("","_blank") );
						self:stopeffect();
					end;

					if numStages ~= 1 then
						self:Load( THEME:GetPathG("MusicWheelItem Song","NormalPart/_stages ".. numStages) );
						self:glowshift();
						self:effectcolor1( color("1,1,1,0.1") );
						self:effectcolor2( color("1,0.9,0.8,0.35") );
					end;
				end;
			end;
		};
	};

--[[
	-- this introduces unwanted lag:
	LoadFont("_blaster 16px")..{
		InitCommand=cmd(x,-(SCREEN_CENTER_X*0.3725);y,-12;horizalign,right;shadowlength,0;visible,false;);
		SetCommand=function(self,params)
			local song = params.Song;
			if not song then return end;

			if GAMESTATE:GetSortOrder() == 'SortOrder_Popularity' and params.Index < 3 then
				self:settext( string.format("%02i", params.Index + 1) );

				local colorName = "Normal";
				-- gold, silver, bronze
				if params.Index == 0 then
					colorName = "Gold";
				elseif params.Index == 1 then
					colorName = "Silver";
				elseif params.Index == 2 then
					colorName = "Bronze";
				end;
				self:diffuse( PopularColors[colorName] );
				self:strokecolor( color("0.25,0.25,0.25,1") );

				-- diffuse the top edge of any high ranking song.
				if colorName ~= "Normal" then
					self:diffusetopedge( color("1,1,1,0.9") );
				end;

				self:visible(true);
			else
				self:visible(false);
				return;
			end;
		end;
	};
--]]
};

-- this section is probably not working in non-dance modes anyways
local u = Def.ActorFrame{};

local positions = {
	-14, -- beginner
	-7,  -- easy
	0,   -- medium
	7,   -- hard
	15,  -- expert
	31,  -- edit, which shouldn't be shown
};

for idx, diff in pairs(Difficulty) do -- 0, Difficulty_Beginner
	-- hack to hide edit
	if idx < 6 and not GAMESTATE:IsCourseMode() then
		u[#u+1] = LoadActor( "_DifficultyDisplay" ) .. {
			InitCommand=cmd(x,128;playcommand,"SetMessage");
			ShowCommand=cmd(visible,true);
			HideCommand=cmd(visible,false);
			BeginCommand=function(self)
				self:y(positions[idx]);
				self:diffuse( DifficultyColor(diff) );
			end;

			SetMessageCommand=function(self,params)
				local song = params.Song;
				-- if there isn't a song, don't bother.
				if not song then return end;

				local st = GAMESTATE:GetCurrentStyle():GetStepsType();
				local bHasStepsTypeAndDifficulty =
					song and song:HasStepsTypeAndDifficulty( st, diff );

				self:playcommand( bHasStepsTypeAndDifficulty and "Show" or "Hide" );
			end;
		};
	end;
end;

t[#t+1] = u;

return t;