// Includes
#include "SpaceShooterApp.h"

#include "Common.h"
#include "StateStart.h"
#include "StateEnd.h"
#include "StatePlay.h"
#include "ppLevel.h"
#include "ppAliens.h"
#include "ppPlayer.h"

// Namespace
using namespace AGK;

CSpaceShooterApp	SpaceShooter;

// constructor
CSpaceShooterApp::CSpaceShooterApp()
{ 
	ConnectApplication(this);
	SetupDevice(DEVICE_WIDTH, DEVICE_HEIGHT, FULLSCREEN);
	SetupTitle(TITLE);
}

void CSpaceShooterApp::Begin(void)
{
	// setup a virtual resolution
	agk::SetVirtualResolution(550, 400);

	// load media that we need global. (with id's)
	// IMGID_* and SFXID_* are defines (macros) there was defined 
	// befor in 'Common.h'
	agk::LoadImage(IMGID_PARTICLES		, "space/particle.png");
	agk::LoadImage(IMGID_GAMEFONT		, "space/ascii.png");
	agk::LoadImage(IMGID_ALIENSHIP		, "space/alienshipleft.png");
	agk::LoadImage(IMGID_ALIENPARTICLE	, "space/shrapnel3.png");
	agk::LoadImage(IMGID_BULLET			, "space/laser.png");

	agk::LoadSound(SFXID_LASER		, "space/laser.wav");
	agk::LoadSound(SFXID_EXPLOSION1	, "space/explode1.wav");
	agk::LoadSound(SFXID_EXPLOSION2	, "space/explode2.wav");
	agk::LoadSound(SFXID_EXPLOSION3	, "space/explode3.wav");
	agk::LoadSound(SFXID_HIT		, "space/playerhit.wav");

	// this game use only one font, so we can set it as default
	agk::SetTextDefaultFontImage(IMGID_GAMEFONT);

	// now create our 3 states. important they must be pointers.
	// CREATE are a macro, too. There was also defined in 'Common.h'.
	// The line 'CREATE(CStateStart());' will be replaced with -
	// (new (std::nothrow) CStateStart())
	CStateStart*	start	= CREATE(CStateStart());
	CStatePlay*		play	= CREATE(CStatePlay());
	CStateEnd*		end		= CREATE(CStateEnd());

	m_pScenery	= CREATE(CLevel());
	m_pAliens	= CREATE(CAliens());
	m_pPlayer	= CREATE(CPlayer());

	m_pPlayer->SetReferences(m_pScenery, m_pAliens);
	m_pPlayer->HidePlayer();

	// share some vars between states. m_p* are the main pointer.
	// m_ref* are references to the main pointer. if we have a pointer
	// from a class, you can use '->' to access the elements of this class.
	start->m_refAliens	= m_pAliens;

	play->m_refAliens	= m_pAliens;
	play->m_refPlayer	= m_pPlayer;

	end->m_refAliens	= m_pAliens;

	// register all state in the state machine. it is only an array of
	// class pointer.
	m_ppStates[EGS_Start]	= start;
	m_ppStates[EGS_Play]	= play;
	m_ppStates[EGS_End]		= end;

	// reset the current state
	m_ppStates[m_eCurrentState]->Reset();
}

void CSpaceShooterApp::Loop(void)
{
	// this is the main-loop to handle the whole game.
	// its run the curren state-class and return the new state.
	// if the state change, then reset the new state und make it to the 
	// current state.
	EGameState state = m_ppStates[m_eCurrentState]->Run(agk::GetFrameTime());
	if (state != m_eCurrentState)
	{
		m_ppStates[state]->Reset();
		m_eCurrentState = state;
	}

	// update the screen
	agk::Sync();
}


void CSpaceShooterApp::End(void)
{
	// release all states.
	for (int i = 0; i < EGS_StateCount; i++)
	{
		if (m_ppStates[i] != NULL)
			RELEASE(m_ppStates[i]);
	};

	RELEASE(m_pPlayer);
	RELEASE(m_pAliens);
	RELEASE(m_pScenery);
}

