var container, stats;

var camera, scene, renderer, cameraCube, sceneCube;
var group;

var targetRotation = 0;
var targetRotationOnMouseDown = 0;

var mouseX = 0;
var mouseXOnMouseDown = 0;

var id_anim = 0;
var initRoll = 0; //le roulement initial sur telephone
var isInit = true; //si true le nouvel angle doit etre considéré comme le point 0 du gyroscope
var angle = 0; //l'angle initial (peut etre recu en parametre)
var gyrOn = false; //le gyroscope est activé ou non 
var isTouched = false;

container = document.getElementById('noodle');
var windowHalfX = container.offsetWidth / 2;
var windowHalfY = container.offsetHeight / 2;

var tailleCarre = 500; //dans le cas ou container a une taille fixe et carre
if (screen.height > 500 && screen.width > 500) {
    tailleCarre = 500;
//    document.getElementById("info").innerHTML += " PAS COOL "+ container.offsetHeight + " " + container.offsetWidth; 
}
else if (screen.height > 300 && screen.width > 300) {
    tailleCarre = 300;
//    document.getElementById("info").innerHTML += " OK " + container.offsetHeight + " " + container.offsetWidth; 
}

var turnIsSet; //par defaut = rotation, possible ou non de tourner la figure manuellement
var rotation; //
var gyroscope; //choix d'activer ou non le gyroscope (JSON)

$("head").append('<script type="text/javascript" src="./js/ext/build/three.js"></script>');
$("head").append('<script type="text/javascript" src="./js/ext/renderers/Projector.js"></script>');
$("head").append('<script type="text/javascript" src="./js/ext/renderers/Detector.js"></script>');

/*
 * dots : tableau de tableau (pour chaque point : x, y, z)
 * renderer : webGL, SVG ou Canvas
 * forme : tube, bubble ou line
 * sphereOn : boolean, les spheres pour se reperer dans l'espace
 * couleurs : palette de couleur (array)
 * rotation : est ce que on peut tourner manuellement
 * axes : fleches de repere
 * gyr : gyroscope active
 * bck : couleur de fond
 */
