#include <stdlib.h>
#include <math.h>

#include "./defines.hpp"
#include "./vec3.hpp"
#include "./ray.hpp"
#include "./material.hpp"
#include "./sphere.hpp"

namespace raytracer{

vec3 sphere::get_sphere_normal_at(const vec3& point, const vec3& center)
{
  return point.add(center.negative()).normalize();
};

double sphere::find_sphere_intersection_length(const ray& ray, const vec3& center, const double radius)
{
  vec3 d= ray.origin.add(center.negative());

  double c= d.dot(d)-radius*radius,
         b= d.dot(ray.direction),
         t= b*b-c;

  if(t< 0) return -1;
  
  double st= sqrt(t);
  t= -b-st-ACCURACY;

  if(t<= 0) t= -b+st-ACCURACY;
    
  return t;
};

bool sphere::intersects(const ray& ray, double& length, vec3& normal, material& material) const
{
  double len= sphere::find_sphere_intersection_length(ray, this->pos_, this->radius_);
  if(len< ACCURACY) return false;
  length= len;
  normal= sphere::get_sphere_normal_at(ray.origin.add(ray.direction.scale(len)), this->pos_);
  material= *this->material_;
  return true;
};
  
}
