// The ray tracer code in this file is written by Adam Burmister. It
// is available in its original form from:
//
//   http://labs.flog.nz.co/raytracer/
//
// It has been modified slightly by Google to work as a standalone
// benchmark, but the all the computational code remains
// untouched. This file also contains a copy of parts of the Prototype
// JavaScript framework which is used by the ray tracer.

// Variable used to hold a number that can be used to verify that
// the scene was ray traced correctly.
var checkNumber;


// ------------------------------------------------------------------------
// ------------------------------------------------------------------------

// The following is a copy of parts of the Prototype JavaScript library:

// Prototype JavaScript framework, version 1.5.0
// (c) 2005-2007 Sam Stephenson
//
// Prototype is freely distributable under the terms of an MIT-style license.
// For details, see the Prototype web site: http://prototype.conio.net/

var Class = {
    create: function() {
        return function() {
            try {
                this.initialize.apply(this, arguments);
            } catch(e) { }
        }
    }
};


Object.extend = function(destination, source) {
    for (var property in source) {
        try {
            destination[property] = source[property];
        } catch(e) { }
    }
    return destination;
};


// ------------------------------------------------------------------------
// ------------------------------------------------------------------------

// The rest of this file is the actual ray tracer written by Adam
// Burmister. It's a concatenation of the following files:
//
//   flog/color.js
//   flog/light.js
//   flog/vector.js
//   flog/ray.js
//   flog/scene.js
//   flog/material/basematerial.js
//   flog/material/solid.js
//   flog/material/chessboard.js
//   flog/shape/baseshape.js
//   flog/shape/sphere.js
//   flog/shape/plane.js
//   flog/intersectioninfo.js
//   flog/camera.js
//   flog/background.js
//   flog/engine.js


/* Fake a Flog.* namespace */
if(typeof(Flog) == 'undefined') var Flog = {};
if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};

Flog.RayTracer.Color = Class.create();

Flog.RayTracer.Color.prototype = {
    red : 0.0,
    green : 0.0,
    blue : 0.0,

    initialize : function(r, g, b) {
        try {
            if(!r) r = 0.0;
            if(!g) g = 0.0;
            if(!b) b = 0.0;

            this.red = r;
            this.green = g;
            this.blue = b;
        } catch(e) { }
    },

    add : function(c1, c2){
        try {
            var result = new Flog.RayTracer.Color(0,0,0);

            result.red = c1.red + c2.red;
            result.green = c1.green + c2.green;
            result.blue = c1.blue + c2.blue;

        } catch(e) { }

        return result;
    },

    addScalar: function(c1, s){
        try {
            var result = new Flog.RayTracer.Color(0,0,0);

            result.red = c1.red + s;
            result.green = c1.green + s;
            result.blue = c1.blue + s;

            result.limit();

        } catch(e) { }

        return result;
    },

    subtract: function(c1, c2){
        try {
            var result = new Flog.RayTracer.Color(0,0,0);

            result.red = c1.red - c2.red;
            result.green = c1.green - c2.green;
            result.blue = c1.blue - c2.blue;

        } catch(e) { }

        return result;
    },

    multiply : function(c1, c2) {
        try {
            var result = new Flog.RayTracer.Color(0,0,0);

            result.red = c1.red * c2.red;
            result.green = c1.green * c2.green;
            result.blue = c1.blue * c2.blue;

        } catch(e) { }

        return result;
    },

    multiplyScalar : function(c1, f) {
        try {
            var result = new Flog.RayTracer.Color(0,0,0);

            result.red = c1.red * f;
            result.green = c1.green * f;
            result.blue = c1.blue * f;

        } catch(e) { }

        return result;
    },

    divideFactor : function(c1, f) {
        try {
            var result = new Flog.RayTracer.Color(0,0,0);

            result.red = c1.red / f;
            result.green = c1.green / f;
            result.blue = c1.blue / f;

        } catch(e) { }

        return result;
    },

    limit: function(){
        try { 
            this.red = (this.red > 0.0) ? ( (this.red > 1.0) ? 1.0 : this.red ) : 0.0;
            this.green = (this.green > 0.0) ? ( (this.green > 1.0) ? 1.0 : this.green ) : 0.0;
            this.blue = (this.blue > 0.0) ? ( (this.blue > 1.0) ? 1.0 : this.blue ) : 0.0;

        } catch(e) { }
    },

    distance : function(color) {
        try {
            var d = Math.abs(this.red - color.red) + Math.abs(this.green - color.green) + Math.abs(this.blue - color.blue);
        } catch(e) { }
        return d;
    },

    blend: function(c1, c2, w){
        try {
            var result = new Flog.RayTracer.Color(0,0,0);
            result = Flog.RayTracer.Color.prototype.add(
                    Flog.RayTracer.Color.prototype.multiplyScalar(c1, 1 - w),
                    Flog.RayTracer.Color.prototype.multiplyScalar(c2, w)
                    );
        } catch(e) { }
        return result;
    },

    brightness : function() {
        try {
            var r = Math.floor(this.red*255);
            var g = Math.floor(this.green*255);
            var b = Math.floor(this.blue*255);
        } catch(e) { }
        return (r * 77 + g * 150 + b * 29) >> 8;
    },

    toString : function () {
        try {
            var r = Math.floor(this.red*255);
            var g = Math.floor(this.green*255);
            var b = Math.floor(this.blue*255);
        } catch(e) { }

        return "rgb("+ r +","+ g +","+ b +")";
    }
}
/* Fake a Flog.* namespace */
if(typeof(Flog) == 'undefined') var Flog = {};
if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};

