/*********************************************************************
*	Play window definition
*	SOURCE FILE
*	Autor:	Michal Jirouš
*	Datum: 28.7.2008
*	Soubor: menu_playwindow.cpp
*	Popis: Soubor obsahuje implementaci okna pro vyber levelu k hrani.
*			okno obsahuje list box s nazvy levelu, nejlepsim score
*			a popisem obtiznosti. V okne je tez popis levelu,
*			jmeno nejlepsiho hrace s jeho casem.
**********************************************************************/


#include "game_mainmenu.h"
#include "textLibrary.h"
#include "game_highscore.h"
#include <sstream>

using namespace mainMenu;
using namespace std;

const float PLAY_LEFT_SIZE					= 2.0f;
const float PLAY_RIGHT_SIZE					= 1.0f;
const float PLAY_NAME_FIELD_SIZE			= 4.0f;
const float PLAY_DIFFICULTY_FIELD_SIZE		= 2.0f;
const float PLAY_TIME_FIELD_SIZE			= 2.0f;
const float PLAY_WINDOW_VERTICAL_PADDING	= 0.05f;
const float PLAY_LEFT_LABELS_HEIGHT			= 32.0f;

const float PLAY_CORRECTION					= 20.0f;



/***************************************************************
***************	PLAY WINDOW CREATION AND FUNCTIONS *************
****************************************************************/

CSubWindow *MainMenu::createPlayWindow()
{
	float width = max(WINDOW_WIDTH * m_fWidth,WINDOW_MINIMUM_WIDTH);

	CSubWindow *window = new CSubWindow( m_fWidth / 2.0f - width / 2.0f, WINDOW_Y_POSITION * m_fHeight,
			width, WINDOW_HEIGHT * m_fHeight);
		window->setCaption( textLibrary::getText( TXT_MAP_CHOOSE ) );

	ContainerRelativeLeftToRight *containerLR = new ContainerRelativeLeftToRight();
	containerLR->setVerticalPadding( PLAY_WINDOW_VERTICAL_PADDING );
	window->setComponent( containerLR );

	ContainerRelativeUpToDown *containerUD = new ContainerRelativeUpToDown();	//leva strana
	containerLR->addComponent( containerUD, PLAY_LEFT_SIZE );

	ContainerRelativeLeftToRight *labels = new ContainerRelativeLeftToRight();
	LabelNoOutline *label = new LabelNoOutline(0,0);
	label->setCaption( textLibrary::getText( TXT_MAP_NAME ) );
	labels->addComponent( label, PLAY_NAME_FIELD_SIZE );

	label = new LabelNoOutline(0,0);
	label->setCaption( textLibrary::getText( TXT_DIFFICULTY ) );
	labels->addComponent( label, PLAY_DIFFICULTY_FIELD_SIZE );

	label = new LabelNoOutline(0,0);
	label->setCaption( textLibrary::getText( TXT_TIME ) + " [s]" );
	labels->addComponent( label, PLAY_TIME_FIELD_SIZE );

	containerUD->addComponent( labels, TOP_LABELS_HEIGHT );

	m_pLevelList = new ListBox( 0, 0 );
	m_pLevelList->setObjectID( LISTBOX_LEVEL_LIST );
	containerUD->addComponent( m_pLevelList, containerUD->getScissorBox().h - TOP_LABELS_HEIGHT );

	ContainerRelativeUpToDown *rightField = new ContainerRelativeUpToDown();
	rightField->setHorizontalPadding( PLAY_WINDOW_VERTICAL_PADDING );
	containerLR->addComponent( rightField, PLAY_RIGHT_SIZE );
	containerLR->setHorizontalPadding( PLAY_WINDOW_VERTICAL_PADDING );

	Button *button = GFG_newButton( textLibrary::getText( TXT_PLAY ), BUTTON_PLAYWINDOW_GO );
	rightField->addComponent( button, BUTTON_HEIGHT );

	button = GFG_newButton( textLibrary::getText( TXT_CLOSE ), BUTTON_PLAYWINDOW_CLOSE );
	rightField->addComponent( button, BUTTON_HEIGHT );

	m_pLevelName = new LabelNoOutline(0,0);
	m_pLevelName->setCaption( "level name" );	//konstanta je jen symbolicka..po spusteni je prepsana vlastnosti levelu
	rightField->addComponent( m_pLevelName, PLAY_LEFT_LABELS_HEIGHT );

	label = new LabelNoOutline(0,0);
	label->setCaption( textLibrary::getText( TXT_BEST_PLAYER_AND_TIME ) );
	rightField->addComponent( label, PLAY_LEFT_LABELS_HEIGHT );

	m_pBestPlayer = new  LabelNoOutline(0,0);
	m_pBestPlayer->setCaption( "best player" );	//konstanta je jen symbolicka..po spusteni je prepsana vlastnosti levelu
	m_pBestPlayer->setAlign( FONT_ALIGN_CENTER );
	rightField->addComponent( m_pBestPlayer, PLAY_LEFT_LABELS_HEIGHT );

	m_pBestTime = new  LabelNoOutline(0,0);
	m_pBestTime->setCaption( "time" );	//konstanta je jen symbolicka..po spusteni je prepsana vlastnosti levelu
	m_pBestTime->setAlign( FONT_ALIGN_CENTER );
	rightField->addComponent( m_pBestTime, PLAY_LEFT_LABELS_HEIGHT );

	
	m_pLevelDescription = new ScrollLabel(0,0);
	m_pLevelDescription->setCaption( "destription" );//konstanta je jen symbolicka..po spusteni je prepsana vlastnosti levelu
	rightField->addComponent( m_pLevelDescription,
		rightField->getScissorBox().h - 2.0f*BUTTON_HEIGHT - 4.0f*PLAY_LEFT_LABELS_HEIGHT - PLAY_CORRECTION );
		//dve tlacitka, 4 labely + dorovnani 

	createLevelList();

	return window;
}

