// *********************************************************
// Ray Tracer Class
// Author : Tamy Boubekeur (boubek@gmail.com).
// Copyright (C) 2012 Tamy Boubekeur.
// All rights reserved.
// *********************************************************

#ifndef RAYTRACER_H
#define RAYTRACER_H

#include <iostream>
#include <vector>
#include <QImage>
#include <QWidget>

#include "Vec3D.h"
#include "Color.h"

class Material;
class Scene;
class Ray;

struct SRenderParameters
{
    struct CameraProperties
    {
        Vec3Df pos, dir, up, right;
        float fov, aspect;

        CameraProperties() : fov(0), aspect(0) {}
    } cam;
    struct ScreenProperties
    {
        unsigned int width, height;
        unsigned int aaX, aaY;
        bool aaEnabled;

        ScreenProperties() : width(0), height(0), aaX(1), aaY(1), aaEnabled(false) {}
    } screen;
    struct DepthOfFieldProperties
    {
        int quality;
        float aperture;
        float focusDistance;
        bool enabled;

        DepthOfFieldProperties() : quality(0), aperture(0), focusDistance(0), enabled(false) {}
    } dof;
};

class RayTracer
{
public:
    static RayTracer * getInstance ();
    static void destroyInstance ();

    inline const Colorf& getBackgroundColor () const { return backgroundColor;}
    inline void setBackgroundColor (const Colorf& c) { backgroundColor = c; }

    void render (QImage& image,
                 const SRenderParameters& rp,
                 QWidget *parent = 0
                 );
    Colorf computeRayColor(const Ray& ray, const Scene* scene, unsigned int depth);
    void renderDofPreview(QImage& image,
                          const SRenderParameters& rp);

    void usePathTracing(bool b) { pathTracing = b; }
    bool isPathTracingUsed() const { return pathTracing; }

    void setRaytraceLights(bool b) { raytraceLights = b; }
    bool lightsAreRaytraced() const { return raytraceLights; }

    unsigned int getMaxDepth() const { return maxDepth; }
    bool canCastRay(unsigned int depth) const { return depth < maxDepth; }

protected:
    inline RayTracer () : overrideMaterial(0), maxDepth(4), pathTracing(false), raytraceLights(true) {}
    inline virtual ~RayTracer () {}

private:
    Colorf backgroundColor;
    Material* overrideMaterial;
    unsigned int maxDepth;
    bool pathTracing, raytraceLights;
};


#endif // RAYTRACER_H

// Some Emacs-Hints -- please don't remove:
//
//  Local Variables:
//  mode:C++
//  tab-width:4
//  End:
