// © Copyright 2008 Vladimir Frolov, Moscow State University Graphics & Media Lab
#pragma once

#ifndef MGML_GUARDIAN
	#include "../CSL/MGML.h"
#endif

#include "IGraphicsEngine.h"

//#ifndef KD_TREE_GUARDIAN
//  #include "kd_tree.h"
//#endif

//#ifndef HIERARCHICAL_GRID_GUARDIAN
//  #include "HierarchicalGrid.h"
//#endif

//#ifndef BVH_GUARDIAN
//  #include "BVH.h"
//#endif

namespace RAYTR
{
  class AccelerationStructure;
	class KdTree;
  class BVH_Tree;
  class HierarchicalGrid;
};

#include <memory>
#include <string>

using namespace MGML;
using namespace RAYTR;




class DLL_API Common_Graphics_Engine : public IGraphicsEngine,
							   public MGML_MATH::SSE_Aligned_Object
{
public:

	typedef unsigned int uint;

  Common_Graphics_Engine(int w,int h);
	~Common_Graphics_Engine();

	void BuildAccelerationStructures(uint in_maxNodes = IGraphicsEngine::MAX_KD_TREE_NODES);

	vec2ui AddTriangles(const Vertex4f* v,int N_vertices,
					     const unsigned int* indices,int N_indices);
	unsigned int AddSpheres(const Sphere4f* s,int N_spheres);
	uint AddPointLight(const PointLight& light);
	uint AddTexture(const void* memory,uint w,uint h,uint format);

	virtual uint	AddScene();
	virtual void	SetActiveScene(uint scnIndex);

	void SetPointLight(const PointLight& light,int index);

	void SetCamMatrix(const Matrix4x4f& mat);
  void MoveCam(const vec4f& pos);

	unsigned int AddMaterial(const Material& mat);

	const PointLight&	GetPointLight(int index) const;
	const Material&		GetMaterial(int index) const;
	const Matrix4x4f&	GetCamMatrix() const;

  BVH_Tree* GetBVHTree() { return m_bvhTree; }

  void DebugDrawAccelStruct();

protected:

  Matrix4x4f* pWorld_matrix;

	UINT*		 screen_buffer;
	int			 width;
	int			 height;

	Material*	  materials;
	int			    num_mat;

	Image*      textures;
	int			    num_textures;

	KdTree*     kd_tree;
  BVH_Tree*   m_bvhTree;
  HierarchicalGrid* m_pGrid;

  AccelerationStructure* m_pAccelStruct;

	PointLight* point_lights;
	int         num_point_lights;
	
	Sphere4f*	  spheres; 
	int			    num_sph;
	
	Vertex4f*   vert;
	int			    num_vert;

	UINT*		    index;
	int			    num_ind;

	unsigned int currScnIndex;
	unsigned int scnTop;

	/*struct Scene : public SSE_Aligned_Object
	{
		Scene();
		~Scene();

		KdTree*     kd_tree;
    BVH_Tree*   m_bvhTree;

		PointLight* point_lights;
		int         num_point_lights;
	
		Sphere4f*	  spheres; 
		int			    num_sph;
	
		Vertex4f*   vert;
		int			    num_vert;

		UINT*		    index;
		int			    num_ind;
	};

	Scene* scns;*/
};

extern DLL_API Ray3f g_debugRay;