Flog.RayTracer.Light = Class.create();

Flog.RayTracer.Light.prototype = {
    position: null,
    color: null,
    intensity: 10.0,

    initialize : function(pos, color, intensity) {
        try {
            this.position = pos;
            this.color = color;
            this.intensity = (intensity ? intensity : 10.0);

        } catch(e) { }
    },

    toString : function () {
        try {
            var result = 'Light [' + this.position.x + ',' + this.position.y + ',' + this.position.z + ']';
        } catch(e) { }
        return result;
    }
}
/* Fake a Flog.* namespace */
if(typeof(Flog) == 'undefined') var Flog = {};
if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};

Flog.RayTracer.Vector = Class.create();

Flog.RayTracer.Vector.prototype = {
    x : 0.0,
    y : 0.0,
    z : 0.0,

    initialize : function(x, y, z) {
        try {
            this.x = (x ? x : 0);
            this.y = (y ? y : 0);
            this.z = (z ? z : 0);
        } catch(e) { }
    },

    copy: function(vector){
        try {
            this.x = vector.x;
            this.y = vector.y;
            this.z = vector.z;
        } catch(e) { }
    },

    normalize : function() {
        try {
            var m = this.magnitude();
            var result = new Flog.RayTracer.Vector(this.x / m, this.y / m, this.z / m);
        } catch(e) { }
        return result;
    },

    magnitude : function() {
        try {
            return Math.sqrt((this.x * this.x) + (this.y * this.y) + (this.z * this.z));
        } catch(e)  { }
    },

    cross : function(w) {
        try {
            return new Flog.RayTracer.Vector(
                    -this.z * w.y + this.y * w.z,
                    this.z * w.x - this.x * w.z,
                    -this.y * w.x + this.x * w.y);
        } catch(e) { }
    },

    dot : function(w) {
        try {
            return this.x * w.x + this.y * w.y + this.z * w.z;
        } catch(e) { }
    },

    add : function(v, w) {
        try {
            return new Flog.RayTracer.Vector(w.x + v.x, w.y + v.y, w.z + v.z);
        } catch(e) { }
    },

    subtract : function(v, w) {
        try {
            if(!w || !v) throw 'Vectors must be defined [' + v + ',' + w + ']';
            return new Flog.RayTracer.Vector(v.x - w.x, v.y - w.y, v.z - w.z);
        } catch(e) { }
    },

    multiplyVector : function(v, w) {
        try {
            return new Flog.RayTracer.Vector(v.x * w.x, v.y * w.y, v.z * w.z);
        } catch(e) { }
    },

    multiplyScalar : function(v, w) {
        try {
            return new Flog.RayTracer.Vector(v.x * w, v.y * w, v.z * w);
        } catch(e) { }
    },

    toString : function () {
        try {
            return 'Vector [' + this.x + ',' + this.y + ',' + this.z + ']';
        } catch(e) { }
    }
}
/* Fake a Flog.* namespace */
if(typeof(Flog) == 'undefined') var Flog = {};
if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};

