<!DOCTYPE html>

<html>
<head>
    <title>XPPL VOLUMETRIC CATALOGUE </title>
    <meta charset="utf-8">
    <link href="https://fonts.googleapis.com/css?family=Karla" rel="stylesheet">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <style>
        body{
            cccccc;
                font-family: 'Karla', sans-serif;
                font-size:15px;

                text-align:left;
                background-color: #140b33;
                margin: 0px;
                overflow: hidden;
            }
            #info {
                position: absolute;
                top: 0px; width: 10%;
                padding: 10px;
            }
            a {
                color: #444b7c;
            }

            .swal-button {
                padding: 7px 19px;

                background-color: #aca4c1;
                font-size: 12px;


}

            .swal-title {
                margin: 0px;
                font-size: 16px;
                box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.21);
                margin-bottom: 28px;
}

            .swal-overlay {
                background-color: rgba(20, 13, 50, 0.6);
}
            .swal-modal {
                background-color: rgba(172, 164, 193, 1);

}



    </style>
</head>
<body>
    <div id="info"><a  target="_blank" rel="noopener">XPPL VOLUMETRIC CATALOGUE  <br> <br> Feel free to move around and explore the content of the library by clicking on the volumetric shapes</div>
    <div id="container"></div>
    <canvas id="viewer"></canvas>
    <script src="https://rawgit.com/mrdoob/three.js/dev/build/three.min.js"></script>
    <script src="https://rawgit.com/mrdoob/three.js/dev/examples/js/controls/OrbitControls.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.4.0/bootbox.min.js"></script>
    <script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
    <script>


var category2color = new Object();
category2color["Technical"] = "#003d5d";
category2color["Science/History"] = "#f23d5d";
category2color["Media studies"] = "#8c3d5d";
category2color["Philosophy"] = "#723d5d";
category2color["Computer culture"] = "#423d5d";
category2color["Design / writing / publishing"] = "#ff0000";
category2color["Desk"] = "#09edff";
category2color["Art"] = "#ffedff";
category2color["Digital (Steve Trim 2 reading)"] = "#ffe1cc";
category2color["Media Studies (Femke Trim 3)"] = "#00e1cc";
category2color["Literature, Culture, Theory"] = "#00a1d4";

category2color["default"] = "#cdc1ec";




        console.clear();

const MAX_DISTANCE = 1000;
//
const MIN_DISTANCE = 200;

const MAX_SPHERE_RADIUS = 700;

var bookTitles;
var request = new XMLHttpRequest();
request.open('GET', 'export.json', true);

request.onload = function() {
  if (request.status >= 200 && request.status < 400) {
    var data = JSON.parse(request.responseText);
    //bookTitles = data;
    bookTitles = data.books[0];

    bookTitles.forEach(function(book) {
      book.type = "sphere";
      console.log('BOOK:', book);



    });
    console.log("got books", bookTitles)
    // loaded data, start
    init();
    animate();
  } else {
    // We reached our target server, but it returned an error

  }
};

request.onerror = function() {
  // There was a connection error of some sort
};

request.send();


// --- threeJS --- //
var renderer, scene, camera, distance, raycaster, projector;

var container = document.getElementById('container');
var raycaster = new THREE.Raycaster(),INTERSECTED;
var mouse = new THREE.Vector2();
var distance = 600;

