/*

	Ripatti Artem (c) 2014

*/

#define _CRT_SECURE_NO_WARNINGS

#include "xrpg_iface.h"
#include <time.h>

namespace xrpg
{
	ZEvent _events[] = {
		{ EVENT_UNKNOWN,	0, 0, 0, 0, 0, 0, "Хз" },
		{ EVENT_SHOP,		0, 0, 0, 0, 1, 0, "Магазин волшебника", "Старый волшебник\nторгует целеблыми зельями" },
		{ EVENT_FORGE,		0, 0, 0, 0, 1, 1, "Кузница", "Кузнец может улучшить\nваше обмундирование" },
		{ EVENT_ROGUES,		0, 0, 0, 0, 1, 2, "Лагерь наемников", "Здесь можно потренироваться\nили поиграть в кости" },
		{ EVENT_WITCH,		0, 0, 0, 0, 1, 3, "Хижина ведьмы", "Хз" },

		{ EVENT_SLIME,		 20,   6,   7,  20, 2, 0, "Слизняк", "Это что еще за сопля?" },
		{ EVENT_SKELETON,	 50,  10,  15,  35, 2, 1, "Скелет", "Устрашающе гремит костями" },
		{ EVENT_ZOMBIE,		 70,  13,  25,  50, 2, 2, "Зомби", "Мозги! Свежие мозги!" },
		{ EVENT_WEREWOLF,	100,  16,  30,  70, 2, 3, "Оборотень", "Чертово полнолуние!" },
		{ EVENT_MINOTAUR,	120,  18,  35,  90, 3, 0, "Минотавр", "Ни бык, ни человек" },
		{ EVENT_GOLEM,		240,  17,  40, 100, 3, 1, "Голем", "Каменное чудище" },
		{ EVENT_ANGEL,		220,  22,  55, 130, 3, 2, "Ангел", "Похоже, этот падший" },
		{ EVENT_TANATOS,	250,  25,  60, 150, 3, 3, "Танатос", "Пришел по твою душу" },
		{ EVENT_DRAGON,		200,  20,  50, 120, 0, 3, "Дракон", "Огнедышащее чудовище" }
	};

	ZXRPG::ZXRPG()
	{
		_state = STATE_BEGIN;
		_cntd = 0;
		_frame = 0;

		reset();
	}

	void ZXRPG::reset()
	{
		_world = 1;
		_cur_e = 0;
		_exp = 0;
		_lvl = 1;
		_hp = 100;
		_gld = 100;
		_pot = 3;
		_atk = 4;
		_def = 1;

		delta_vec.clear();
	}

	void ZXRPG::gen()
	{
		srand( (unsigned int)time(0) );

		for (int a=1; a<=6; a++)
			_evs[a] = _events[ rand()%3 + (_world-1)%7 + xrpg::EVENT_SLIME ];
		_evs[7] = _events[ xrpg::EVENT_DRAGON ];
		int koeff = _world+1 + ((_world-1)/7)*2;
		for (int a=1; a<=7; a++)
		{
			_evs[a].hp = _evs[a].hp*koeff/2;
			_evs[a].atk = _evs[a].atk*koeff/2;
			_evs[a].ex = _evs[a].ex*koeff/2;
			_evs[a].gld = _evs[a].gld*koeff/2;
		}

		for (int a=1; a<=5; a++)
			if (rand()%4==0)
				_evs[a] = _events[ rand()%3 + xrpg::EVENT_SHOP ];

		_evs[ 5+rand()%2 ] = _events[ xrpg::EVENT_SHOP ];
	}