function init(dots, choix_renderer, forme, sphereOn, couleurs, rotation, axes, gyr, bck) {

    if (forme === "tube" || forme === "line" || forme === "superTube" || forme === "metalTube") {
        $("head").append('<script type="text/javascript" src="./js/draw/noodle.js"></script>');
        $("head").append('<script type="text/javascript" src="./js/ext/curves/NURBSCurve.js"></script>');
        $("head").append('<script type="text/javascript" src="./js/ext/curves/NURBSUtils.js"></script>');
    }
    if (forme === "bubble" || forme === "superTube") {
        $("head").append('<script type="text/javascript" src="./js/draw/skyBox.js"></script>');
    }

    $("head").append('<script type="text/javascript" src="./js/draw/' + forme + '.js"></script>');

    gyroscope = gyr;
    turnIsSet = rotation;

    if (rotation) {
        startTurn();
    }

    var params = dots;

    camera = new THREE.PerspectiveCamera(50, 1, 1, 1000);
    camera.position.set(0, 100, 500); //camera proche de la figure

    scene = new THREE.Scene();
    group = new THREE.Group();

    //arrow helper
    if (axes) {
        createArrow();
    }

    if (!Detector.webgl && choix_renderer === "web") {
        alert("Your computer does not support webGL, sorry !");
        choix_renderer = "canvas";
    }

    //Choix du renderer
    switch (choix_renderer) {
        case 'web':
            $("head").append('<script type="text/javascript" src="./js/ext/renderers/WebGLRenderer.js"></script>');
            renderer = new THREE.WebGLRenderer({
                antialias: true,
                alpha: true
            });
            break;
        case 'svg':
            $("head").append('<script type="text/javascript" src="./js/ext/renderers/SVGRenderer.js"></script>');
            renderer = new THREE.SVGRenderer({
                antialias: true,
                alpha: true
            });
            break;
        case 'canvas':
        default :
            $("head").append('<script type="text/javascript" src="./js/ext/renderers/CanvasRenderer.js"></script>');
            renderer = new THREE.CanvasRenderer({
                antialias: true,
                alpha: true
            });
            break;
    }

    scene.add(group);

    //A indiquer dans les fonctions forme !
//    renderer.setClearColor(0xFFFFFF); // bgcolor

    if (forme.slice(0, 8) === "pastille") {
        forme = "pastille";
    }

    //appelle de la fonction pour dessiner, voir fichier draw.js
//    window[forme](dots, couleurs);
    draw(dots, couleurs, 10, 3);


//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

    //couleur fond
    if (bck) {
        renderer.setClearColor(bck);
    }

    renderer.setPixelRatio(window.devicePixelRatio);
//    renderer.setSize(window.innerWidth, window.innerHeight);
//    renderer.setSize(container.offsetWidth, container.offsetHeight);
    renderer.setSize(tailleCarre, tailleCarre);

    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() {

    renderer.setSize(tailleCarre, tailleCarre);

    render();

}

//

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) {
    isTouched = true;
    //coupe le gyroscope
    window.removeEventListener('deviceorientation', deviceOrientationHandler, false);
    gyrOn = false;
    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() {

    var angle1 = group.rotation.y;
//    var test = document.getElementById("testGyr").innerHTML = "angle1 " + Math.round((angle1 * 180 / Math.PI) % 360) * 1000 / 1000; //approximation en degre

    group.rotation.y += (targetRotation - group.rotation.y) * 0.05;
    var angle2 = group.rotation.y;
//    var test2 = document.getElementById("testGyr2").innerHTML = "angle2 " + Math.round((angle2 * 180 / Math.PI) % 360) * 1000 / 1000;
    var delta = Math.round((angle1 - angle2) * 100) / 100;
//    var test3 = document.getElementById("testGyrDelta").innerHTML = "delta " + delta;
    // var testTouched = document.getElementById("testTouched").innerHTML = "isGyrOn "+!isTouched;

    //remet le gyroscope
    if (!gyrOn && isTouched && delta === 0) {
        isTouched = false;
        angle = (angle2 * 180 / Math.PI) % 360;
        isInit = true;
        if ("DeviceOrientationEvent" in window && gyroscope) {
            window.addEventListener('deviceorientation', deviceOrientationHandler, false);
        }
        gyrOn = true;
    }
    renderer.render(scene, camera);

    if (typeof sceneCube != "undefined") {
        renderer.render(sceneCube, cameraCube);
    }
}

function turn(degre, nouveau) {

    var radians = Math.PI * degre / 180;
    if (id_anim != 0) {
        cancelAnimationFrame(id_anim);
        id_anim = 0;
    }

    group.rotation.y = radians;
    renderer.render(scene, camera);

    if (typeof sceneCube != "undefined") {
        renderer.render(sceneCube, cameraCube);
    }

    if (nouveau) {
        angle = degre;
        isInit = true;
        if ("DeviceOrientationEvent" in window && gyroscope) {
//            $("#noodle").append("<p>Gyr on !</p>");
            window.addEventListener('deviceorientation', deviceOrientationHandler, false);
        }
    }
}

function setGyr() {
    gyrOn = true;
    // check deviceorientation support
    // true:  set event listener
    // false: alert message
    ("DeviceOrientationEvent" in window && gyroscope)
            ? window.addEventListener('deviceorientation', deviceOrientationHandler, false)
            : alert("Your browser does not support device orientation.");
}

// handler for device orientation event
function deviceOrientationHandler(e) {

    // rotation along the x-axis
    var yaw = Math.floor(e.alpha);
    // rotation along the y-axis
    var pitch = Math.floor(e.beta);
    // rotation along the z-axis
    var roll = Math.floor(e.gamma);

    if (window.orientation === 0) { // Portrait
        var mouvement = roll;
    }
    else { //Landscape
        var mouvement = yaw;
    }

    if (isInit) {
        initRoll = mouvement;
        isInit = false;
    }

    turn(angle + mouvement - initRoll, false); //tourne autour de l'angle choisi, en prenant en compte si le tel etait penche
}

function showAngle() {
    alert("Angle de group : " + group.rotation.y * 180 / Math.PI);
}

function setTurn() {
    if (turnIsSet) {
        stopTurn();
    }
    else {
        startTurn();
    }
    turnIsSet = !turnIsSet;
}

function startTurn() {
    container.addEventListener('mousedown', onDocumentMouseDown, false);
    container.addEventListener('touchstart', onDocumentTouchStart, false);
    container.addEventListener('touchmove', onDocumentTouchMove, false);
}

function stopTurn() {
    container.removeEventListener('mousedown', onDocumentMouseDown, false);
    container.removeEventListener('touchstart', onDocumentTouchStart, false);
    container.removeEventListener('touchmove', onDocumentTouchMove, false);
}

//arrow helper pour indiquer le sens de la figure
function createArrow() {
    var dir = new THREE.Vector3(0, 1, 0);
    var origin = new THREE.Vector3(0, -100, 0);
    var length = 400;
    var hex = 0xFF0000;
    var headLenght = 30;
    var headWidth = 20;

    var arrowHelper = new THREE.ArrowHelper(dir, origin, length, hex, headLenght, headWidth);
    scene.add(arrowHelper);
}