// -- basic initialization -- //
function init() {
    renderer = new THREE.WebGLRenderer({
        antialias: true
    });

    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setClearColor(0x140b33, 1);
    container.appendChild(renderer.domElement);

    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.01, 300000);
  //  controls = new THREE.OrbitControls(camera);
    //camera.position.set(1, 1, -5);
    camera.position.set(MAX_DISTANCE/2, MAX_DISTANCE/20, MAX_DISTANCE/20);

    camera.updateProjectionMatrix();

    controls = new THREE.OrbitControls(camera, renderer.domElement);
  //  controls.maxDistance = MAX_DISTANCE * 3;
    controls.target = new THREE.Vector3(0, 0, 0);
    controls.rotateSpeed = .2;
    controls.enableDamping = true;
    console.log(controls.enableDamping);
    controls.dampingFactor = .15;
    controls.panSpeed = .15;
    controls.screenSpacePanning = true;
    // to disable zoom
    controls.enableZoom = true;
    // to disable rotation
    controls.enableRotate = true;
    // to disable pan
    controls.enablePan = true;
    scene.add(camera);

    //camera.position.set(-150, 10, 1);
    //controls.update();
   // scene.add(camera);

    light = new THREE.PointLight(0x404040);
    light.position.set(50, 0, 0);
    scene.add(light);
   /* light_two = new THREE.PointLight(0xffffff, 1, 4000);
    light_two.position.set(-100, 800, 800);
    lightAmbient = new THREE.AmbientLight(0x404040);
    scene.add(light, light_two, lightAmbient);*/

    // createSpheres();

    scene.add(new THREE.DirectionalLight(0xffffff));
    scene.add(new THREE.AmbientLight(0x222222));

    renderer.setPixelRatio(window.devicePixelRatio);

    let viewer = document.querySelector('#viewer');
    viewer.parentNode.replaceChild(renderer.domElement, viewer);

    createDiamond();

    createSpace();

    renderer.render(scene, camera);

    document.addEventListener('mousemove', onMouseMove, false);
    document.addEventListener('mousedown', onDocumentMouseDown, false);
    window.addEventListener('resize', onWindowResize, false);


}

// -- diamonds -- //


function catInobject(obj, category){ //checks if category is in object, if so return corresponding color
    if (obj.hasOwnProperty(category)) {
    var color = obj[category];
    } else { var color = obj["default"];
 }
    return color;
}

function createDiamond() {

    diamondsGroup = new THREE.Object3D();


        console.log();

        bookTitles.forEach(function (book) {
            var chosencolor = catInobject(category2color, book.category);
            var sphere = new THREE.SphereGeometry(1.3, Math.random() * 50, Math.random() * 50);
            var material = new THREE.MeshPhongMaterial({
                color: chosencolor,//Math.random() * 0xff00000 - 0xff00000,
                shading: THREE.FlatShading
            });
            var sphere = new THREE.Mesh(sphere, material);
            sphere.position.x = get_x(book.title) * Math.random() * 100 - 1000;
            sphere.position.z = get_z(book.category) * Math.random() *  100 - 1000;
            sphere.rotation.y =get_y(book.fileformat) * Math.random() * 100 - 1000;
            //sphere.scale.x = sphere.scale.y = sphere.scale.z = Math.random() * 50 + 10;
            sphere.scale.x = sphere.scale.y = sphere.scale.z = get_size(book.title);

            sphere.userData = book;
            diamondsGroup.add(sphere);

        })
        diamondsGroup.position.x = 500;
        scene.add(diamondsGroup);

};

function get_size(title){
    radius = 0;
    for (var i = 0; i < title.length; i++) {
      radius = radius + title.charCodeAt(i)
    }
    console.log(radius)
    return radius/100;
}

function get_x(title){
    radius = 0;
    for (var i = 0; i < title.length; i++) {
      radius = radius + title.charCodeAt(i)
    }
    console.log(radius)
    return radius/100;
}
function get_y(title){
    radius = 0;
    for (var i = 0; i < title.length; i++) {
      radius = radius + title.charCodeAt(i)
    }
    console.log(radius)
    return radius/100;
}
function get_z(title){
    radius = 0;
    for (var i = 0; i < title.length; i++) {
      radius = radius + title.charCodeAt(i)
    }
    console.log(radius)
    return radius/100;
}

