// **********************************************************************
//                            OpenAlchemist
//                        ---------------------
//
//  File        : TitleState.cpp
//  Description : 
//  Author      : Guillaume Delhumeau <guillaume.delhumeau@gmail.com>
//  License     : GNU General Public License 2 or higher
//
// **********************************************************************

#include <SDL.h>

#include "TitleState.h"
#include "../memory.h"
#include "../CommonResources.h"
#include "../GameEngine.h"
#include "../misc.h"

/************************************************************************/
/* Constructor                                                          */
/************************************************************************/
TitleState::TitleState()
{
}

/************************************************************************/
/* Destructor                                                           */
/************************************************************************/
TitleState::~TitleState()
{
	unload_gfx();
}

/************************************************************************/
/* Init                                                                 */
/************************************************************************/
void TitleState::init()
{
}

/************************************************************************/
/* Term                                                                 */
/************************************************************************/
void TitleState::term()
{
}

/************************************************************************/
/* Load GFX                                                             */
/************************************************************************/
void TitleState::load_gfx(SDL_Renderer *gc)
{
	unload_gfx();

	// Getting skins resources
	CL_ResourceManager gfx("title.xml");

	_start_message = CL_Sprite(gc, "title/start_message/sprite", &gfx);
	_start_message_x = CL_Integer_to_int("title/start_message/left", &gfx);
	_start_message_y = CL_Integer_to_int("title/start_message/top", &gfx);

	for(int i=0; i<NUMBER_OF_SENTENCES; ++i)
	{
		if (gfx.resource_exists("title/help/"+to_string(i+1)+"/sentence_text"))
		{
			_sentences_text[i] = gfx.get_string_resource("title/help/"+to_string(i+1)+"/sentence_text", "");
		}
		else
		{
			_sentences[i] = CL_Sprite(gc, "title/help/"+to_string(i+1)+"/sentence", &gfx);
		}
		_sentences_x[i] = CL_Integer_to_int("title/help/"+to_string(i+1)+"/left", &gfx);
		_sentences_y[i] = CL_Integer_to_int("title/help/"+to_string(i+1)+"/top", &gfx);
		_sentences_time[i] = CL_Integer_to_int("title/help/"+to_string(i+1)+"/time", &gfx);
	}

	_keydemo_left    = CL_Sprite(gc, "title/keydemo/left", &gfx);
	_keydemo_up      = CL_Sprite(gc, "title/keydemo/up", &gfx);
	_keydemo_right   = CL_Sprite(gc, "title/keydemo/right", &gfx);
	_keydemo_down    = CL_Sprite(gc, "title/keydemo/down", &gfx);
	_keydemo_escape  = CL_Sprite(gc, "title/keydemo/escape", &gfx);
	_keydemo_options = CL_Sprite(gc, "title/keydemo/options", &gfx);

	_init_state = gfx.get_string_resource("title/init_state", "");
	if (!_init_state.empty())
		_p_common_resources->p_engine->register_state_general_menu(_init_state);

	_keyleft_x = 50;
	_keyleft_y = _keyright_y = _keydown_y = 100;
	_keyup_x = _keydown_x = 100;
	_keyup_y = 50;
	_keyright_x = 150;

	_demo_player.load_gfx(gc, "player1/");
}

/************************************************************************/
/* Unload gfx                                                           */
/************************************************************************/
void TitleState::unload_gfx()
{
}

/************************************************************************/
/* Draw                                                                 */
/************************************************************************/
void TitleState::draw(SDL_Renderer *gc)
{
	int width(0);
	int height(0);
	if (_sentences_text[_step].empty())
	{
		_sentences[_step].draw (gc, _sentences_x[_step], _sentences_y[_step]);
		width = _sentences[_step].get_width();
		height = _sentences[_step].get_height();
	}
	else
	{
		std::stringstream ss(_sentences_text[_step]);
		std::string item;
		int y = _sentences_y[_step];
		while (std::getline(ss, item, ':'))
		{
			int x = _sentences_x[_step] - (_p_common_resources->main_font.get_text_width(gc, item) / 2);
			_p_common_resources->main_font.draw_text(gc, x, y, item);
			y += _p_common_resources->main_font.get_text_height(gc, item);
			height += _p_common_resources->main_font.get_text_height(gc, item);
		}
	}
	_start_message.draw(gc, _start_message_x,_start_message_y);
	switch(_step)
	{
	case 2:
		_keydemo_left.draw(gc, _sentences_x[_step] + width/2 - _keydemo_left.get_width()/2,
			_sentences_y[_step] + height);
		_keydemo_left.update();
		break;
	case 3:
		_keydemo_right.draw(gc, _sentences_x[_step] + width/2 - _keydemo_left.get_width()/2,
			_sentences_y[_step] + height);
		_keydemo_right.update();
		break;
	case 4:
		_keydemo_up.draw(gc, _sentences_x[_step] + width/2 - _keydemo_left.get_width()/2,
			_sentences_y[_step] + height);
		_keydemo_up.update();
		break;
	case 5:
	case 7:
		_keydemo_down.draw(gc, _sentences_x[_step] + width/2 - _keydemo_left.get_width()/2,
			_sentences_y[_step] + height);
		_keydemo_down.update();
		break;
	case 6:
		_keydemo_left.draw(gc, _sentences_x[_step] + width/2 - _keydemo_left.get_width(),
			_sentences_y[_step] + height);
		_keydemo_left.update();

		_keydemo_right.draw(gc, _sentences_x[_step] + width/2 + _keydemo_left.get_width(),
			_sentences_y[_step] + height);
		_keydemo_right.update();
		break;
	case 12:
		_keydemo_escape.draw(gc, _sentences_x[_step] + width/2 - _keydemo_left.get_width()/2,
			_sentences_y[_step] + height);
		_keydemo_escape.update();
		break;
	case 13:
		_keydemo_options.draw(gc, _sentences_x[_step] + width/2 - _keydemo_left.get_width()/2,
			_sentences_y[_step] + height);
		_keydemo_options.update();
		break;
		break;

	}
}