Flog.RayTracer.Ray = Class.create();

Flog.RayTracer.Ray.prototype = {
    position : null,
    direction : null,
    initialize : function(pos, dir) {
        try {
            this.position = pos;
            this.direction = dir;
        } catch(e) { }
    },

    toString : function () {
        try {
            return 'Ray [' + this.position + ',' + this.direction + ']';
        } catch(e) { }
    }
}
/* Fake a Flog.* namespace */
if(typeof(Flog) == 'undefined') var Flog = {};
if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};

Flog.RayTracer.Scene = Class.create();

Flog.RayTracer.Scene.prototype = {
    camera : null,
    shapes : [],
    lights : [],
    background : null,

    initialize : function() {
        try {
            this.camera = new Flog.RayTracer.Camera(
                    new Flog.RayTracer.Vector(0,0,-5),
                    new Flog.RayTracer.Vector(0,0,1),
                    new Flog.RayTracer.Vector(0,1,0)
                    );
            this.shapes = new Array();
            this.lights = new Array();
            this.background = new Flog.RayTracer.Background(new Flog.RayTracer.Color(0,0,0.5), 0.2);

        } catch(e) { }
    }
}
/* Fake a Flog.* namespace */
if(typeof(Flog) == 'undefined') var Flog = {};
if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
if(typeof(Flog.RayTracer.Material) == 'undefined') Flog.RayTracer.Material = {};

Flog.RayTracer.Material.BaseMaterial = Class.create();

Flog.RayTracer.Material.BaseMaterial.prototype = {

    gloss: 2.0,             // [0...infinity] 0 = matt
    transparency: 0.0,      // 0=opaque
    reflection: 0.0,        // [0...infinity] 0 = no reflection
    refraction: 0.50,
    hasTexture: false,

    initialize : function() {

    },

    getColor: function(u, v){

    },

    wrapUp: function(t){
        try {
            t = t % 2.0;
            if(t < -1) t += 2.0;
            if(t >= 1) t -= 2.0;
        } catch(e) { }
        return t;
    },

    toString : function () {
        try {
            return 'Material [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
        } catch(e) { }
    }
}
/* Fake a Flog.* namespace */
if(typeof(Flog) == 'undefined') var Flog = {};
if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};

Flog.RayTracer.Material.Solid = Class.create();

Flog.RayTracer.Material.Solid.prototype = Object.extend(
        new Flog.RayTracer.Material.BaseMaterial(), {
            initialize : function(color, reflection, refraction, transparency, gloss) {
                try {
                    this.color = color;
                    this.reflection = reflection;
                    this.transparency = transparency;
                    this.gloss = gloss;
                    this.hasTexture = false;
                } catch(e) { }
            },

            getColor: function(u, v){
                try {
                    return this.color;
                } catch(e) { }
            },

            toString : function () {
                try {
                    return 'SolidMaterial [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
                } catch(e) { }
            }
        }
        );
/* Fake a Flog.* namespace */
if(typeof(Flog) == 'undefined') var Flog = {};
if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};

Flog.RayTracer.Material.Chessboard = Class.create();

Flog.RayTracer.Material.Chessboard.prototype = Object.extend(
        new Flog.RayTracer.Material.BaseMaterial(), {
            colorEven: null,
            colorOdd: null,
            density: 0.5,

            initialize : function(colorEven, colorOdd, reflection, transparency, gloss, density) {
                try {
                    this.colorEven = colorEven;
                    this.colorOdd = colorOdd;
                    this.reflection = reflection;
                    this.transparency = transparency;
                    this.gloss = gloss;
                    this.density = density;
                    this.hasTexture = true;
                } catch(e) { }
            },

            getColor: function(u, v){
                try {
                    var t = this.wrapUp(u * this.density) * this.wrapUp(v * this.density);
                } catch(e) { }

                if(t < 0.0)
                    return this.colorEven;
                else
                    return this.colorOdd;
            },

            toString : function () {
                try {
                    return 'ChessMaterial [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
                } catch(e) { }
            }
        }
);
/* Fake a Flog.* namespace */
if(typeof(Flog) == 'undefined') var Flog = {};
if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
if(typeof(Flog.RayTracer.Shape) == 'undefined') Flog.RayTracer.Shape = {};

