#include "stdafx.h"
#include "GameStateNextLevel.h"
#include "Common.h"
#include "IRender.h"
#include "ISystem.h"
#include "TextManager.h"
#include "LevelDirector.h"
#include "ObjectsStorage.h"
#include "PlayerProfile.h"

const float CHAR_TIMER = 0.02f;
const float BREAK_TIMER = 2.0f;
const float AFTER_IMAGE_TIMER = 0.5f;
const float FADE_TIME = 1.0f;


void GameStateNextLevel::RenderBefore( IRender & render, const IGameContext & context )
{
	  // CopyRegion is used because we want to stretch background image (it's too small)
	render.CopyRegion( m_bgImage, 0, 0, 0, 0, -1, -1, SCREEN_W, SCREEN_H );	
	render.DrawRectFill( 0, 0, SCREEN_W, SCREEN_H, Color( 0, 0, 0, 200 ) );

	  // Time has come to draw the next letter
	if ( !m_finish && m_timer <= 0.0f )
	{
		  // The new speaker has not yet been drawn
		if ( m_currentActor.IsValid() )
		{
			render.DrawImage( m_image, m_currentActor, 200, m_areaY );
			render.DrawRect( m_image, 200, m_areaY, 300, m_areaY + 100, Color(255,255,255) );
			m_currentActor = ImageHandle();
			m_timer = AFTER_IMAGE_TIMER;
		}			
				  
		if ( m_skipPhrase )
		{
			  // Quickly write all letters of phrase
			while( m_textPrinter.Update( m_image, render ) );
			m_next = true;
		}
		else
		{
			  // Write one letter of phrase. If it is the last letter, set m_next to true
			if ( !m_textPrinter.Update( m_image, render ) )
				m_next = true;
			m_timer = CHAR_TIMER;
		}
	}

	render.DrawRectFill( m_image, 0, SCREEN_H - 40, SCREEN_W, SCREEN_H, Color(0,0,0) );
	if ( !m_finish )
	{
		render.DrawAlignedText( m_image, SCREEN_W/2, SCREEN_H - 40, Color(200,200,200), 16, TEXT_ALIGN_CENTER, "Press Fire to skip to the next phrase" );
		render.DrawAlignedText( m_image,SCREEN_W/2, SCREEN_H - 20, Color(200,200,200), 16, TEXT_ALIGN_CENTER, "Press ESC to skip briefing" );
	}
	else
	{
		int c = 100 + 155 * (cosf(3*m_flash) + 1.0f)/2.0f;
		if ( c > 255 )
			c = 255;
		render.DrawAlignedText( m_image, SCREEN_W/2, SCREEN_H - 40, Color(c,c,c), 16, TEXT_ALIGN_CENTER, "Press Fire to continue" );
	}

	if ( m_fade )
	{
		int c = 255.0f * (1.0f - m_timer / FADE_TIME);
		if ( c < 0 )
			c = 0;
		if ( c > 255 )
			c = 255;
		render.DrawRectFill( m_image, 0, 0, SCREEN_W, SCREEN_H, Color( 0, 0, 0, c ) );
	}

	render.DrawImage( m_image, 0, 0 );
}

void GameStateNextLevel::RenderAfter( IRender & render, const IGameContext & context )
{

}

void GameStateNextLevel::Update( float dt, IGameContext & context )
{
	m_flash += dt;
	if ( m_flash >= ALLEGRO_PI )
		m_flash -= 2*ALLEGRO_PI;
	m_timer -= dt;
	if ( m_timer <= 0 )
	{
		if ( m_fade )
		{
			context.RemoveState( GAMESTATE_NEXT_LEVEL );
			context.PushState( GAMESTATE_LEVEL );
		}
	}

	if ( m_first )
	{
		context.LoadNextLevel();
		context.GetPlayerProfile().ResetLevelStats();
		m_first = false;
	}

	if ( !m_finish && m_next )
	{
		const STalkEntry *pTalk = context.GetLevelDirector().GetBriefing( m_briefingIndex );

		if ( pTalk )
		{
			m_currentActor = pTalk->m_image;
			const Text *txt = GetTextManager().GetResource( pTalk->m_text );
			if ( txt )
				m_textPrinter.SetText( txt->text() );
			
			if ( m_briefingIndex > 0 && !m_skipAll )
				m_timer = BREAK_TIMER;

			if ( m_skipPhrase && !m_skipAll )
			{
				m_skipPhrase = false;
			}
		}
		else
		{
			m_currentActor = ImageHandle();
			m_textPrinter.SetText( 0 );
			m_finish = true;
		}

		if ( m_briefingIndex > 0 )
		{
			if ( m_textY > m_areaY + 120 )
				m_areaY = m_textY;
			else
				m_areaY = m_areaY + 120;
		}

		m_textPrinter.SetRegion( 310, m_areaY + 10, 500, 300 );

		++m_briefingIndex;
		m_next = false;
	}
}

void GameStateNextLevel::OnPush( IGameContext & context )
{
	context.GetOjectsStorage().GetMusic().ReceiveEvent( "BRIEFING" );

	if ( !m_image.IsValid() )
		m_image = GetRender().CreateImage( SCREEN_W, SCREEN_H, true, "brief" );

	if ( !m_bgImage.IsValid() )
		m_bgImage = GetRender().LoadImage( "Data/Sprites/title_screen.png" );

	m_timer = 0.0f;
	m_briefingIndex = 0;

	m_next = true;
	m_first = true;
	m_finish = false;
	m_skipPhrase = false;
	m_skipAll = false;
	m_fade = false;

	m_areaY = 50;
	m_textY = 0;
	m_textX = 0;

	m_flash = 0.0f;

	AddKeyboardHandler( this, &GameStateNextLevel::SkipAll, KeyboardEvent::KBD_KEY_DOWN, ALLEGRO_KEY_ESCAPE );	
	
	const int keyFire		= GetSystem().GetConfigValue_Int( "DD_Controls", "Fire" );	
	AddKeyboardHandler( this, &GameStateNextLevel::SkipPhrase,  KeyboardEvent::KBD_KEY_DOWN, keyFire    ? keyFire    : ALLEGRO_KEY_Q );
}

bool GameStateNextLevel::SkipPhrase( const InputEvent & e)
{
	if ( m_finish && !m_fade )
	{
		m_fade = true;
		m_timer = FADE_TIME;
	}
	else
	{
		m_timer = 0;
		m_skipPhrase = true;
	}
	return true;
}

bool GameStateNextLevel::SkipAll( const InputEvent & e)
{
	if ( m_finish && !m_fade )
	{
		m_fade = true;
		m_timer = FADE_TIME;	
	}
	else
	{
		m_timer = 0;
		m_skipAll = true;
		m_skipPhrase = true;
	}
	return true;
}