	bool ZXRPG::do_frame( XInputEngine * IE, XSoundEngine * SE )
	{
		if (_state == xrpg::STATE_BEGIN)
		{
			if (IE->mouse_pressed( 0, false, true ))
			{
				reset();
				_state = xrpg::STATE_WORLD;
				_cntd = 100;
			}
		}
		else if (_state == xrpg::STATE_WORLD)
		{
			_cntd--;
			if (_cntd==0)
			{
				_state = xrpg::STATE_GOTO_NEXT;
				_cntd = 100;
				gen();
			}
		}
		else if (_state == xrpg::STATE_GOTO_NEXT)
		{
			_cntd--;
			if (_cntd==0)
			{
				_state = xrpg::STATE_INCREASE;
				_cntd = 100;
				_cur_e++;
			}
		}
		else if (_state == xrpg::STATE_INCREASE)
		{
			_cntd-=5;
			if (_cntd==0)
			{
				_state = xrpg::STATE_CUR_EVENT;
				_cntd = 100;
			}
		}
		else if (_state == xrpg::STATE_GAME_OVER)
		{
			if (IE->mouse_pressed( 0, false, true ))
			{
				_state = xrpg::STATE_BEGIN;
				_cntd = 100;
			}
		}
		else if (_state == xrpg::STATE_CUR_EVENT)
		{
			int xx = IE->get_mouse_x()/2;
			int yy = IE->get_mouse_y()/2;
					
			if (_messages.size()==0)
				for (int a=0; a<3; a++)
					if (80+80*a-38 <= xx && xx < 80+80*a+38 && 130 <= yy && yy < 160)
						if (IE->mouse_pressed( 0, true, false ))
							if (a==2 && _cur_e!=7)
							{
								_state = xrpg::STATE_DECREASE;
								_cntd = 100;
							}
							else if (a<2)
							{
								if (_evs[_cur_e].type == xrpg::EVENT_SHOP)
								{
									if (a==0 && _gld>=20) { d_gld(-20); d_pot(1); }
									if (a==1 && _gld>=100) { d_gld(-100); d_hp(100); }
								}
								else if (_evs[_cur_e].type == xrpg::EVENT_FORGE)
								{
									if (a==0 && _gld>=100) { d_gld(-100); d_atk(1); }
									if (a==1 && _gld>=100) { d_gld(-100); d_def(1); }
								}
								else if (_evs[_cur_e].type == xrpg::EVENT_ROGUES)
								{
									if (a==0 && _gld>=100)
									{
										d_gld(-100);
										_exp+=50;
										while(_exp >= _lvl*10)
										{
											_exp -= _lvl*10;
											_lvl++;
											_messages.push( "Level UP!" );
										}
									}
									if (a==1 && _gld>=10)
										if (rand()&1) { d_gld(10); _messages.push( "Ты выиграл $20!" ); }
										else { d_gld(-10); _messages.push( "Ты проиграл :(" ); }
								}
								else
								{
									if (a==0 && _hp>0)
									{
										d_e_hp( -get_atk() );
										if (_evs[_cur_e].hp>0)
										{
											d_hp( -max(0, _evs[_cur_e].atk - get_def()) );
											if (_hp==0)
												_messages.push( "Поражение!" );
										}
										else
										{
											char ch[256];
											sprintf( ch, "Монстр повержен и\nты получил %dEXP и $%d", _evs[_cur_e].ex, _evs[_cur_e].gld );
											_exp += _evs[_cur_e].ex;
											d_gld( _evs[_cur_e].gld );
											_messages.push( string(ch) );
											while(_exp >= _lvl*10)
											{
												_exp -= _lvl*10;
												_lvl++;
												_messages.push( "Level UP!" );
											}
											if (_cur_e==7)
											{
												_messages.push( "Ты убил дракона!" );
												if (_world < 7) _messages.push( "Но твоя принцесса\nв другом замке!" );
												else if (_world == 7)
												{
													_messages.push( "Ты спас принцессу!\nСпасибо тебе!" );
													_messages.push( "Но ты можешь продолжить\nприключение и убить\nбольше драконов!" );
												}
												else _messages.push( "Как насчет еще одного?" );
											}
										}
									}
									if (a==1 && _pot>0) { d_pot(-1); d_hp(10); }
								}
							}

			if (_messages.size()>0)
				if (160-20 <= xx && xx < 160+20 && 130 <= yy && yy < 150)
					if (IE->mouse_pressed( 0, true, false ))
					{
						_messages.pop();
						if (_messages.size()==0 && _evs[_cur_e].type != xrpg::EVENT_ROGUES)
						{
							if (_hp==0)
							{
								_state = xrpg::STATE_GAME_OVER;
								_cntd = 100;
							}
							else
							{
								_state = xrpg::STATE_DECREASE;
								_cntd = 100;
							}
						}
					}
		}
		else if (_state == xrpg::STATE_DECREASE)
		{
			_cntd-=5;
			if (_cntd==0)
			{
				_state = xrpg::STATE_GOTO_NEXT;
				_cntd = 100;
				if (_cur_e==7)
				{
					_cur_e=0;
					_world++;
					_state = xrpg::STATE_WORLD;
				}
			}
		}

		return true;
	}