Flog.RayTracer.Shape.Sphere = Class.create();

Flog.RayTracer.Shape.Sphere.prototype = {
    initialize : function(pos, radius, material) {
        try {
            this.radius = radius;
            this.position = pos;
            this.material = material;

        } catch(e) { }
    },

    intersect: function(ray){
        try {
            var info = new Flog.RayTracer.IntersectionInfo();
            info.shape = this;

            var dst = Flog.RayTracer.Vector.prototype.subtract(ray.position, this.position);

            var B = dst.dot(ray.direction);
            var C = dst.dot(dst) - (this.radius * this.radius);
            var D = (B * B) - C;

            if(D > 0){ // intersection!
                info.isHit = true;
                info.distance = (-B) - Math.sqrt(D);
                info.position = Flog.RayTracer.Vector.prototype.add(
                        ray.position,
                        Flog.RayTracer.Vector.prototype.multiplyScalar(
                            ray.direction,
                            info.distance
                            )
                        );
                info.normal = Flog.RayTracer.Vector.prototype.subtract(
                        info.position,
                        this.position
                        ).normalize();

                info.color = this.material.getColor(0,0);
            } else {
                info.isHit = false;
            }

        } catch(e) { }
        return info;
    },

    toString : function () {
        try {
            return 'Sphere [position=' + this.position + ', radius=' + this.radius + ']';
        } catch(e) { }
    }
}
/* Fake a Flog.* namespace */
if(typeof(Flog) == 'undefined') var Flog = {};
if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
if(typeof(Flog.RayTracer.Shape) == 'undefined') Flog.RayTracer.Shape = {};

Flog.RayTracer.Shape.Plane = Class.create();

Flog.RayTracer.Shape.Plane.prototype = {
    d: 0.0,

    initialize : function(pos, d, material) {
        try {
            this.position = pos;
            this.d = d;
            this.material = material;
        } catch(e) { }
    },

    intersect: function(ray){
        try {
            var info = new Flog.RayTracer.IntersectionInfo();

            var Vd = this.position.dot(ray.direction);
            if(Vd == 0) return info; // no intersection

            var t = -(this.position.dot(ray.position) + this.d) / Vd;
            if(t <= 0) return info;

            info.shape = this;
            info.isHit = true;
            info.position = Flog.RayTracer.Vector.prototype.add(
                    ray.position,
                    Flog.RayTracer.Vector.prototype.multiplyScalar(
                        ray.direction,
                        t
                        )
                    );
            info.normal = this.position;
            info.distance = t;

            if(this.material.hasTexture){
                var vU = new Flog.RayTracer.Vector(this.position.y, this.position.z, -this.position.x);
                var vV = vU.cross(this.position);
                var u = info.position.dot(vU);
                var v = info.position.dot(vV);
                info.color = this.material.getColor(u,v);
            } else {
                info.color = this.material.getColor(0,0);
            }

        } catch(e) { }
        return info;
    },

    toString : function () {
        try {
            return 'Plane [' + this.position + ', d=' + this.d + ']';
        } catch(e) { }
    }
}
/* Fake a Flog.* namespace */
if(typeof(Flog) == 'undefined') var Flog = {};
if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};

Flog.RayTracer.IntersectionInfo = Class.create();

