var container, stats;

var camera, scene, renderer;
var group;

var targetRotation = 0;
var targetRotationOnMouseDown = 0;

var mouseX = 0;
var mouseXOnMouseDown = 0;

var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;

var id_anim = 0;

/*
 * dots : tableau de tableau (pour chaque point : x, y, z)
 * renderer : webGL, SVG ou Canvas
 * forme : tube, bubble ou line
 * sphereOn : afficher les speres rouge et bleue ou non
 */
function init(dots, choix_renderer, forme, sphereOn) {

    var params = dots;

    container = document.createElement('div');
    container.id = "container";
    document.body.appendChild(container);

    camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 1000);
//    camera.position.set(0, 200, 500); //3e param = plus il est petit, plus la camera proche de la figure
    camera.position.set(0, 100, 500);

    scene = new THREE.Scene();

    group = new THREE.Group();
//    group.position.y = 200;
    
    scene.add(group);

    //	NURBS curve
    var nurbsControlPoints = [];
    var nurbsKnots = [];
    var nurbsDegree = 3;

    for (var i = 0; i <= nurbsDegree; i++) {
        nurbsKnots.push(0);
    }

    var counter = 0;
    //Creation des vecteurs, besoin pour tube et line
    if (forme === "tube" || forme === "line") {
        group.position.y = 100;       
        
        for (var i = 0, j = 10; i < j; i++) {
            nurbsControlPoints.push(
                    new THREE.Vector3(
                            params[counter],
                            params[counter + 1],
                            params[counter + 2]
                            // 1 // weight of control point: higher means stronger attraction
                            )
                    );
            counter = counter + 3;
            var knot = (i + 1) / (j - nurbsDegree);
            nurbsKnots.push(THREE.Math.clamp(knot, 0, 1));
        }
    }
    else if (forme.slice(0, 8) === "pastille") {
        group.position.y = 0;
        
        switch (forme) {
            case "pastille1":
                //palette "highchart"
                var couleurs = [0x4572A8, 0xAA4648, 0x89A548, 0x806998, 0x3D96A8, 0xDB8438, 0x92A8C8, 0xA47D78, 0xB5CA98, 0xEEEEE8, 0x4572A8, 0xAA4648, 0x89A548, 0x806998, 0x3D96A8, 0xDB8438];
                break;
            case "pastille2":
                //palette "rainbow_12
                var couleurs = [0xff0008, 0xff00f8, 0xff8008, 0xffff08, 0x008008, 0x00ff08, 0x0080f8, 0x00fff8, 0x0000f8, 0x8000f8, 0xff0008, 0xff00f8, 0xff8008, 0xffff08, 0x008008, 0x00ff08];
                break;
            default:
                //palette windows repete "arc"
                var couleurs = [0x3C61A6, 0xAD519A, 0xBF2130, 0xDE703C, 0xF9C34A, 0x8FB65A, 0x3C61A6, 0xAD519A, 0xBF2130, 0xDE703C, 0xF9C34A, 0x8FB65A, 0x3C61A6, 0xAD519A, 0xBF2130, 0xDE703C, 0xF9C34A, 0x8FB65A];
                break;
        }
        forme = "pastille";
    }

