//-------------------------------------------------------------------------------
///
/// \file       lights.h
/// \author     Cem Yuksel (www.cemyuksel.com)
/// \version    3.0
/// \date       August 21, 2019
///
/// \brief Example source for CS 6620 - University of Utah.
///
//-------------------------------------------------------------------------------
 
#ifndef _LIGHTS_H_INCLUDED_
#define _LIGHTS_H_INCLUDED_
 
#include "scene.h"
 
//-------------------------------------------------------------------------------
 
class GenLight : public Light
{
protected:
    void SetViewportParam(int lightID, ColorA ambient, ColorA intensity, Vec4f pos ) const;
    static float Shadow(Ray ray, float t_max=BIGFLOAT);
};
 
//-------------------------------------------------------------------------------
 
class AmbientLight : public GenLight
{
public:
    AmbientLight() : intensity(0,0,0) {}
    virtual Color Illuminate(Vec3f const &p, Vec3f const &N) const { return intensity; }
    virtual Vec3f Direction(Vec3f const &p) const { return Vec3f(0,0,0); }
    virtual bool IsAmbient() const { return true; }
    virtual void SetViewportLight(int lightID) const { SetViewportParam(lightID,ColorA(intensity),ColorA(0.0f),Vec4f(0,0,0,1)); }
 
    void SetIntensity(Color intens) { intensity=intens; }
private:
    Color intensity;
};
 
//-------------------------------------------------------------------------------
 
class DirectLight : public GenLight
{
public:
    DirectLight() : intensity(0,0,0), direction(0,0,1) {}
    virtual Color Illuminate(Vec3f const &p, Vec3f const &N) const { return Shadow(Ray(p,-direction)) * intensity; }
    virtual Vec3f Direction(Vec3f const &p) const { return direction; }
    virtual void SetViewportLight(int lightID) const { SetViewportParam(lightID,ColorA(0.0f),ColorA(intensity),Vec4f(-direction,0.0f)); }
 
    void SetIntensity(Color intens) { intensity=intens; }
    void SetDirection(Vec3f dir) { direction=dir.GetNormalized(); }
private:
    Color intensity;
    Vec3f direction;
};
 
//-------------------------------------------------------------------------------
 
class PointLight : public GenLight
{
public:
    PointLight() : intensity(0,0,0), position(0,0,0) {}
    virtual Color Illuminate(Vec3f const &p, Vec3f const &N) const { return Shadow(Ray(p,position-p),1) * intensity; }
    virtual Vec3f Direction(Vec3f const &p) const { return (p-position).GetNormalized(); }
    virtual void SetViewportLight(int lightID) const { SetViewportParam(lightID,ColorA(0.0f),ColorA(intensity),Vec4f(position,1.0f)); }
    void SetIntensity(Color intens) { intensity=intens; }
    void SetPosition(Vec3f pos) { position=pos; }
 
private:
    Color intensity;
    Vec3f position;
};
 
//-------------------------------------------------------------------------------
 
#endif