Flog.RayTracer.IntersectionInfo.prototype = {
    isHit: false,
    hitCount: 0,
    shape: null,
    position: null,
    normal: null,
    color: null,
    distance: null,

    initialize : function() {
        try {
            this.color = new Flog.RayTracer.Color(0,0,0);
        } catch(e) { }
    },

    toString : function () {
        try {
            return 'Intersection [' + this.position + ']';
        } catch(e) { }
    }
}
/* Fake a Flog.* namespace */
if(typeof(Flog) == 'undefined') var Flog = {};
if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};

Flog.RayTracer.Camera = Class.create();

Flog.RayTracer.Camera.prototype = {
    position: null,
    lookAt: null,
    equator: null,
    up: null,
    screen: null,

    initialize : function(pos, lookAt, up) {
        try {
            this.position = pos;
            this.lookAt = lookAt;
            this.up = up;
            this.equator = lookAt.normalize().cross(this.up);
            this.screen = Flog.RayTracer.Vector.prototype.add(this.position, this.lookAt);
        } catch(e) { }
    },

    getRay: function(vx, vy){
        try {
            var pos = Flog.RayTracer.Vector.prototype.subtract(
                    this.screen,
                    Flog.RayTracer.Vector.prototype.subtract(
                        Flog.RayTracer.Vector.prototype.multiplyScalar(this.equator, vx),
                        Flog.RayTracer.Vector.prototype.multiplyScalar(this.up, vy)
                        )
                    );
            pos.y = pos.y * -1;
            var dir = Flog.RayTracer.Vector.prototype.subtract(
                    pos,
                    this.position
                    );

            var ray = new Flog.RayTracer.Ray(pos, dir.normalize());

        } catch(e) { }
        return ray;
    },

    toString : function () {
        try {
            return 'Ray []';
        } catch(e) { }
    }
}
/* Fake a Flog.* namespace */
if(typeof(Flog) == 'undefined') var Flog = {};
if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};

Flog.RayTracer.Background = Class.create();

Flog.RayTracer.Background.prototype = {
    color : null,
    ambience : 0.0,

    initialize : function(color, ambience) {
        try {
            this.color = color;
            this.ambience = ambience;
        } catch(e) { }
    }
}
/* Fake a Flog.* namespace */
if(typeof(Flog) == 'undefined') var Flog = {};
if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};

Flog.RayTracer.Engine = Class.create();

