void ScreenDebugOverlay::Init()
{
	Screen::Init();

	// Init debug mappings
	// TODO: Arch-specific?
	{
		g_Mappings.Clear();

		g_Mappings.holdForDebug1 = DeviceInput(DEVICE_KEYBOARD, KEY_F3);
		g_Mappings.holdForDebug2.MakeInvalid();
		g_Mappings.holdForSlow = DeviceInput(DEVICE_KEYBOARD, KEY_ACCENT);
		g_Mappings.holdForFast = DeviceInput(DEVICE_KEYBOARD, KEY_TAB);
		g_Mappings.toggleMute = DeviceInput(DEVICE_KEYBOARD, KEY_PAUSE);

		/* TODO: Find a better way of indicating which option is which here.
		 * Maybe we should take a page from ScreenEdit's menus and make
		 * RowDefs()? */

		int i=0;
		g_Mappings.gameplayButton[i++]	= DeviceInput(DEVICE_KEYBOARD, KEY_F8);
		g_Mappings.gameplayButton[i++]	= DeviceInput(DEVICE_KEYBOARD, KEY_F7);
		g_Mappings.gameplayButton[i++]	= DeviceInput(DEVICE_KEYBOARD, KEY_F6);
		i=0;
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C1);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C2);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C3);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C4);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C5);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C6);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C7);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C8);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C9);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C0);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cq);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cw);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Ce);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cr);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Ct);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cy);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cu);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Ci);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Co);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cp);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Ca);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cs);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cd);
		g_Mappings.pageButton[DeviceInput(DEVICE_KEYBOARD, KEY_F5)] = 0;
		g_Mappings.pageButton[DeviceInput(DEVICE_KEYBOARD, KEY_F6)] = 1;
		g_Mappings.pageButton[DeviceInput(DEVICE_KEYBOARD, KEY_F7)] = 2;
		g_Mappings.pageButton[DeviceInput(DEVICE_KEYBOARD, KEY_F8)] = 3;
	}

	std::map<std::string,int> iNextDebugButton;
	int iNextGameplayButton = 0;
	for (auto *p: *g_pvpSubscribers)
	{
		std::string sPageName = p->GetPageName();

		DeviceInput di;
		switch( p->GetType() )
		{
		case IDebugLine::all_screens:
			di = g_Mappings.debugButton[iNextDebugButton[sPageName]++];
			break;
		case IDebugLine::gameplay_only:
			di = g_Mappings.gameplayButton[iNextGameplayButton++];
			break;
		}
		p->m_Button = di;

		if( find(m_asPages.begin(), m_asPages.end(), sPageName) == m_asPages.end() )
			m_asPages.push_back( sPageName );
	}

	m_iCurrentPage = 0;
	m_bForcedHidden = false;

	m_Quad.StretchTo( Rage::RectF( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT ) );
	m_Quad.SetDiffuse( BACKGROUND_COLOR );
	this->AddChild( &m_Quad );

	// if you're going to add user commands, make sure to have the overrides
	// set after parsing the metrics. -aj
	m_textHeader.SetName( "HeaderText" );
	m_textHeader.LoadFromFont( THEME->GetPathF("ScreenDebugOverlay", "header") );
	LOAD_ALL_COMMANDS_AND_SET_XY_AND_ON_COMMAND( m_textHeader );
	m_textHeader.SetText( DEBUG_MENU.GetValue() );
	this->AddChild( &m_textHeader );

	for (auto s = m_asPages.begin(); s != m_asPages.end(); ++s)
	{
		int iPage = s - m_asPages.begin();

		DeviceInput di;
		bool b = GetKeyFromMap( g_Mappings.pageButton, iPage, di );
		ASSERT( b );

		std::string sButton = INPUTMAN->GetDeviceSpecificInputString( di );

		BitmapText *p = new BitmapText;
		p->SetName( "PageText" );
		p->LoadFromFont( THEME->GetPathF("ScreenDebugOverlay", "page") );
		LOAD_ALL_COMMANDS_AND_ON_COMMAND( p );
		// todo: Y value is still hardcoded. -aj
		p->SetXY( PAGE_START_X+iPage*PAGE_SPACING_X, SCREEN_TOP+20 );
		p->SetText( *s + " (" + sButton + ")" );
		m_vptextPages.push_back( p );
		this->AddChild( p );
	}

	auto onEachLine = [this](IDebugLine *) {
		{
			BitmapText *bt = new BitmapText;
			bt->SetName( "ButtonText" );
			bt->LoadFromFont( THEME->GetPathF("ScreenDebugOverlay", "line") );
			bt->SetHorizAlign( align_right );
			bt->SetText( "blah" );
			LOAD_ALL_COMMANDS_AND_ON_COMMAND( *bt );
			m_vptextButton.push_back( bt );
			this->AddChild( bt );
		}
		{
			BitmapText *bt = new BitmapText;
			bt->SetName( "FunctionText" );
			bt->LoadFromFont( THEME->GetPathF("ScreenDebugOverlay", "line") );
			bt->SetHorizAlign( align_left );
			bt->SetText( "blah" );
			LOAD_ALL_COMMANDS_AND_ON_COMMAND( *bt );
			m_vptextFunction.push_back( bt );
			this->AddChild( bt );
		}
	};
	
	std::for_each(g_pvpSubscribers->begin(), g_pvpSubscribers->end(), onEachLine);
	this->SetVisible( false );
}
void ScreenDebugOverlay::Init()
{
	Screen::Init();

	// Init debug mappings
	// TODO: Arch-specific?
	{
		g_Mappings.Clear();

		g_Mappings.holdForDebug1 = DeviceInput(DEVICE_KEYBOARD, KEY_F3);
		g_Mappings.holdForDebug2.MakeInvalid();
		g_Mappings.holdForSlow = DeviceInput(DEVICE_KEYBOARD, KEY_ACCENT);
		g_Mappings.holdForFast = DeviceInput(DEVICE_KEYBOARD, KEY_TAB);

		/* TODO: Find a better way of indicating which option is which here.
		 * Maybe we should take a page from ScreenEdit's menus and make
		 * RowDefs()? */

		int i=0;
		g_Mappings.gameplayButton[i++]	= DeviceInput(DEVICE_KEYBOARD, KEY_F8);
		g_Mappings.gameplayButton[i++]	= DeviceInput(DEVICE_KEYBOARD, KEY_F7);
		g_Mappings.gameplayButton[i++]	= DeviceInput(DEVICE_KEYBOARD, KEY_F6);
		i=0;
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C1);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C2);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C3);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C4);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C5);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C6);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C7);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C8);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C9);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C0);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cq);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cw);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Ce);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cr);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Ct);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cy);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cu);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Ci);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Co);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cp);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_UP);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_DOWN);
		g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_BACK);
		g_Mappings.pageButton[DeviceInput(DEVICE_KEYBOARD, KEY_F5)] = 0;
		g_Mappings.pageButton[DeviceInput(DEVICE_KEYBOARD, KEY_F6)] = 1;
		g_Mappings.pageButton[DeviceInput(DEVICE_KEYBOARD, KEY_F7)] = 2;
		g_Mappings.pageButton[DeviceInput(DEVICE_KEYBOARD, KEY_F8)] = 3;
	}

	map<RString,int> iNextDebugButton;
	int iNextGameplayButton = 0;
	FOREACH( IDebugLine*, *g_pvpSubscribers, p )
	{
		RString sPageName = (*p)->GetPageName();

		DeviceInput di;
		switch( (*p)->GetType() )
		{
		case IDebugLine::all_screens:
			di = g_Mappings.debugButton[iNextDebugButton[sPageName]++];
			break;
		case IDebugLine::gameplay_only:
			di = g_Mappings.gameplayButton[iNextGameplayButton++];
			break;
		}
		(*p)->m_Button = di;

		if( find(m_asPages.begin(), m_asPages.end(), sPageName) == m_asPages.end() )
			m_asPages.push_back( sPageName );
	}

	m_iCurrentPage = 0;
	m_bForcedHidden = false;

	m_Quad.StretchTo( RectF( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT ) );
	m_Quad.SetDiffuse( BACKGROUND_COLOR );
	this->AddChild( &m_Quad );

	// if you're going to add user commands, make sure to have the overrides
	// set after parsing the metrics. -aj
	m_textHeader.SetName( "HeaderText" );
	m_textHeader.LoadFromFont( THEME->GetPathF("ScreenDebugOverlay", "header") );
	LOAD_ALL_COMMANDS_AND_SET_XY_AND_ON_COMMAND( m_textHeader );
	m_textHeader.SetText( DEBUG_MENU );
	this->AddChild( &m_textHeader );

	FOREACH_CONST( RString, m_asPages, s )
	{
		int iPage = s - m_asPages.begin();

		DeviceInput di;
		bool b = GetKeyFromMap( g_Mappings.pageButton, iPage, di );
		ASSERT( b );

		RString sButton = INPUTMAN->GetDeviceSpecificInputString( di );

		BitmapText *p = new BitmapText;
		p->SetName( "PageText" );
		p->LoadFromFont( THEME->GetPathF("ScreenDebugOverlay", "page") );
		LOAD_ALL_COMMANDS_AND_ON_COMMAND( p );
		// todo: Y value is still hardcoded. -aj
		p->SetXY( PAGE_START_X+iPage*PAGE_SPACING_X, SCREEN_TOP+20 );
		p->SetText( *s + " (" + sButton + ")" );
		m_vptextPages.push_back( p );
		this->AddChild( p );
	}