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

#include "IGraphicsEngine.h"
//#include "Common_Graphics_Engine.h"
#include "Ray_Tracer.h"

#ifndef RTLIB_GUARDIAN
	#include "rtlib.h"
#endif

using namespace MGML_ERROR;

class DLL_API GPU_Ray_Tracer: public Ray_Tracer // ,public Singleton
{
	typedef IGraphicsEngine Interface;
	typedef Ray_Tracer		Base;

public:

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

	void BeginDrawScene(unsigned int trace_depth, bool shadows);			// account multithreading
	void EndDrawScene();			// account multithreading

  void BeginDrawScene(const Ray3f* a_rays, int a_maxSize, int a_traceDepth, bool a_shadows);	
  void GetColorsToBuffer(vec4f* a_colors, int a_maxSize);			                  

	void BuildAccelerationStructures(uint in_maxNodes = MAX_KD_TREE_NODES);

	void SetActiveScene(unsigned int scnIndex);
	void SetCamMatrix(const Matrix4x4f& mat);

  void PrintPerfInfo(std::ostream& out);

	Ray_Tracer::RT_Core* GetRTCore();

	class DLL_API RT_Core : public Base::RT_Core
	{
	public:
		//typedef Ray3f Ray;
		//typedef Lite_Hit Hit;

		void TraverseRays(Ray* in_out_rays, RAYTR::Hit* out_hits, size_t in_N);
		void TraverseRays(Ray* in_out_rays, RAYTR::Hit* out_hits, size_t in_width, size_t in_height);
	};

protected:
	virtual GPU_Ray_Tracer& operator=(const GPU_Ray_Tracer& x)
	{ 
		throw Error("GPU_Ray_Tracer:: Atempt to call protected operator=() "); 
		return (GPU_Ray_Tracer&)x;
	}

	void CopyDynamicDataToGPU();
  RT_Core m_core;



	GLUquadricObj* QuadrObj; 
};