	void ZXRPG::draw_frame( XInputEngine * IE, XGraphicEngine * GE )
	{
		_frame++;
		if (_frame == 128) _frame = 0;
		int _anim = _frame/32;
		if (_anim == 3) _anim = 1;

		if (_state == xrpg::STATE_BEGIN)
		{
			GE->set_texture( xrpg::TEXTURE_TITLE );
			GE->draw_pict( ge::PICT( 0.f, 40.f, 320.f, 160.f ) );

			GE->set_texture( xrpg::TEXTURE_SYSTEM );
			GE->draw_pict( ge::PICT( 40.f, 60.f, 240.f, 120.f ).set_tex( 0.f, 0.f, 0.25f, 0.25f ).
				mul_to_color( 1.f, 1.f, 1.f, 0.7f ) );

			GE->write( 160.f,   5.f, "Tiny RPG", 1.f, 1.f, 1.f );
			GE->write( 160.f,  20.f, "специально для IGDC 104 - RPG II", 0.4f, 0.4f, 0.4f );

			GE->write( 160.f, 70.f,
				"Ты - храбрый рыцарь\n"
				"и ты должен вызволить принцессу\n"
				"из замка злобного дракона!"
				, 1.f, 1.f, 1.f );

			GE->set_texture( xrpg::TEXTURE_CHARS );
			GE->draw_pict( ge::PICT( 100.f-12.f, 115.f, 24.f, 32.f ).set_tex( _anim*(0.25f/3), 0.25f, 0.25f/3, 0.25f ) );
			GE->draw_pict( ge::PICT( 160.f-12.f, 115.f, 24.f, 32.f ).set_tex( _anim*(0.25f/3), 0.75f, 0.25f/3, 0.25f ) );
			GE->draw_pict( ge::PICT( 220.f-12.f, 115.f, 24.f, 32.f ).set_tex( _anim*(0.25f/3), 0.5f, 0.25f/3, 0.25f ) );

			GE->write( 160.f, 155.f, "В путь же, герой!", 1.f, 1.f, 1.f );

			if (_anim&1)
				GE->write( 160.f, 205.f, "Кликните чтобы продолжить", 1.f, 1.f, 1.f );

			GE->write( 160.f,  220.f, "Ripatti Software (c) 2014", 0.4f, 0.4f, 0.4f );
		}
		else if (_state == xrpg::STATE_WORLD)
		{
			char ch[32];
			sprintf( ch, "World %d", _world );
			GE->write( 160.f, 90.f, ch, 1.f, 1.f, 1.f );

			GE->set_texture( xrpg::TEXTURE_CHARS );
			GE->draw_pict( ge::PICT( 140.f, 100.f, 24.f, 32.f ).set_tex( _anim*(0.25f/3), 0.25f, 0.25f/3, 0.25f ) );
			GE->write( 170.f, 115.f, "x1", 1.f, 1.f, 1.f );
		}
		else if (_state == xrpg::STATE_GAME_OVER)
		{
			GE->write( 160.f, 100.f, "GAME OVER", 1.f, 1.f, 1.f );

			if (_anim&1)
				GE->write( 160.f, 205.f, "Кликните чтобы продолжить", 1.f, 1.f, 1.f );
		}
		else
		{
			GE->set_texture( xrpg::TEXTURE_GRASS+(_world-1)%7 );
			GE->draw_pict( ge::PICT( 0.f, 60.f, 320.f, 160.f ) );

			GE->set_texture( xrpg::TEXTURE_SYSTEM );
			for (int a=0; a<7; a++)
				for (int b=0; b<4; b++)
					GE->draw_pict( ge::PICT( 20.f+40.f*a+10.f*b, 200.f, 5.f, 4.f ).set_tex( 0.75f, 0.f, 0.25f, 0.25f ) );

			GE->set_texture( xrpg::TEXTURE_ICONS );
			for (int a=0; a<6; a++)
				GE->draw_pict( ge::PICT( 50.f+40.f*a, 192.f, 20.f, 20.f ).set_tex( 0.f, 0.5f, 0.25f, 0.25f ) );
			GE->draw_pict( ge::PICT( 40.f+40.f*6, 172.f, 40.f, 40.f ).set_tex( 0.5f, 0.5f, 0.5f, 0.5f ) );

			GE->set_texture( xrpg::TEXTURE_ICONS );
			char ch[32];
			sprintf( ch, "World %d-%d  LVL %d  EXP %d/%d", _world, _cur_e, _lvl, _exp, _lvl*10 );
			GE->write( 160.f, 10.f, ch, 1.f, 1.f, 1.f );

			GE->draw_pict( ge::PICT( 165.f-150.f, 30.f, 20.f, 20.f ).set_tex( 0.5f, 0.f, 0.25f, 0.25f ) );
			sprintf( ch, "%d", _hp );
			GE->write( 200.f-150.f, 35.f, ch, 1.f, 1.f, 1.f );

			GE->draw_pict( ge::PICT( 165.f-90.f, 30.f, 20.f, 20.f ).set_tex( 0.f, 0.f, 0.25f, 0.25f ) );
			sprintf( ch, "%d", get_atk() );
			GE->write( 200.f-90.f, 35.f, ch, 1.f, 1.f, 1.f );

			GE->draw_pict( ge::PICT( 165.f-30.f, 30.f, 20.f, 20.f ).set_tex( 0.25f, 0.f, 0.25f, 0.25f ) );
			sprintf( ch, "%d", get_def() );
			GE->write( 200.f-30.f, 35.f, ch, 1.f, 1.f, 1.f );

			GE->draw_pict( ge::PICT( 165.f+30.f, 30.f, 20.f, 20.f ).set_tex( 0.f, 0.25f, 0.25f, 0.25f ) );
			sprintf( ch, "%d", _gld );
			GE->write( 200.f+30.f, 35.f, ch, 1.f, 1.f, 1.f );

			GE->draw_pict( ge::PICT( 165.f+90.f, 30.f, 20.f, 20.f ).set_tex( 0.75f, 0.f, 0.25f, 0.25f ) );
			sprintf( ch, "%d", _pot );
			GE->write( 200.f+90.f, 35.f, ch, 1.f, 1.f, 1.f );

			if (_state == xrpg::STATE_GOTO_NEXT)
			{
				int pos = 40*_cur_e + ((100-_cntd)*40)/100 + 8;
				GE->set_texture( xrpg::TEXTURE_CHARS );
				GE->draw_pict( ge::PICT( (float)pos, 172.f, 24.f, 32.f ).set_tex( _anim*(0.25f/3), 0.f, 0.25f/3, 0.25f ) );
			}
			else
			{
				int pos = 40*_cur_e + 8;
				GE->set_texture( xrpg::TEXTURE_CHARS );
				GE->draw_pict( ge::PICT( (float)pos, 172.f, 24.f, 32.f ).set_tex( (0.25f/3), 0.25f, 0.25f/3, 0.25f ) );
			}

			if (_state == xrpg::STATE_INCREASE || _state == xrpg::STATE_DECREASE || _state == xrpg::STATE_CUR_EVENT)
			{
				float alp = 1.f;
				if (_state == xrpg::STATE_INCREASE) alp = (100-_cntd)/100.f;
				else if (_state == xrpg::STATE_DECREASE) alp = _cntd/100.f;

				GE->set_texture( xrpg::TEXTURE_SYSTEM );
				int posx = 40*_cur_e + 8 + 12;
				GE->draw_pict( ge::PICT( posx + (40-posx)*alp - 1.f,
					202 + (55-202)*alp - 1.f, 240*alp + 2.f, 120*alp + 2.f ).
					set_tex( 0.75f, 0.f, 0.25f, 0.25f ) );
				GE->draw_pict( ge::PICT( posx + (40-posx)*alp, 202 + (55-202)*alp, 240*alp, 120*alp ).
					set_tex( 0.f, 0.f, 0.25f, 0.25f ) );

				if (_state == xrpg::STATE_CUR_EVENT)
				{
					GE->write( 160.f, 60.f, _evs[_cur_e].title.c_str(), 1.f, 1.f, 1.f );

					GE->set_texture( xrpg::TEXTURE_CHARS );
					GE->draw_pict( ge::PICT( 55.f, 80.f, 24.f, 32.f ).
						set_tex( _anim*(0.25f/3)+0.25f*_evs[_cur_e].tex_x, 0.25f*_evs[_cur_e].tex_y, 0.25f/3, 0.25f ) );

					GE->write( 175.f, 80.f, _evs[_cur_e].desc.c_str(), 1.f, 1.f, 1.f );

					int xx = IE->get_mouse_x()/2;
					int yy = IE->get_mouse_y()/2;
					GE->set_texture( xrpg::TEXTURE_SYSTEM );
					
					for (int a=0; a<3; a++)
						if (80+80*a-38 <= xx && xx < 80+80*a+38 && 130 <= yy && yy < 160)
						{
							GE->draw_pict( ge::PICT( 80.f+80.f*a-38.f, 130.f, 76.f, 30.f ).
								set_tex( 0.75f, 0.f, 0.25f, 0.25f ) );
							GE->draw_pict( ge::PICT( 80.f+80.f*a-37.f, 131.f, 74.f, 28.f ).
								set_tex( 0.f, 0.f, 0.25f, 0.25f ) );
							if (IE->mouse_pressed_now( 0 ))
								GE->draw_pict( ge::PICT( 80.f+80.f*a-37.f, 131.f, 74.f, 28.f ).
									set_tex( 0.75f, 0.f, 0.25f, 0.25f ).mul_to_color( 1.f, 1.f, 1.f, 0.5f ) );
						}

					if (_evs[_cur_e].type == xrpg::EVENT_SHOP)
					{
						GE->write(  80.f, 132.f, "Купить\nЗелье $20", 1.f, 1.f, 1.f );
						GE->write( 160.f, 132.f, "Лечение\n$100", 1.f, 1.f, 1.f );
						GE->write( 240.f, 132.f, "Покинуть\nмагазин", 1.f, 1.f, 1.f );
					}
					else if (_evs[_cur_e].type == xrpg::EVENT_FORGE)
					{
						GE->write(  80.f, 132.f, "+1 Атака\n$100", 1.f, 1.f, 1.f );
						GE->write( 160.f, 132.f, "+1 Защита\n$100", 1.f, 1.f, 1.f );
						GE->write( 240.f, 132.f, "Покинуть\nкузницу", 1.f, 1.f, 1.f );
					}
					else if (_evs[_cur_e].type == xrpg::EVENT_ROGUES)
					{
						GE->write(  80.f, 132.f, "Тренировка\n$100", 1.f, 1.f, 1.f );
						GE->write( 160.f, 132.f, "Играть\n$10", 1.f, 1.f, 1.f );
						GE->write( 240.f, 132.f, "Покинуть\nлагерь", 1.f, 1.f, 1.f );
					}
					else
					{
						GE->set_texture( xrpg::TEXTURE_ICONS );
						GE->draw_pict( ge::PICT( 130.f, 100.f, 20.f, 20.f ).set_tex( 0.5f, 0.f, 0.25f, 0.25f ) );
						sprintf( ch, "%d", _evs[_cur_e].hp );
						GE->write( 160.f, 105.f, ch, 1.f, 1.f, 1.f );

						GE->draw_pict( ge::PICT( 190.f, 100.f, 20.f, 20.f ).set_tex( 0.f, 0.f, 0.25f, 0.25f ) );
						sprintf( ch, "%d", _evs[_cur_e].atk );
						GE->write( 220.f, 105.f, ch, 1.f, 1.f, 1.f );

						//GE->draw_pict( ge::PICT( 220.f, 100.f, 20.f, 20.f ).set_tex( 0.25f, 0.f, 0.25f, 0.25f ) );
						//sprintf( ch, "%d", _evs[_cur_e].def );
						//GE->write( 250.f, 105.f, ch, 1.f, 1.f, 1.f );

						GE->write(  80.f, 132.f, "Атаковать\nврага!", 1.f, 1.f, 1.f );
						GE->write( 160.f, 132.f, "Выпить\nзелье", 1.f, 1.f, 1.f );
						if (_cur_e != 7) GE->write( 240.f, 132.f, "Сбежать", 1.f, 1.f, 1.f );
					}
				}
			}

			for (int a=0; a<(int)delta_vec.size(); a++)
				if (delta_vec[a].cntd > 0)
				{
					char ch[10];
					sprintf( ch, "%d", delta_vec[a].delta );
					if (delta_vec[a].delta>=0) sprintf( ch, "+%d", delta_vec[a].delta );
					GE->write( delta_vec[a].x+5.f, delta_vec[a].y-(100-delta_vec[a].cntd)*0.2f, ch,
						delta_vec[a].delta < 0 ? 1.f : 0.f, delta_vec[a].delta < 0 ? 0.f : 1.f, 0.f );
					delta_vec[a].cntd-=4;
				}

			if (_messages.size()>0)
			{
				GE->set_texture( xrpg::TEXTURE_SYSTEM );
				GE->draw_pict( ge::PICT( 160.f-100.f-1, 80.f-1, 202.f, 82.f ).
					set_tex( 0.75f, 0.f, 0.25f, 0.25f ) );
				GE->draw_pict( ge::PICT( 160.f-100.f, 80.f, 200.f, 80.f ).
					set_tex( 0.f, 0.f, 0.25f, 0.25f ) );

				GE->write( 160.f, 85.f, _messages.front().c_str(), 1.f, 1.f, 1.f );

				int xx = IE->get_mouse_x()/2;
				int yy = IE->get_mouse_y()/2;
				
				if (160-20 <= xx && xx < 160+20 && 130 <= yy && yy < 150)
				{
					GE->draw_pict( ge::PICT( 160.f-20.f, 130.f, 40.f, 20.f ).
						set_tex( 0.75f, 0.f, 0.25f, 0.25f ) );
					GE->draw_pict( ge::PICT( 160.f-19.f, 131.f, 38.f, 18.f ).
						set_tex( 0.f, 0.f, 0.25f, 0.25f ) );
					if (IE->mouse_pressed_now( 0 ))
						GE->draw_pict( ge::PICT( 160.f-19.f, 131.f, 38.f, 18.f ).
							set_tex( 0.75f, 0.f, 0.25f, 0.25f ).mul_to_color( 1.f, 1.f, 1.f, 0.5f ) );
				}
				GE->write( 160.f, 133.f, "OK", 1.f, 1.f, 1.f );
			}
		}
	}
};