

/*
Created by Benedict Wright
*/

/// <reference path="resources/three.d.ts" />
/// <reference path="debugPrinter.ts" />
module FD {

        /**
        * Rotates a point around a second point.
        * @function rotateAroundPoint
        * @param {Three.Vector3} originalCoordinates 
        * @param {Three.Vector3} point coordinates around which to rotate
        * @param {Three.Vector3} axis axis around which to rotate
        * @param {int} angle in radians
        */

    export function rotateAroundPoint(originalCoordinates: THREE.Vector3, point: THREE.Vector3, axis: THREE.Vector3, radians: number): THREE.Vector3 {

        //translate to point
        originalCoordinates.sub(point);
        axis.normalize();
        //rotate
        var c = Math.cos(radians);
        var s = Math.sin(radians);
        var t = 1 - Math.cos(radians);
        var x = axis.x;
        var y = axis.y;
        var z = axis.z;

        var n11 = t * x * x + c;
        var n12 = t * x * y - s * z;
        var n13 = t * x * z + s * y;
        var n14 = 0;

        var n21 = t * x * y + s * z;
        var n22 = t * y * y + c;
        var n23 = t * y * z - s * x;
        var n24 = 0;

        var n31 = t * x * z - s * y;
        var n32 = t * y * z + s * x;
        var n33 = t * z * z + c;
        var n34 = 0;

        var n41 = 0;
        var n42 = 0;
        var n43 = 0;
        var n44 = 1;

        var R = new THREE.Matrix4(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44);

        // var newCoords = R.multiplyVector3(originalCoordinates);
        var newCoords = originalCoordinates.applyMatrix4(R);
        //translate back
        newCoords.add(point);

        return newCoords;


    }

    export function pointMultiplication(v1: THREE.Vector3, v2: THREE.Vector3): number {
        return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
    }

        /**
        * Angle between 3 points.
        * @function threePointAngle
        * @param {Three.Vector3} a
        * @param {Three.Vector3} b
        * @param {Three.Vector3}c
        */
    export function threePointAngle(a: THREE.Vector2, b: THREE.Vector2, c: THREE.Vector2): number {

        //a.normalize();
        //b.normalize();
        //c.normalize();


        //var abx = b.x - a.x;
        //var aby = b.y - a.y;
        //var acx = b.x - c.x;
        //var acy = b.y - c.y;

        //var dotabac = (abx * acx + aby * acy);

        //var lenab = Math.sqrt(abx * abx + aby * aby);
        //var lenac = Math.sqrt(acx * acx + acy * acy);

        //var dacos = dotabac / lenab / lenac;

        //var phi = Math.acos(dacos);

        var t1 = b.x - a.x;//x1-x2
        var t2 = b.x - c.x;//x3-x2
        var t3 = b.y - a.y;//y1-y2
        var t4 = b.y - c.y;//y3-y2

        /*
        var t1 = a.x - b.x;//x1-x2
        var t2 = c.x - b.x;//x3-x2
        var t3 = a.y - b.y;//y1-y2
        var t4 = c.y - b.y;//y3-y2
        */
        var len1 = Math.sqrt(t1 * t1 + t3 * t3);
        var len2 = Math.sqrt(t2 * t2 + t4 * t4);

        var x = t1 * t2 + t3 * t4;
        var y = len1 * len2;


        var z = x / y;

        //debugPrinter.print("x: "+x+" y: "+y+" z: "+z,true);

        var phi = Math.acos(x / y);

        return phi;
    }



    /**
        * Creates a sprite.
        * @function makeSprite
        * @param {string} message
        * @param {int} fontSize
        */


    //taken from http://stemkoski.github.io/Three.js/Labeled-Geometry.html
    //to be tested
    export function makeSprite(message: String, fontSize: number) {
        //debugPrinter.print("adding sprite: "+message,true);

        var fontface = "Arial";
        var fontsize = fontSize;
        var borderThickness = 0;
        var borderColor = { r: 255, g: 255, b: 255, a: 1.0 };
        var backgroundColor = { r: 0, g: 0, b: 0, a: 1.0 };


        

        var canvas = document.createElement('canvas');


        var context = canvas.getContext('2d');

        context.font = "Bold " + fontsize + "px " + fontface;

        var metrics = (<any>context).measureText(message);


        // background color
        context.fillStyle = "rgba(" + backgroundColor.r + "," + backgroundColor.g + ","
        + backgroundColor.b + "," + backgroundColor.a + ")";
        // border color
        context.strokeStyle = "rgba(" + borderColor.r + "," + borderColor.g + ","
        + borderColor.b + "," + borderColor.a + ")";

        context.fillStyle = "rgba(100, 100, 100, 1.0)";
        context.lineWidth = 7;
        context.strokeStyle = "rgba(0, 0, 0, 1.0)";
        context.fillRect(0, 0, metrics.width + 10, 20);


        // text color
        context.fillStyle = "rgba(240, 240, 240, 1.0)";

        (<any>context).fillText(" " + message, borderThickness, fontsize + borderThickness);

        // canvas contents will be used for a texture
        var texture = new THREE.Texture(canvas)
	texture.needsUpdate = true;

        //var spriteAlignment = THREE.SpriteAlignment.topLeft;

        var spriteMaterial = new THREE.SpriteMaterial(
            { map: texture, useScreenCoordinates: false, alignment: new THREE.Vector2(1,-1) });
        var sprite = new THREE.Sprite(spriteMaterial);
        sprite.scale.set(0.5, 0.25, 1.0);
        return sprite;
    }
}
