#ifndef __RAY_STREAM_H__
#define __RAY_STREAM_H__

#include "RayBundle.h"

namespace VRUT
{
	class RayStream
	{
	public:
		struct RayData
		{
			Ray ray;
			Vector4 weight;
			int pixelIndex;
		};

	private:
		Vector4 weights[MAX_RAYS_IN_BUNDLE];
		int pixelIndices[MAX_RAYS_IN_BUNDLE];
		bool processed[MAX_RAYS_IN_BUNDLE];
		RayBundle topBundle;
		RayBundle bottomBundle;
		std::vector<RayData> rayData;

		void TransformDownUnit(unsigned int numberOfPackets);
		void TransformDown(const Matrix & matrix, unsigned int numberOfPackets);

	public:
		RayStream(void);
		~RayStream(void);
		unsigned int GetNumberOfRays() const
		{
			return topBundle.GetNumberOfRays();
		}
		const Ray * GetRays(void) const;
		const RayIntersectionInfo * GetRayIntersectionInfos(void) const;
		const Vector4 * GetWeights(void) const;
		const int * GetPixelIndices(void) const;
		RayBundle & GetTopBundle(void);
		RayBundle & GetBottomBundle(void);
		void PushRay(const Ray & ray, int pixelIndex, float weight);
		void PushRay(const Ray & ray, int pixelIndex, const Vector4 & weight);
		void Clear(void);
		bool RefillRays(void);
		void TransformDown(const BVHTop::BVHNodeInfo & nodeInfo, unsigned int numberOfPackets);
		void TransformUp(const BVHBottom & bvh, NODE_ID nodeID, const BVHTop::BVHNodeInfo & nodeInfo, unsigned int numberOfPackets);
		unsigned int TransformUpShadow(const BVHBottom & bvh, const BVHTop::BVHNodeInfo & nodeInfo, MaterialCache & materialCache, Vector4 lightColors[], float rayOffset, unsigned int numberOfPackets);
	};
}

#endif /* __RAY_STREAM_H__ */
