#ifndef MAIN_CODE_H_INCLUDED
#define MAIN_CODE_H_INCLUDED


#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#ifdef TARGET_ANDROID

#include <GLES/gl.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#endif

#include "boost/shared_ptr.hpp"
#include "boost/thread/thread.hpp"
#include "boost/assign.hpp"
#include "boost/bind.hpp"
#include "boost/asio.hpp"
#include "boost/signal.hpp"
#include "boost/random.hpp"

#include "include/Engine.h"

using namespace SE;

struct CAsteroidStruct
{
	int Health;
	float Angle;
	float AngularVelocity;
	vec2 CenterPos;
	vec2 Velocity;
	TRenderPair RenderPair;
};

struct CPlayer
{
	vec2 Pos;
	float Angle;
	vec2 Velocity;
	TRenderPair RenderPair;
};


struct CLaserStruct
{
	vec2 Pos;
	vec2 Dir;
	TRenderPair RenderPair;
};

enum CGameState
{
	GS_PLAY,
	GS_WON,
	GS_LOST
};

class TMyApplication : public TApplication
{
protected:

	//Game elements
	std::list<CAsteroidStruct> Asteroids;
	std::list<CLaserStruct> Lasers;
	CPlayer Player;

	//Minor
	boost::random::mt19937 RandomGenerator;
	bool TapIsDown;
	vec2 LastTap;
	TSimpleTimer LaserTimer;

	//Game score and state
	CGameState GameState;
	int Level;
	int Score;

	//Static graphics
	TTriangleList LevelScoreText;
	TTriangleList LevelMessageText;
	TRenderPair BackgroundRenderPair;


	CAsteroidStruct CreateAsteroid(vec2 pos, vec2 dir, int health);

	void CreateRandomAsteroid(vec2 pos, int health);

	void CreateAsteroidParts(vec2 pos, int newHealth);

	vec2 NormalizePos(vec2 pos);
	
	void RefreshPlayerPos();

	void AddNewLaser();
	void UpdatePlayerPosition(float scaledTime);
	void ProcessLaserHit();
	void ProcessPlayerCollisions();
	void ClearUnusedLasers();

	void RefreshScoreText();

public:
	bool Inited;

	TMyApplication() : TApplication(), Inited(false) { }

	
    virtual void InnerInit();
    
    virtual void InnerDeinit();
	
	virtual void InnerDraw();
	
	virtual void InnerUpdate(cardinal dt);

	virtual void InnerOnTapDown(vec2 p);
	
	virtual void InnerOnTapUp(vec2 p);

	virtual void InnerOnTapUpAfterMove(vec2 p);
	
	virtual void InnerOnMove(vec2 shift);
	 
	bool IsInited() { return Inited; }

	void InitLevel();


	

};


#endif