Flog.RayTracer.Engine.prototype = {
    canvas: null, /* 2d context we can render to */

    initialize: function(options){
        try {
            this.options = Object.extend({
                canvasHeight: 100,
                canvasWidth: 100,
                pixelWidth: 2,
                pixelHeight: 2,
                renderDiffuse: false,
                renderShadows: false,
                renderHighlights: false,
                renderReflections: false,
                rayDepth: 2
            }, options || {});

            this.options.canvasHeight /= this.options.pixelHeight;
            this.options.canvasWidth /= this.options.pixelWidth;

        } catch(e) { }

        /* TODO: dynamically include other scripts */
    },

    setPixel: function(x, y, color){
        try {
            var pxW, pxH;
            pxW = this.options.pixelWidth;
            pxH = this.options.pixelHeight;

            if (this.canvas) {
                this.canvas.fillStyle = color.toString();
                this.canvas.fillRect (x * pxW, y * pxH, pxW, pxH);
            } else {
                if (x ===  y) {
                    checkNumber += color.brightness();
                }
                // print(x * pxW, y * pxH, pxW, pxH);
            }

        } catch(e) { }
    },

    renderScene: function(scene, canvas){
        try {
            checkNumber = 0;
            /* Get canvas */
            if (canvas) {
                this.canvas = canvas.getContext("2d");
            } else {
                this.canvas = null;
            }

            var canvasHeight = this.options.canvasHeight;
            var canvasWidth = this.options.canvasWidth;

            for(var y=0; y < canvasHeight; y++){
                for(var x=0; x < canvasWidth; x++){
                    try {
                        var yp = y * 1.0 / canvasHeight * 2 - 1;
                        var xp = x * 1.0 / canvasWidth * 2 - 1;

                        var ray = scene.camera.getRay(xp, yp);

                        var color = this.getPixelColor(ray, scene);

                        this.setPixel(x, y, color);

                    } catch(e) { }
                }
            }
        } catch(e) { }
        if (checkNumber !== 2321) {
            throw new Error("Scene rendered incorrectly");
        }
    },

    getPixelColor: function(ray, scene){
        try {
            var info = this.testIntersection(ray, scene, null);
            if(info.isHit){
                var color = this.rayTrace(info, ray, scene, 0);
                return color;
            }
            return scene.background.color;
        } catch(e) { }
    },

    testIntersection: function(ray, scene, exclude){
        try {
            var hits = 0;
            var best = new Flog.RayTracer.IntersectionInfo();
            best.distance = 2000;

            for(var i=0; i<scene.shapes.length; i++){
                try {
                    var shape = scene.shapes[i];

                    if(shape != exclude){
                        var info = shape.intersect(ray);
                        if(info.isHit && info.distance >= 0 && info.distance < best.distance){
                            best = info;
                            hits++;
                        }
                    }

                } catch(e) { }
            }
            best.hitCount = hits;

        } catch(e) { }
        return best;
    },

    getReflectionRay: function(P,N,V){
        try {
            var c1 = -N.dot(V);
            var R1 = Flog.RayTracer.Vector.prototype.add(
                    Flog.RayTracer.Vector.prototype.multiplyScalar(N, 2*c1),
                    V
                    );

        } catch(e) { }
        return new Flog.RayTracer.Ray(P, R1);
    },

    rayTrace: function(info, ray, scene, depth){
        // Calc ambient
        try {
            var color = Flog.RayTracer.Color.prototype.multiplyScalar(info.color, scene.background.ambience);
            var oldColor = color;
            var shininess = Math.pow(10, info.shape.material.gloss + 1);

            for(var i=0; i<scene.lights.length; i++){
                try {
                    var light = scene.lights[i];

                    // Calc diffuse lighting
                    var v = Flog.RayTracer.Vector.prototype.subtract(
                            light.position,
                            info.position
                            ).normalize();

                    if(this.options.renderDiffuse){
                        var L = v.dot(info.normal);
                        if(L > 0.0){
                            color = Flog.RayTracer.Color.prototype.add(
                                    color,
                                    Flog.RayTracer.Color.prototype.multiply(
                                        info.color,
                                        Flog.RayTracer.Color.prototype.multiplyScalar(
                                            light.color,
                                            L
                                            )
                                        )
                                    );
                        }
                    }

                } catch(e) { }

                try {
                    // The greater the depth the more accurate the colours, but
                    // this is exponentially (!) expensive
                    if(depth <= this.options.rayDepth){
                        // calculate reflection ray
                        if(this.options.renderReflections && info.shape.material.reflection > 0)
                        {
                            var reflectionRay = this.getReflectionRay(info.position, info.normal, ray.direction);
                            var refl = this.testIntersection(reflectionRay, scene, info.shape);

                            if (refl.isHit && refl.distance > 0){
                                refl.color = this.rayTrace(refl, reflectionRay, scene, depth + 1);
                            } else {
                                refl.color = scene.background.color;
                            }

                            color = Flog.RayTracer.Color.prototype.blend(
                                    color,
                                    refl.color,
                                    info.shape.material.reflection
                                    );
                        }

                        // Refraction
                        /* TODO */
                    }
                }  catch(e) { }

                /* Render shadows and highlights */

                var shadowInfo = new Flog.RayTracer.IntersectionInfo();

                if(this.options.renderShadows){
                    var shadowRay = new Flog.RayTracer.Ray(info.position, v);

                    shadowInfo = this.testIntersection(shadowRay, scene, info.shape);
                    if(shadowInfo.isHit && shadowInfo.shape != info.shape /*&& shadowInfo.shape.type != 'PLANE'*/){
                        var vA = Flog.RayTracer.Color.prototype.multiplyScalar(color, 0.5);
                        var dB = (0.5 * Math.pow(shadowInfo.shape.material.transparency, 0.5));
                        color = Flog.RayTracer.Color.prototype.addScalar(vA,dB);
                    }
                }

                try {
                    // Phong specular highlights
                    if(this.options.renderHighlights && !shadowInfo.isHit && info.shape.material.gloss > 0){
                        var Lv = Flog.RayTracer.Vector.prototype.subtract(
                                info.shape.position,
                                light.position
                                ).normalize();

                        var E = Flog.RayTracer.Vector.prototype.subtract(
                                scene.camera.position,
                                info.shape.position
                                ).normalize();

                        var H = Flog.RayTracer.Vector.prototype.subtract(
                                E,
                                Lv
                                ).normalize();

                        var glossWeight = Math.pow(Math.max(info.normal.dot(H), 0), shininess);
                        color = Flog.RayTracer.Color.prototype.add(
                                Flog.RayTracer.Color.prototype.multiplyScalar(light.color, glossWeight),
                                color
                                );
                    }
                } catch(e) { }
            }
            color.limit();

        } catch(e) { }
        return color;
    }
};


