local function TextBanner()
    -- of course this will be a part of a bigger Lua file, I just wanted to keep it
    -- simple. copy and paste for genre ( song:GetGenre() ) and artist ( song:GetDisplayArtist() ).
    -- also you can throw other shit like maxwidth in the init; I suggest that since
    -- you'll be generating these dynamically, unlike IIDX. may also want to throw
    -- in some horizaligns.

    local SmallRefresh = cmd(finishtweening;diffusealpha,0.5;glow,1,1,1,0.75;bounceend,0.25;diffusealpha,1;glow,1,1,1,0;);
    local LargeRefresh = cmd(finishtweening;glow,1,1,1,0.75;zoomy,1.15;decelerate,0.25;glow,1,1,1,0;zoomy,1;);

    local t = Def.ActorFrame {
        OffCommand=cmd(bouncebegin,0.3;zoom,0;);
        -- Genre
        LoadFont( "PreviewText","Genre" )..{
        Text="jews";
        InitCommand=cmd(playcommand,"Set";horizalign,right;shadowlength,0;maxwidth,SCREEN_WIDTH/2);
        SetCommand=function(self)
            local song = GAMESTATE:GetCurrentSong();
            if not song
                -- exit early, hide
                then self:visible(false);
                    
                return;
            end;
            -- otherwise, set it to the song title
            self:visible(true);
            self:settext( song:GetGenre() );
            self:playcommand("Animate");
        end;
        CurrentSongChangedMessageCommand=cmd(playcommand,"Set");
        AnimateCommand=SmallRefresh;
        };
        -- Main Title
        LoadFont( "PreviewText","Title" )..{
        Text="jews";
        InitCommand=cmd(playcommand,"Set";y,37;horizalign,right;shadowlength,0;maxwidth,SCREEN_WIDTH/2);
        SetCommand=function(self)
            local song = GAMESTATE:GetCurrentSong();
            if not song
                -- exit early, hide
                then self:visible(false);
                return;
            end;
            -- otherwise, set it to the song title
            self:visible(true);
            self:settext( song:GetDisplayMainTitle( ) );
            self:diffuse( color(1,1,1,0) );
            self:diffusebottomedge( SONGMAN:GetSongColor(song) );
            self:playcommand("Animate");
        end;
        CurrentSongChangedMessageCommand=cmd(playcommand,"Set");
        AnimateCommand=LargeRefresh;
        };
    --~ 	-- Main Title
        LoadFont( "PreviewText","Title" )..{
        Text="jews";
        InitCommand=cmd(playcommand,"Set";blend,"BlendMode_Add";y,37;horizalign,right;shadowlength,0;maxwidth,SCREEN_WIDTH/2);
        SetCommand=function(self)
            local song = GAMESTATE:GetCurrentSong();
            if not song
                -- exit early, hide
                then self:visible(false);
                return;
            end;
            -- otherwise, set it to the song title
            self:visible(true);
            self:settext( song:GetDisplayMainTitle( ) );
            self:diffuse( color(1,1,1,0) );
            self:diffusebottomedge( SONGMAN:GetSongColor(song) );
            self:diffusealpha( 0.25 );
            self:playcommand("Animate")
        end;
        CurrentSongChangedMessageCommand=cmd(playcommand,"Set");
        AnimateCommand=LargeRefresh;
        };
    --~ 	-- Course
        LoadFont( "PreviewText","Title" )..{
        Text="jews";
        InitCommand=cmd(playcommand,"Set";y,37;horizalign,right;shadowlength,0;maxwidth,SCREEN_WIDTH/2);
        SetCommand=function(self)
            local song = GAMESTATE:GetCurrentCourse();
            if not song
                -- exit early, hide
                then self:visible(false);
                return;
            end;
            -- otherwise, set it to the song title
            self:visible(true);
            self:settext( song:GetDisplayFullTitle() );
            self:diffuse( color(1,1,1,1) );
            self:diffusebottomedge(color("#00aeef"));
            self:playcommand("Animate")
        end;
        CurrentTrailChangedMessageCommand=cmd(playcommand,"Set");
        CurrentSongChangedMessageCommand=cmd(playcommand,"Set");
        AnimateCommand=LargeRefresh;
        Condition=GAMESTATE:IsCourseMode();
        };
            -- Artist
        LoadFont( "PreviewText","Artist" )..{
        Text="jews";
        InitCommand=cmd(playcommand,"Set";y,78;horizalign,right;shadowlength,0;maxwidth,SCREEN_WIDTH/2;);
        SetCommand=function(self)
            local song = GAMESTATE:GetCurrentSong();
            if not song
                -- exit early, hide
                then self:visible(false);
                return;
            end;
            -- otherwise, set it to the song title
            self:visible(true);
            self:settext( song:GetDisplayArtist() );
            self:playcommand("Animate")
        end;
        CurrentSongChangedMessageCommand=cmd(playcommand,"Set");
        AnimateCommand=SmallRefresh;
        };
    };

    return t;
