//@ skip if $model == "Apple Watch Series 3" # added by mark-jsc-stress-test.py
// 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();