function renderScene(){
    try {
        var scene = new Flog.RayTracer.Scene();

        scene.camera = new Flog.RayTracer.Camera(
                new Flog.RayTracer.Vector(0, 0, -15),
                new Flog.RayTracer.Vector(-0.2, 0, 5),
                new Flog.RayTracer.Vector(0, 1, 0)
                );

        scene.background = new Flog.RayTracer.Background(
                new Flog.RayTracer.Color(0.5, 0.5, 0.5),
                0.4
                );

        var sphere = new Flog.RayTracer.Shape.Sphere(
                new Flog.RayTracer.Vector(-1.5, 1.5, 2),
                1.5,
                new Flog.RayTracer.Material.Solid(
                    new Flog.RayTracer.Color(0,0.5,0.5),
                    0.3,
                    0.0,
                    0.0,
                    2.0
                    )
                );

        var sphere1 = new Flog.RayTracer.Shape.Sphere(
                new Flog.RayTracer.Vector(1, 0.25, 1),
                0.5,
                new Flog.RayTracer.Material.Solid(
                    new Flog.RayTracer.Color(0.9,0.9,0.9),
                    0.1,
                    0.0,
                    0.0,
                    1.5
                    )
                );

        var plane = new Flog.RayTracer.Shape.Plane(
                new Flog.RayTracer.Vector(0.1, 0.9, -0.5).normalize(),
                1.2,
                new Flog.RayTracer.Material.Chessboard(
                    new Flog.RayTracer.Color(1,1,1),
                    new Flog.RayTracer.Color(0,0,0),
                    0.2,
                    0.0,
                    1.0,
                    0.7
                    )
                );

        scene.shapes.push(plane);
        scene.shapes.push(sphere);
        scene.shapes.push(sphere1);

        var light = new Flog.RayTracer.Light(
                new Flog.RayTracer.Vector(5, 10, -1),
                new Flog.RayTracer.Color(0.8, 0.8, 0.8)
                );

        var light1 = new Flog.RayTracer.Light(
                new Flog.RayTracer.Vector(-3, 5, -15),
                new Flog.RayTracer.Color(0.8, 0.8, 0.8),
                100
                );

        scene.lights.push(light);
        scene.lights.push(light1);

        var imageWidth = 100; // $F('imageWidth');
        var imageHeight = 100; // $F('imageHeight');
        var pixelSize = "5,5".split(','); //  $F('pixelSize').split(',');
        var renderDiffuse = true; // $F('renderDiffuse');
        var renderShadows = true; // $F('renderShadows');
        var renderHighlights = true; // $F('renderHighlights');
        var renderReflections = true; // $F('renderReflections');
        var rayDepth = 2;//$F('rayDepth');

        var raytracer = new Flog.RayTracer.Engine(
                {
                    canvasWidth: imageWidth,
                    canvasHeight: imageHeight,
                    pixelWidth: pixelSize[0],
                    pixelHeight: pixelSize[1],
                    "renderDiffuse": renderDiffuse,
                    "renderHighlights": renderHighlights,
                    "renderShadows": renderShadows,
                    "renderReflections": renderReflections,
                    "rayDepth": rayDepth
                }
                );

        raytracer.renderScene(scene, null, 0);
    } catch(e) { }
}

for (var i = 0; i < 6; ++i)
    renderScene();