end;
local function BPMDisplay()
    local bpmdisplay = Def.BPMDisplay {
		File=THEME:GetPathF("BPMDisplay", "bpm");
		Name="BPMDisplay";
		SetCommand=function(self) self:SetFromGameState() end;
		CurrentSongChangedMessageCommand=cmd(playcommand,"Set");
		CurrentCourseChangedMessageCommand=cmd(playcommand,"Set");
	};
    return bpmdisplay;
end;
--/DUBAIONE/
local function Profile(pn)
	if PROFILEMAN:IsPersistentProfile(pn) then
		-- player profile
		return PROFILEMAN:GetProfile(pn);
	else
		-- machine profile
		return PROFILEMAN:GetMachineProfile();
	end;
end;
local function PlayerScore(pn)
	local s = LoadFont("Hayate Menu")..{
		Name="Score"..pn;
		InitCommand=cmd(shadowlength,0;diffuse,PlayerColor(pn);diffusetopedge,LightColor(PlayerColor(pn));player,pn);
		BeginCommand=cmd(playcommand,"Set");
		
		SetCommand=function(self)
			-- Grab the song and course. We don't know if this is going to
			-- be called on SSMusic or SSCourse, so it's good to get both.
			-- We'll filter this later.
			local song = GAMESTATE:GetCurrentSong();
			local course = GAMESTATE:GetCurrentCourse();
			
			-- set up some variables that are used in both functions.
			local scorelist;
			local text = "";
			local profile;
			if song then
				-- we have a song, we need some steps
				local steps = GAMESTATE:GetCurrentSteps(pn);
				
				if steps then
					-- get profile
					profile = Profile(pn);
					-- populate high score list
					scorelist = profile:GetHighScoreList(song,steps);
					-- a little bird told me this trick.
					-- I ain't sayin' nothin.
					assert(scorelist);
					-- get all the scores from the score list
					local scores = scorelist:GetHighScores();
					
					-- get the top score
					local topscore = scores[1];
					-- if it doesn't exist, set it to 0. this took me forever
					-- to find a workaround since if there are no high scores
					-- for a song this will BREAK.
					if not topscore then
						text = string.format("%.2f%%", 0);
					else
						-- There IS a high score, format it to percentages
						-- and be on our merry way.
						text = string.format("%.2f%%", topscore:GetPercentDP()*100.0);
					end;
				else
					-- no steps. do nothing.
					return;
				end;
			-- the course code is pretty much the same, aside from the args to
			-- Profile:GetHighScoreList.
			elseif course then
				-- we have a course, get a trail
				local trail = GAMESTATE:GetCurrentTrail(pn);
				if trail then
					-- get profile
					profile = Profile(pn);
					-- populate high score list
					scorelist = profile:GetHighScoreList(course,trail);
					assert(scorelist);
					
					local scores = scorelist:GetHighScores();
					-- get the top score
					local topscore = scores[1];
					if not topscore then
						text = string.format("%.2f%%", 0);
					else
						text = string.format("%.2f%%", topscore:GetPercentDP()*100.0);
					end;
				else
					-- no trail. do nothing.
					return;
				end;
			else
				-- FUCK THAT, A NIGGA WANNA COME IN MY FACE?
				text = string.format("%.2f%%", 0); -- BUST BACK
			end;
			self:settext(text);
		end;
		-- song and course changes
		CurrentSongChangedMessageCommand=cmd(playcommand,"Set");
		CurrentCourseChangedMessageCommand=cmd(playcommand,"Set");
		-- steps and trail changes
		CurrentStepsP1ChangedMessageCommand=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;
		
		CurrentTrailP1ChangedMessageCommand=function(self)
			if pn == PLAYER_1 then self:playcommand("Set"); end;
		end;
		CurrentTrailP2ChangedMessageCommand=function(self)
			if pn == PLAYER_2 then self:playcommand("Set"); end;
		end;
	};
	
	return s;