// -- dots on the back -- //
function createSpace() {

    let dots = new THREE.Object3D();

    for (let i = 0; i < 1000; i++) {
        let circleGeometry = new THREE.SphereGeometry(2, Math.random() * 5, Math.random() * 5);
        let color;
        if (Math.round(Math.random()) === 0)
            color = new THREE.Color('#003d5d');
        else
            //color = new THREE.Color('#f23d5d');
            color = new THREE.Color('#f23d5d');

        let material = new THREE.MeshPhongMaterial({
            color: color
            //side: THREE.DoubleSide
        });

        material.flatShading = true;

        //var material = new THREE.MeshBasicMaterial({
            //color : new THREE.Color(Math.floor(Math.random() * 1) === 1),
            //color : new THREE.Color(Math.random() * 0.5 + 0.5, Math.random() * 0.5 + 0.5, 0),
            //shading: THREE.FlatShading,
        //})
       var circle = new THREE.Mesh(circleGeometry, material);
        material.side = THREE.DoubleSide;

        circle.position.x = Math.random() * -distance * 100;
        circle.position.y = Math.random() * -distance * 8;
        circle.position.z = Math.random() * distance * 5;
        circle.rotation.y = Math.random() * 2 * Math.PI;
        circle.scale.x = circle.scale.y = circle.scale.z = Math.random() * 6 + 5;
        dots.add(circle);
    }

    dots.position.x = 14000;
    dots.position.y = 1500;
    dots.position.z = 4000;
    dots.rotation.y = Math.PI * 600;
    dots.rotation.z = Math.PI * 500;

    scene.add(dots);
};


 /*   let circle = new THREE.Mesh(circleGeometry, material);

    let direction = getRandomVector().normalize();
    let minDistance = MAX_DISTANCE * 8;
    let maxDistance = minDistance + 0.5;
    direction.multiplyScalar(Math.random() * (maxDistance - minDistance) + minDistance);

    circle.position.add(direction);

    dots.add(circle);
    }
    scene.add(dots);
} */

function getRandomVector(max_distance) {
    if (max_distance === undefined)
        max_distance = 1;
    return new THREE.Vector3(getRandom(max_distance), getRandom(max_distance), getRandom(max_distance));
}

function getRandom(max_distance) {
    let random = Math.random() * max_distance;
    random *= Math.floor(Math.random() * 2) === 1 ? 1 : -1;
    return random;
}



// -- events -- //
function onMouseMove(event) {
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
     mouseX = event.clientX - window.innerWidth / 2 ;
     mouseY = event.clientY - window.innerHeight / 2 ;
    camera.position.x += (mouseX - camera.position.x) * 0.01;
    camera.position.y += (mouseY - camera.position.y) * 0.01;
    camera.lookAt(scene.position);
};

function onDocumentMouseDown(event) {

    event.preventDefault();
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

    raycaster.setFromCamera(mouse, camera);

    var intersects = raycaster.intersectObjects(diamondsGroup.children);
    if (intersects.length > 0) {
        var book = intersects[0].object.userData;
        console.log("click", book);
        //alert("book" + book.title);

        //swal(book.title + book.authors);

        swal(book.title + " \n " + " " + book.authors[0].author_name +   " \n" + book.category, {
            button: {
                text: "Open",
            }
        }).then (function(){
            window.location = "/books/"+book.id
        });



    }

};

function onDocumentMouseWheel( event ) {

    fov -= event.wheelDeltaY * 0.05;
    camera.projectionMatrix = THREE.Matrix4.makePerspective( fov, window.innerWidth / window.innerHeight, 1, 1100 );

}


function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.updateProjectionMatrix();
    controls.update();
};

// ---- //
function animate() {
    requestAnimationFrame(animate);
    controls.update();
    render();
};

// -- render all -- //
function render() {

    var timer = 0.00001 * Date.now();

    for (var i = 0, l = diamondsGroup.children.length; i < l; i++) {
        var object = diamondsGroup.children[i];
        object.position.y = 500 * Math.cos(timer + i);
        object.rotation.y += Math.PI / 500;
    }

    // update the picking ray with the camera and mouse position
    raycaster.setFromCamera(mouse, camera);

    // calculate objects intersecting the picking ray
    var intersects = raycaster.intersectObjects(diamondsGroup.children);

    if (intersects.length > 0) {
        if (INTERSECTED != intersects[0].object) {
            if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);
            INTERSECTED = intersects[0].object;
            INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();
            INTERSECTED.material.emissive.setHex(Math.random() * 0xff00000 - 0xff00000);
        }
    } else {
        if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);
        INTERSECTED = null;
    }

    renderer.render(scene, camera);
};

// -- run functions -- //
//init();
//animate();

    </script>

</body>
</html>
