#ifndef INCLUDED_GAMESCREEN
#define INCLUDED_GAMESCREEN

#include <Math/Vector.h>
#include <Math/Point.h>
#include <Utility/Timer.h>
#include <Utility/FilePath.h>

#include <list>
#include <memory>

namespace Dubious {
namespace Renderer {
class Scene;
class Camera;
class ObjectRenderer;
class OutlinedObjectRenderer;
class ShadowRenderer;
class BillboardRenderer;
class Color;
class PngImage;
typedef std::shared_ptr<Scene> ScenePtr;
typedef std::shared_ptr<Camera> CameraPtr;
typedef std::shared_ptr<ObjectRenderer> ObjectRendererPtr;
typedef std::shared_ptr<OutlinedObjectRenderer> OutlinedObjectRendererPtr;
typedef std::shared_ptr<ShadowRenderer> ShadowRendererPtr;
typedef std::shared_ptr<BillboardRenderer> BillboardRendererPtr;
typedef std::shared_ptr<PngImage> PngImagePtr;
}
namespace Physics {
class World;
typedef std::shared_ptr<World> WorldPtr;
}
}

class AAssetManager;
class Object;
class Explosion;
class ModelStore;
class Weapon;
typedef std::shared_ptr<ModelStore> ModelStorePtr;
typedef std::shared_ptr<Object> ObjectPtr;
typedef std::shared_ptr<Explosion> ExplosionPtr;
typedef std::shared_ptr<Weapon> WeaponPtr;
typedef std::list<ObjectPtr> ObjectPtrList;
typedef std::list<ExplosionPtr> ExplosionPtrList;
typedef std::vector<WeaponPtr> WeaponPtrVector;

using namespace Dubious;

//////////////////////////////////////////////////////////////
class GameScreen 
{
public:
	GameScreen( AAssetManager& Manager, const Math::Size& Dimensions, const std::string& Path );
	~GameScreen();

	void				OnDraw();
	void				OnPhysics( float Elapsed );
	void				OnResetGL();
	void				OnMoveCamera( const Math::Point& Offset );
	void				OnZoomCamera( int Span );
	void				OnFireBtn( AAssetManager& Manager, float SliderPos, const Math::Point& Target );
	void				OnWeaponSelect( int Index );

//	void				OnResetScene();
//	void				OnExitScene();

	void				AddObject( ObjectPtr pObject );
	Renderer::CameraPtr	Camera() { return m_pCamera; }
	ModelStorePtr		GetModelStore() { return m_pModelStore; }
	Renderer::ObjectRendererPtr Renderer() { return m_pRenderer; }
	Renderer::ShadowRendererPtr ShadowRenderer() { return m_pShadowRenderer; }
	Math::Size			Dimensions() const { return m_Dimensions; }
	int					GetScore() const { return m_Score; }
	bool				SceneIsFinished() const { return m_PossibleScore == 0; }

private:
	GameScreen( const GameScreen& );
	GameScreen& operator=( const GameScreen& );

	void				ReadWeapons( AAssetManager& Manager );
	void				ResetScreen( AAssetManager& Manager, const std::string& Path );
	void				ShowSummary();

	Physics::WorldPtr 	m_pWorld;
	Renderer::ScenePtr 	m_pScene;
	Renderer::CameraPtr m_pCamera;
	Renderer::ObjectRendererPtr m_pRenderer;
	Renderer::OutlinedObjectRendererPtr m_pOutlinedRenderer;
	Renderer::ShadowRendererPtr m_pShadowRenderer;
	Renderer::BillboardRendererPtr m_pBillboardRenderer;
	Utility::Timer 		m_LoopTimer;
	Math::Size 			m_Dimensions;

	ModelStorePtr		m_pModelStore;
	int					m_FrameCount;
	int					m_FrameTimer;
	unsigned int		m_PhysicsBullet;
	unsigned int		m_PhysicsMaint;
	unsigned int		m_PhysicsHandling;

	ObjectPtr			m_pFloor;
	ObjectPtrList		m_Objects;
	ExplosionPtrList	m_Explosions;
	WeaponPtr			m_pWeapon;
	WeaponPtrVector		m_WeaponStore;
	Renderer::PngImagePtr m_pExplosionPng0;
	Renderer::PngImagePtr m_pExplosionPng1;
	int					m_Score;
	int					m_PossibleScore;

};

#endif