/************************************************************************/
/* Update                                                               */
/************************************************************************/
void TitleState::update(SDL_Renderer *gc)
{
	_start_message.update();

	if(_next_time < SDL_GetTicks())
	{
		_step = (_step + 1) % NUMBER_OF_SENTENCES;
		_next_time = SDL_GetTicks() + _sentences_time[_step];
		_sentences[_step].update();
	}

	switch(_step)
	{
		// Welcome to OpenAlchemist !
	case 0:
		_new_game = false;
		break;

		// This is your pieces
	case 1:
		if(!_new_game)
		{
			_new_game = true;
			_demo_player.new_game();
		}
		break;

		// You can move them to the left...
	case 2:
		_demo_player.move_left();
		break;

		// ...or to the right !
	case 3:
		_demo_player.move_right();
		_change_angle = false;
		break;

		// You can also rotate pieces...
	case 4:
		if(!_change_angle)
		{
			_demo_player.change_angle();
			_change_angle = true;
		}
		_fall = false;
		break;

		// ...and make them fall !
	case 5:
		if(!_fall)
		{
			_demo_player.fall();
			_fall = true;
			_select_the_position = false;
		}
		break;

		// Select the position...
	case 6:
		if(!_select_the_position)
		{
			_select_the_position = true;
			_demo_player.move_left();
			_fall = false;
		}
		break;

		// ...and fall !
	case 7:
		if(!_fall)
		{
			_demo_player.fall();
			_fall = true;
		}
		break;

		// When you have more than 3 same items...
	case 8:
		_fall_paused = true;
		break;

		// ...they're destroyed...
	case 9:
		if(_fall_paused)
		{
			_demo_player.resume();
			_fall_paused = false;
			_destruction_paused = true;
		}
		break;

		// ...and a new one is created !
	case 10:
		if(_destruction_paused)
		{
			_demo_player.resume();
			_destruction_paused = false;
		}
		break;

		// Align more than 3 items and you get bonus !
	case 11:
		break;

		// You can also open the game menu...
	case 12:
		break;

		// ...or the options menu !
	case 13:
		break;

		// Now you know everything...
	case 14:
		break;

		// ...so start a my_new game and have fun !
	case 15:
		break;
	}

	_demo_player.update();
}

/************************************************************************/
/* Events                                                               */
/************************************************************************/
void TitleState::events(GameWindow& window)
{
	const Uint8 *state = SDL_GetKeyboardState(NULL);
	if(_p_common_resources -> key.enter.get() || state[SDL_SCANCODE_SPACE] || state[SDL_SCANCODE_1])
	{
		_p_common_resources -> p_engine -> set_state_ingame();
		_p_common_resources -> player1.new_game();
		if (!_init_state.empty())
			_p_common_resources->p_engine->set_state_general_menu(_init_state);
	}
	if(_p_common_resources->player2_support && state[SDL_SCANCODE_2])
	{
		_p_common_resources -> p_engine -> set_state_ingame();
		_p_common_resources->player1.load_gfx(_p_common_resources->p_gc, "player1_2p/");
		_p_common_resources -> player1.new_game();
		_p_common_resources->player2 = std::unique_ptr<Player>(new HumanPlayer(2));
		_p_common_resources->player2->load_gfx(_p_common_resources->p_gc, "player2/");
		_p_common_resources->player2->new_game();
		if (!_init_state.empty())
			_p_common_resources->p_engine->set_state_general_menu(_init_state);
	}

	if(_p_common_resources-> key.escape.get() || _p_common_resources -> key.pause.get())
	{
		_p_common_resources -> p_engine -> set_state_pause_menu();
	}

	if(_p_common_resources -> key.skins.get())
	{
		_p_common_resources -> p_engine -> set_state_skin_menu();
	}

	if(_p_common_resources->key.options.get() )
	{
		_p_common_resources -> p_engine -> set_state_options_menu();
	}

}

/************************************************************************/
/* Front layer behind                                                   */
/************************************************************************/
bool TitleState::front_layer_behind()
{
	return true;
}

/************************************************************************/
/* Start                                                                */
/************************************************************************/
void TitleState::start()
{
	_step = 0;
	_next_time = SDL_GetTicks() + 5000;
	_p_common_resources -> p_current_player = &_demo_player;
	_demo_player.new_game();
}