end;
local t = Def.ActorFrame {
    Def.ActorFrame { -- Banner
--[[      InitCommand=cmd(y,SCREEN_CENTER_Y-84;x,SCREEN_WIDTH*0.75);
     OffCommand=cmd(bouncebegin,0.5;addx,-SCREEN_WIDTH*0.6); --]]
     InitCommand=cmd(x,SCREEN_WIDTH/8*0.5+128;y,SCREEN_HEIGHT/8*1+40);
        Def.ActorProxy {
            BeginCommand=function(self) local banner = SCREENMAN:GetTopScreen():GetChild('Banner'); self:SetTarget(banner); end;
        };
        LoadActor( "_banner frame" ) .. {
        };
    };
    -- Song Info ( God so pasty :( )
    Def.ActorFrame { Name="SongInfoContainer";
     InitCommand=cmd(x,SCREEN_WIDTH/8*0.5+196+16;y,SCREEN_HEIGHT/8*1+90);
        Def.BPMDisplay {
            File=THEME:GetPathF("BPMDisplay", "bpm");
            Name="BPMDisplay";
            InitCommand=cmd(horizalign,right;shadowlength,0);
            SetCommand=function(self) self:SetFromGameState() end;
            CurrentSongChangedMessageCommand=cmd(playcommand,"Set");
            CurrentCourseChangedMessageCommand=cmd(playcommand,"Set");
        };
        LoadFont("BPMDisplay","bpm") .. {
            Text="BPM";
            InitCommand=cmd(x,2;horizalign,left;shadowlength,0);
        };
    };
    --- What?
    LoadFont("System") .. {
        InitCommand=cmd(horizalign,left;x,SCREEN_WIDTH/8*0.5+8;y,SCREEN_HEIGHT/8*1+80+10;shadowlength,0);
        BeginCommand=cmd(playcommand,"Set");
        OnCommand=cmd(diffusealpha,0;sleep,0.3;linear,0.3;diffusealpha,1);
        SongChosenMessageCommand=cmd(linear,0.5;diffusealpha,0);
        SortOrderChangedMessageCommand=cmd(playcommand,"Set";finishtweening;diffusealpha,0;addx,-15;decelerate,0.2;addx,15;diffusealpha,1);
        SetCommand=function(self)
            local s = SortOrderToLocalizedString( GAMESTATE:GetSortOrder() );
            self:settext( s );
        end;
    };
    Def.DifficultyList {
        Name="DifficultyList";
        InitCommand=cmd(x,SCREEN_WIDTH/8*0.5+128;y,SCREEN_CENTER_Y-52);
        BeginCommand=cmd(visible,not GAMESTATE:IsCourseMode());
        SongChosenMessageCommand=function(self) self:setfromgamestate(); self.SongChosen = true; self:playcommand("SlideOn"); end;
--~         SlideOnCommand=cmd(linear,0.5;addx,-286;);
        RefreshCommand=function(self) self:setfromgamestate() end;
        CurrentStepsP1ChangedMessageCommand=cmd(playcommand,"Refresh");
        CurrentTrailP1ChangedMessageCommand=cmd(playcommand,"Refresh");
        CurrentStepsP2ChangedMessageCommand=cmd(playcommand,"Refresh");
        CurrentTrailP2ChangedMessageCommand=cmd(playcommand,"Refresh");
        CursorP1 = Def.ActorFrame {
--~             InitCommand=cmd(x,-120;pulse;effectclock,'bgm';effectmagnitude,1,1.2,1;effectperiod,2;);
            InitCommand=cmd(x,-140;pulse;effecttiming,0.75,0,0,0.25;effectclock,"beat";effectmagnitude,1,0.9,1);
            BeginCommand=cmd(visible,true);
            StepsSelectedMessageCommand=function( self, param ) 
                if param.Player ~= PLAYER_1 then return end;
                self:visible(false);
            end;
            children={
                LoadActor( "cursor frame" ) .. {
                    BeginCommand=cmd(diffuse,PlayerColor(PLAYER_1);player,PLAYER_1;);
                };
--[[                 LoadFont( "Common" ) .. {
                    Text="P1";
                    InitCommand=cmd(x,-4;y,-1;diffuse,color("#000000");shadowlength,0);
                    BeginCommand=cmd(player,PLAYER_1;);
                }; --]]
            }
        };
        CursorP2 = Def.ActorFrame {
--~             InitCommand=cmd(x,120;pulse;effectclock,'bgm';effectmagnitude,1,1.2,1;effectperiod,2;);
            InitCommand=cmd(x,140;pulse;effecttiming,0.75,0,0,0.25;effectclock,"beat";effectmagnitude,1,0.9,1);
            BeginCommand=cmd(visible,true);
            StepsSelectedMessageCommand=function( self, param ) 
                if param.Player ~= PLAYER_2 then return end;
                self:visible(false);
            end;
            children={
                LoadActor( "cursor frame" ) .. {
                    BeginCommand=cmd(zoomx,-1;diffuse,PlayerColor(PLAYER_2);player,PLAYER_2;);
                };
--[[                 LoadFont( "Common" ) .. {
                    Text="P2";
                    InitCommand=cmd(x,4;y,-1;diffuse,color("#000000");shadowlength,0);
                    BeginCommand=cmd(player,PLAYER_2;);
                }; --]]
            }
        };
        CursorP1Frame = LoadActor( "_cursor frame p1" ) .. {
--~             InitCommand=cmd(pulse;effectclock,"bgm");
        };
        CursorP2Frame = LoadActor( "_cursor frame p2" ) .. {
--~             InitCommand=cmd(pulse;effectclock,"bgm");
        };
    };
    PlayerScore(PLAYER_1)..{
        OnCommand=cmd(x,SCREEN_WIDTH/8*0.5+64;y,SCREEN_CENTER_Y+120);
    };
    PlayerScore(PLAYER_2)..{
        OnCommand=cmd(x,SCREEN_WIDTH/8*0.5+196;y,SCREEN_CENTER_Y+120);
    };
    -- Blah
    LoadFont("Pixel")..{
        Text="P1 Best";
        InitCommand=cmd(x,SCREEN_WIDTH/8*0.5+64;y,SCREEN_CENTER_Y+108);
        BeginCommand=cmd(shadowlength,0;diffuse,PlayerColor(PLAYER_1);diffusetopedge,LightColor(PlayerColor(PLAYER_1));player,PLAYER_1);
    };
    LoadFont("Pixel")..{
        Text="P2 Best";
        InitCommand=cmd(x,SCREEN_WIDTH/8*0.5+196;y,SCREEN_CENTER_Y+108);
        BeginCommand=cmd(shadowlength,0;diffuse,PlayerColor(PLAYER_2);diffusetopedge,LightColor(PlayerColor(PLAYER_2));player,PLAYER_2);
    };
    LoadFont("Pixel")..{
        Text="Song Time";
        InitCommand=cmd(x,SCREEN_WIDTH/8*0.5+128;y,SCREEN_CENTER_Y+146);
        BeginCommand=cmd(shadowlength,0);
    };
	LoadFont("BPMDisplay", "bpm") .. {
		SetCommand=function(self)
			local song = GAMESTATE:GetCurrentSong()
			local course = GAMESTATE:GetCurrentCourse()
			if not song and not course then
				self:settext("-")
				return
			end
			self:hidden(0)
			local time
			if song then time = song:MusicLengthSeconds() end
			if course then
				local st = GAMESTATE:GetCurrentStyle():GetStepsType()
				time = course:GetTotalSeconds( st )
			end
			if time then
				self:settext( SecondsToMSSMsMs(time) );
			else
				self:settext( "00:00.00" );
			end
		end;
        
		InitCommand=cmd(x,SCREEN_WIDTH/8*0.5+128;y,SCREEN_CENTER_Y+160;shadowlength,0);
		OnCommand=cmd(diffusealpha,0;linear,0.5;diffusealpha,1);
		OffCommand=cmd(rainbowscroll,false;linear,0.5;diffusealpha,0);

		CurrentSongChangedMessageCommand=cmd(playcommand,"Set");
		CurrentCourseChangedMessageCommand=cmd(playcommand,"Set");
	};
	Def.CourseContentsList {
		MaxSongs = 4;

		InitCommand=cmd(x,SCREEN_WIDTH/8*0.5+128;y,SCREEN_CENTER_Y-52);
		OnCommand=cmd(zoomy,0;bounceend,0.3;zoom,1);
		OffCommand=cmd(zoomy,1;bouncebegin,0.3;zoomy,0);
		ShowCommand=cmd(bouncebegin,0.3;zoomy,1);
		HideCommand=cmd(linear,0.3;zoomy,0);
		SetCommand=function(self)
			self:SetFromGameState();
            self:setsecondsperitem(0.25);
			self:SetSecondsPauseBetweenItems(0.5);
			self:scrollwithpadding(0, 0);
		end;
		CurrentTrailP1ChangedMessageCommand=cmd(playcommand,"Set");
		CurrentTrailP2ChangedMessageCommand=cmd(playcommand,"Set");

		Display = Def.ActorFrame { 
			InitCommand=cmd(setsize,200,33);

            LoadActor( THEME:GetPathB("","_frame 3x1"), "Pill Courses", 190)..{
                SetSongCommand=function(self,params)
                    self:diffuse( DarkColor(SONGMAN:GetSongColor(params.Song)));
                end;
            };

            LoadFont("System") .. {
				OnCommand=cmd(y,-1;shadowlength,0;maxwidth,160);
				SetSongCommand=function(self, params) 
                    self:settext(params.Song:GetDisplayMainTitle());
                    self:diffuse( LightColor( SONGMAN:GetSongColor(params.Song) ) )
                    self:diffusebottomedge( SONGMAN:GetSongColor(params.Song) )
                end
			};
			LoadFont("System") .. {
				OnCommand=cmd(x,-108;y,-1;shadowlength,0;);
				SetSongCommand=function(self, params) 
                    self:settext(string.format("%i", params.Number));
                end
			};

			LoadFont("System") .. {
				OnCommand=cmd(x,108;y,-1;shadowlength,0);
				SetSongCommand=function(self, params)
					if params.PlayerNumber ~= GAMESTATE:GetMasterPlayerNumber() then return end
					self:settext( params.Meter );
                    self:diffuse( LightColor(DifficultyColor(params.Difficulty)) )
					self:diffusebottomedge( DifficultyColor(params.Difficulty) );
				end;
			};
		};
	};
--[[     LoadFont("Pixel")..{
        Text="R21 Patch";
		SetCommand=function(self)
            local Song = GAMESTATE:GetCurrentSong()
            local Time
            if Song then Time = Song:MusicLengthSeconds()
            if Time then
                if Time == 105 then
                    self:visible(true)
                end
            self:visible(false)
        end;

		InitCommand=cmd(x,SCREEN_WIDTH/8*0.5+196;y,SCREEN_CENTER_Y+168;shadowlength,0);
		OnCommand=cmd(diffusealpha,0;linear,0.5;diffusealpha,1);
		OffCommand=cmd(rainbowscroll,false;linear,0.5;diffusealpha,0);

		CurrentSongChangedMessageCommand=cmd(playcommand,"Set");
		CurrentCourseChangedMessageCommand=cmd(playcommand,"Set");
    }; --]]
--[[     TextBanner() .. {
        InitCommand=cmd(x,SCREEN_RIGHT-40;y,SCREEN_CENTER_Y-24);
    }; --]]
};
return t;