//vytvori panely seznamu dle jmen a vlastnosti levelu
void MainMenu::createLevelList()
{
	if( !m_pLevelList )
		return;

	bool detailsSet = false;

	std::map<std::string, levels::LevelInfo> *mapList = &levels::getLevels();
	for( map<std::string, levels::LevelInfo>::iterator iter = mapList->begin(); iter != mapList->end(); iter++)
	{
		LevelPanel *newPanel = new LevelPanel();
		newPanel->create( iter->first, &iter->second );
		
		if( !detailsSet )
		{
			detailsSet = true;
			setLevelDescriptionDetails( newPanel );
		}
		m_pLevelList->addPanel( newPanel );	
	}
}

//naformatuje cas pro textovy vystup
string MainMenu::formatTime( Uint32 uiMs )
{
	ostringstream buf;
	int mins = uiMs / 60000;
	int secs = (uiMs - mins * 60000) / 1000;
	int ms = uiMs - mins * 60000 - secs*1000;
	buf << mins << ":";
	if( secs < 10 )
		buf << "0" << secs;
	else
		buf	<< secs;
	buf << "." << ms;
	return buf.str();
}

//nastavi podrobny popis levelu v okne dle panelu s nazvem levelu
void MainMenu::setLevelDescriptionDetails( LevelPanel *panel )
{
	if( !panel )
		return;

	if( m_pLevelName )
		m_pLevelName->setCaption( panel->m_pLevelInfo->m_sName );
	if( m_pLevelDescription )
		m_pLevelDescription->setCaption( panel->m_pLevelInfo->m_sDescription );
	if( m_pBestPlayer )
	{
		highscore::HighScoreInfo *hinfo = highscore::getHighScore( panel->m_sLevelKey );
		if( hinfo )
		{
			m_pBestPlayer->setCaption( hinfo->m_sPlayer );
			m_pBestTime->setCaption( formatTime( hinfo->m_uiTime ) );
		}
		else
		{
			m_pBestPlayer->setCaption( "" );
			m_pBestTime->setCaption( NO_HIGHSCORE );
		}
	}
}

//aktualizuje highscore u vsech levelu
void MainMenu::refreshPlayWindowComponents()
{
	list<CBasePanel*> *tmpList = m_pLevelList->getPanelList();
	for( list<CBasePanel*>::iterator iter = tmpList->begin(); iter != tmpList->end(); iter++ )
	{
		LevelPanel *tmpPanel = reinterpret_cast<LevelPanel*>( (*iter) );
		if( tmpPanel )
			tmpPanel->updateHighScore();
	}

	LevelPanel *panel = reinterpret_cast<LevelPanel*>( m_pLevelList->getSelectedPanel() );
	if( panel )
	{
		setLevelDescriptionDetails( panel );
	}
}


/*********************************************************
***********	LEVEL PANEL DEFINITION	   *******************
*********************************************************/
void LevelPanel::create( std:: string key, levels::LevelInfo *info )
{
	if( info == NULL )
		return;
	m_sLevelKey = key;
	m_pLevelInfo = info;
	
	setHeight( 32 );
	ContainerRelativeLeftToRight *container = new ContainerRelativeLeftToRight();
	LabelNoOutline *label = new LabelNoOutline(0,0);
	label->setPadding( 0.0f );
	label->setColorText( COLOR_PANEL_TEXT );
	label->setCaption( m_pLevelInfo->m_sName );
	container->addComponent( label, PLAY_NAME_FIELD_SIZE );

	label = new LabelNoOutline(0,0);
	label->setPadding( 0.0f );
	label->setAlign( FONT_ALIGN_CENTER );
	label->setColorText( COLOR_PANEL_TEXT );
	label->setCaption( levels::getDifficultyName( m_pLevelInfo->m_iDifficulty ) );
	container->addComponent( label, PLAY_DIFFICULTY_FIELD_SIZE );

	m_pTimeLabel = new LabelNoOutline(0,0);
	m_pTimeLabel->setPadding( 0.0f );
	m_pTimeLabel->setAlign( FONT_ALIGN_CENTER );
	m_pTimeLabel->setColorText( COLOR_PANEL_TEXT );
	updateHighScore();
	container->addComponent( m_pTimeLabel, PLAY_TIME_FIELD_SIZE );
	setComponent( container );

}

LevelPanel::LevelPanel()
{
	m_pTimeLabel = NULL;
	m_pLevelInfo = NULL;
	m_uiTime = 0;
}

//pokud je hodnota highscore jina nez ve vlastnostech panelu, tak se aktualizuje
void LevelPanel::updateHighScore()
{
	if( m_pTimeLabel && m_pLevelInfo)
	{
		highscore::HighScoreInfo *hinfo = highscore::getHighScore( m_sLevelKey );
		if( hinfo && m_uiTime != hinfo->m_uiTime )
			m_pTimeLabel->setCaption( main_menu.formatTime( hinfo->m_uiTime )  );
		else
			m_pTimeLabel->setCaption( NO_HIGHSCORE );
	}
}
