/*
 * Copyright (C) 2007 askywhale
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License (version 2)
 *  as published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 */

package com.askywhale.rings;

import net.sf.j3d.threeD.raytracer.engine.AbstractSurface;
import net.sf.j3d.threeD.raytracer.engine.Intersection;
import net.sf.j3d.threeD.raytracer.engine.Ray;
import net.sf.j3d.threeD.raytracer.engine.RayTracingEngine;
import net.sf.j3d.util.graphics.RGB;
import net.sf.j3d.util.Vector;

public class SphereSurface extends AbstractSurface {

    public SphereSurface(Vector location, double radius) {
        super(location, radius);        
    }
    
    public SphereSurface(Vector location, double radius, RGB color) {
        super(location, radius, color);
    }
    
    public Vector getNormalAt(Vector point) {
        Vector normal = point.subtract(super.getLocation());
        normal = super.getTransform(true).transformAsNormal(normal);
        return normal;
    }
    
    public boolean intersect(Ray ray) {
        Ray newRay = new Ray(
                super.getTransform(true).getInverse().transformAsLocation(ray.getOrigin()),
                super.getTransform(true).getInverse().transformAsOffset(ray.getDirection()));
        
        Vector a = newRay.getOrigin();
        Vector d = newRay.getDirection();
        double b = d.dotProduct(a);
        double c = a.dotProduct(a);
        
        double discriminant = (b * b) - (d.dotProduct(d)) * (c - 1);
        
        if (discriminant < 0)
            return false;
        else
            return true;
    }
    
    public Intersection intersectAt(Ray ray) {
        Ray newRay = new Ray(
                super.getTransform(true).getInverse().transformAsLocation(ray.getOrigin()),
                super.getTransform(true).getInverse().transformAsOffset(ray.getDirection()));
        
        Vector a = newRay.getOrigin();
        Vector d = newRay.getDirection();
        double b = d.dotProduct(a);
        double c = a.dotProduct(a);
        
        double discriminant = (b * b) - (d.dotProduct(d)) * (c - 1);
        double discriminantSqrt = Math.sqrt(discriminant);
        
        double t[] = new double[2];
        
        t[0] = (-b + discriminantSqrt) / (d.dotProduct(d));
        t[1] = (-b - discriminantSqrt) / (d.dotProduct(d));
        return new Intersection(ray, this, t);
    }
    
    public double getIndexOfRefraction(Vector p) {
		double s = this.getSize();
		
		if (p.subtract(this.getLocation()).lengthSq() <= s * s + RayTracingEngine.e) {
			return super.getIndexOfRefraction();
		} else {
			return 1.0;
		}
	}

}
