//----------------------------------------------------------------------------
// William Baxter III's Ray Tracer
//
//     Project for Comp 238, Raster Graphics
//     University of North Carolina at Chapel Hill
//     
// $Id:$
//----------------------------------------------------------------------------

#include <math.h>
#include "wb3PointLight.hpp"
#include "wb3Material.hpp"
#include "wb3Artifact.hpp"
#include "wb3Scene.hpp"

//----------------------------------------------------------------------------
wb3PointLight::wb3PointLight(const Vec3f& position)
  : wb3Light()
{
  m_pos = position;
}
//----------------------------------------------------------------------------
wb3PointLight::wb3PointLight(const Vec3f& color,const Vec3f& position)
  : wb3Light(color)
{
  m_pos = position;
}
//----------------------------------------------------------------------------


// Computes the local portion of the illumination for a point
void wb3PointLight::Contribute(
  const wb3Scene *scene, const wb3Artifact *hit,
  const Ray3f& I, 
  const Vec3f &isect, 
  const Vec3f &N, Vec3f& color) const
{
  Vec3f toLight = GetPosition() - isect;
  float scale = N * toLight;
  if (scale > 0) { // SCALE IS NOT NORMALIZED YET!!
    // the light is on the front side.
    float toLightDist = toLight.Length();
    // Make sure nothing else is in the way
    toLight /= toLightDist;
    Ray3f shadowRay(isect, toLight);
    float dist;
    if (!GetShadowing() || 
        !scene->Intersect(shadowRay, &dist, hit) ||
        dist > toLightDist)
    {
      // Diffuse component
      scale /= toLightDist; // normalize scale
      Vec3f hC;// color at hit
      color += scale * GetColor() & hit->GetDiffuse(hC, isect);

      // Specular component
      Vec3f R = I.V() + 2.0f * (-I.V() * N) * N; // reflected direction
      scale = float(pow(toLight * R, hit->GetSpecularity(isect)));
      color += scale * GetColor() & hit->GetSpecular(hC,isect);
    }
  }
}