//Choix de la forme
    switch (forme) {
        case "pastille":
//            var couleurs = [0x000000, 0x0000FF, 0x663300, 0x006600, 0x3399FF, 0x00CC00, 0x66FF00, 0xFF0000, 0x990066, 0xFF3399, 0xFF6600, 0x996600, 0xFFCC00, 0x99FFFF, 0x999966, 0xFFCCCC];

            var geometry = new THREE.SphereGeometry(12, 12, 12);
            var counter = 0;
            for (var i = 0; i < 10; i++) {
//pour le ramener a un int entre 0 et 15
//                var indice = (params[counter + 2] * 1.5 + 200) / 25;
//                indice = Math.round(indice);

                var material = new THREE.MeshBasicMaterial({color: couleurs[i]});
//                var material = new THREE.MeshBasicMaterial({color: couleurs[indice]});
//                var material = new THREE.MeshBasicMaterial({color: "0x006600"});

                var sphere = new THREE.Mesh(geometry, material);
                sphere.position.x = params[counter];
                sphere.position.y = params[counter + 1];
                sphere.position.z = 0;
                group.add(sphere);
                counter += 3;
            }

            break;
        case "bubble":
            var geometry = new THREE.SphereGeometry(10, 10, 10);
            var material = new THREE.MeshPhongMaterial({color: 0xffffff});
            var counter = 0;
            for (var i = 0; i < 10; i++) {
                var sphere = new THREE.Mesh(geometry, material);
                sphere.position.x = params[counter];
                sphere.position.y = params[counter + 1];
                sphere.position.z = params[counter + 2];
                group.add(sphere);
                counter += 3;
            }

            break;
        case "line":
            //DEBUT Line
            var nurbsCurve = new THREE.NURBSCurve(nurbsDegree, nurbsKnots, nurbsControlPoints);
            var nurbsGeometry = new THREE.Geometry();
            nurbsGeometry.vertices = nurbsCurve.getPoints(200);
            var nurbsMaterial = new THREE.LineBasicMaterial({linewidth: 10, color: 0x333333});
            var nurbsLine = new THREE.Line(nurbsGeometry, nurbsMaterial);
            nurbsLine.position.set(0, -100, 0);
            var nurbsControlPointsGeometry = new THREE.Geometry();
            nurbsControlPointsGeometry.vertices = nurbsCurve.controlPoints;
            var nurbsControlPointsMaterial = new THREE.LineBasicMaterial({linewidth: 2, color: 0x3333cc, opacity: 0.25});
            var nurbsControlPointsLine = new THREE.Line(nurbsControlPointsGeometry, nurbsControlPointsMaterial);
            nurbsControlPointsLine.position.copy(nurbsLine.position);
            group.add(nurbsLine, nurbsControlPointsLine);
            //FIN Line
            break;
        case "tube":
        default:
            //DEBUT tube
            var tubeGeometry = new THREE.TubeGeometry(new THREE.SplineCurve3(nurbsControlPoints), 150, 4, 4, false);
            // var tubeGeometry = new THREE.TubeGeometry(new THREE.SplineCurve3   (nurbsControlPoints));

            //Material
            // var material = new THREE.MeshBasicMaterial({color:0xFF0000, overdraw: true});
            // var material = new THREE.MeshDepthMaterial({overdraw: true});
            // var material =  new THREE.MeshLambertMaterial( { color:0xffffff, shading: THREE.FlatShading, overdraw: true } );

            var material = new THREE.MeshPhongMaterial({color: 0xffffff});
            var tubeMesh = new THREE.Mesh(tubeGeometry, material);
            tubeMesh.position.set(0, -100, 0);
            group.add(tubeMesh);
            //FIN
            break;
    }

    //DEBUT spheres
    if (sphereOn) {
        var geometry = new THREE.SphereGeometry(8, 8, 8);
        var geometry2 = new THREE.SphereGeometry(8, 8, 8);
        var material = new THREE.MeshBasicMaterial({color: 0x7e53935});
        var materialSphere = new THREE.MeshBasicMaterial({color: 0x42A5F5});

        var sphere = new THREE.Mesh(geometry, material);
        var sphere2 = new THREE.Mesh(geometry2, materialSphere);
        sphere.position.set(0, 100-group.position.y, 0); //boule rouge
        sphere2.position.set(0, 100-group.position.y, 180); //boule bleue

        group.add(sphere, sphere2);
    }
    //FIN spheres

    //DEBUT lumiere
    var directionalLight = new THREE.DirectionalLight(0xffffff, 0.3);
    directionalLight.position.set(0, 0, 1);
    scene.add(directionalLight);
    //FIN lumiere

    //Choix du renderer
    switch (choix_renderer) {
        case 'web':
            renderer = new THREE.WebGLRenderer( {alpha: true, antialias: true} );
			renderer.setClearColor(0xffffff, 1);
            break;
        case 'svg':
            renderer = new THREE.SVGRenderer();
            break;
        case 'canvas':
        default :
            renderer = new THREE.CanvasRenderer();
            break;
    }

    renderer.setClearColor(0xFFFFFF);		// bgcolor
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);

    container.appendChild(renderer.domElement);

    container.addEventListener('mousedown', onDocumentMouseDown, false);
    container.addEventListener('touchstart', onDocumentTouchStart, false);
    container.addEventListener('touchmove', onDocumentTouchMove, false);

    window.addEventListener('resize', onWindowResize, false);


}



function onWindowResize() {

    windowHalfX = window.innerWidth / 2;
    windowHalfY = window.innerHeight / 2;

    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    renderer.setSize(window.innerWidth, window.innerHeight);

}

//

function onDocumentMouseDown(event) {

    if (id_anim == 0) {
        animate();
    }

    event.preventDefault();

    document.addEventListener('mousemove', onDocumentMouseMove, false);
    document.addEventListener('mouseup', onDocumentMouseUp, false);
    document.addEventListener('mouseout', onDocumentMouseOut, false);

    mouseXOnMouseDown = event.clientX - windowHalfX;
    targetRotationOnMouseDown = targetRotation;

}

function onDocumentMouseMove(event) {

    mouseX = event.clientX - windowHalfX;

    targetRotation = targetRotationOnMouseDown + (mouseX - mouseXOnMouseDown) * 0.02;

}

function onDocumentMouseUp(event) {

    document.removeEventListener('mousemove', onDocumentMouseMove, false);
    document.removeEventListener('mouseup', onDocumentMouseUp, false);
    document.removeEventListener('mouseout', onDocumentMouseOut, false);

}

function onDocumentMouseOut(event) {

    document.removeEventListener('mousemove', onDocumentMouseMove, false);
    document.removeEventListener('mouseup', onDocumentMouseUp, false);
    document.removeEventListener('mouseout', onDocumentMouseOut, false);

}

function onDocumentTouchStart(event) {

    if (id_anim == 0) {
        animate();
    }

    if (event.touches.length == 1) {

        event.preventDefault();

        mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX;
        targetRotationOnMouseDown = targetRotation;

    }

}

function onDocumentTouchMove(event) {

    if (event.touches.length == 1) {

        event.preventDefault();

        mouseX = event.touches[ 0 ].pageX - windowHalfX;
        targetRotation = targetRotationOnMouseDown + (mouseX - mouseXOnMouseDown) * 0.05;

    }

}

function animate() {

    id_anim = requestAnimationFrame(animate);

    render();
    // stats.update();

}

function render() {

    group.rotation.y += (targetRotation - group.rotation.y) * 0.05;
    renderer.render(scene, camera);

}

function turn(degre) {

    var radians = Math.PI * degre / 180;

    if (id_anim != 0) {
        cancelAnimationFrame(id_anim);
        id_anim = 0;
    }

    group.rotation.y = radians;

    renderer.render(scene, camera);

}

function showAngle() {
    alert("Angle de group : " + group.rotation.y);
}