/**
 * dat.globe Javascript WebGL Globe Toolkit
 * http://dataarts.github.com/dat.globe
 *
 * Copyright 2011 Data Arts Team, Google Creative Lab
 *
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 */

var DAT = DAT || {};

DAT.Globe = function(container, colorFn) {

  colorFn = colorFn || function(x) {
    var c = new THREE.Color();
    c.setHSV( (0.6 - ( x * 0.5 ) ), 1.0, 1.0 );
    return c;
  };

  var Shaders = {
    'earth' : {
      uniforms: {
        'texture': { type: 't', value: 0, texture: null }
      },
      vertexShader: [
        'varying vec3 vNormal;',
        'varying vec2 vUv;',
        'void main() {',
          'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
          'vNormal = normalize( normalMatrix * normal );',
          'vUv = uv;',
        '}'
      ].join('\n'),
      fragmentShader: [
        'uniform sampler2D texture;',
        'varying vec3 vNormal;',
        'varying vec2 vUv;',
        'void main() {',
          'vec3 diffuse = texture2D( texture, vUv ).xyz;',
          'float intensity = 1.05 - dot( vNormal, vec3( 0.0, 0.0, 1.0 ) );',
          'vec3 atmosphere = vec3( 1.0, 1.0, 1.0 ) * pow( intensity, 3.0 );',
          'gl_FragColor = vec4( diffuse + atmosphere, 1.0 );',
          
        '}'
      ].join('\n')
    },
    'atmosphere' : {
      uniforms: {},
      vertexShader: [
        'varying vec3 vNormal;',
        'void main() {',
          'vNormal = normalize( normalMatrix * normal );',
          'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
        '}'
      ].join('\n'),
      fragmentShader: [
        'varying vec3 vNormal;',
        'void main() {',
          'float intensity = pow( 0.8 - dot( vNormal, vec3( 0, 0, 1.0 ) ), 12.0 );',
          'gl_FragColor = vec4( 1.0, 1.0, 1.0, 1.0 ) * intensity;',
        '}'
      ].join('\n')
    }
  };

  var camera, scene, sceneAtmosphere, renderer, w, h;
  var vector, mesh, atmosphere, point;
  var sat = new Array();  
  var friends_mk = new Array();  
    
  var overRenderer;
  var starst = new Array();

  var imgDir = '/globe/';

  var curZoomSpeed = 0;
  var zoomSpeed = 50;

  var mouse = { x: 0, y: 0 }, mouseOnDown = { x: 0, y: 0 };
  var rotation = { x: 0, y: 0 },
      target = { x: Math.PI*3/2, y: Math.PI / 6.0 },
      targetOnDown = { x: 0, y: 0 };

  var distance = 100000, distanceTarget = 100000;
  var padding = 40;
  var PI_HALF = Math.PI / 2;

  function init() {

    container.style.color = '#fff';
    container.style.font = '13px/20px Arial, sans-serif';

    var shader, uniforms, material;
    w = container.offsetWidth || window.innerWidth;
    h = container.offsetHeight || window.innerHeight;

    camera = new THREE.Camera(
        30, w / h, 1, 10000);
    camera.position.z = distance;

    vector = new THREE.Vector3();

    scene = new THREE.Scene();
    sceneAtmosphere = new THREE.Scene();

    var starsg = new THREE.Object3D;    

    starsGeometry = new THREE.Geometry();
    
    for ( i = 0; i < 500; i++ ) {
        
        vector = new THREE.Vector3( Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1 );
        vector.multiplyScalar( 35 );
        
        starsGeometry.vertices.push( new THREE.Vertex( vector ) );
        
    }
        
    var starsMaterials = [
        new THREE.ParticleBasicMaterial( { color: 0xA0A0A0, size: ((Math.random() * 2)+1), sizeAttenuation: false } ),
        new THREE.ParticleBasicMaterial( { color: 0xA0A0A0, size: ((Math.random() * 3)+1), sizeAttenuation: false } ),
        new THREE.ParticleBasicMaterial( { color: 0xD0D0D0, size: ((Math.random() * 2)+1), sizeAttenuation: false } ),
        new THREE.ParticleBasicMaterial( { color: 0xA0A0A0, size: ((Math.random() * 2)+1), sizeAttenuation: false } ),
        new THREE.ParticleBasicMaterial( { color: 0xE0E0E0, size: ((Math.random() * 3)+1), sizeAttenuation: false } ),
        new THREE.ParticleBasicMaterial( { color: 0xA0A0A0, size: ((Math.random() * 2)+1), sizeAttenuation: false } )
    ];
        
    for ( i = 10; i < 30; i++ ) {
        
        var ran = Math.floor( (Math.random() * 6)+1);
        var stars = new THREE.ParticleSystem( starsGeometry, starsMaterials[ ran ], ran );
        
        stars.rotation.x = Math.random() * 6;
        stars.rotation.y = Math.random() * 6;
        stars.rotation.z = Math.random() * 6;
        
        var s = i * 10;
        stars.scale.set( s, s, s );
        
        stars.matrixAutoUpdate = false;
        stars.updateMatrix();
        
        stars.rot = Math.random() * 10;
        
        starst.push(stars);
        
    }

    for(var i in starst) scene.addObject(starst[i]);        
//    material = new THREE.MeshBasicMaterial( { color:0x0F0F0F, wireframe : true, opacity:0.001 } );
    material = new THREE.MeshPhongMaterial( { ambient: 0xC5EDE0, color: 0xFdFdFd, wireframe : true, specular: 0x009900, shininess: 30, shading: THREE.FlatShading } );
//    var geometry = new THREE.Sphere(203, 40, 30);
//    var geometry = new THREE.IcosahedronGeometry( 2.5 );       
    var geometry = new THREE.IcosahedronGeometry( 2.5 );       
    
    pointLight = new THREE.PointLight( 0x5EA3FF, 1 );
    pointLight.position.z = camera.position.z;
    pointLight.position.y = camera.position.y + 100;
    pointLight.position.x = camera.position.x + 100;
    pointLight.intensity = 0.5;
//	scene.addObject( pointLight );
    
    mesh1 = new THREE.Mesh(geometry, material);
//    mesh1.matrixAutoUpdate = false;
    mesh1.materials[0].opacity = 0.0005;
    mesh1.scale.x = mesh1.scale.y = mesh1.scale.z = 206;
    scene.addObject(mesh1);

    var geometry = new THREE.Sphere(200, 40, 30);
//    var geometry = new THREE.Icosahedron(20);

    shader = Shaders['earth'];
    uniforms = THREE.UniformsUtils.clone(shader.uniforms);

    uniforms['texture'].texture = THREE.ImageUtils.loadTexture(imgDir+'worl' +
        '.jpg');

//    material = new THREE.MeshPhongMaterial( { ambient: 0x000000, color: 0x000000, specular: 0xFFFFFF, shading: THREE.SmoothShading } );
//    material = new THREE.MeshBasicMaterial( { color:0x000000, wireframe : false, opacity:1.0 } );

    material = new THREE.MeshShaderMaterial({

          uniforms: uniforms,
          vertexShader: shader.vertexShader,
          fragmentShader: shader.fragmentShader,

        });
                
//        satelites();
                
        $.getJSON('lines.json', function(feed) {        
                data = feed;
                console.log(data);                
                var colors = [];
                var count = 0
                for(var i in data.lines) {                         
                    var l = (data.lines[i]);
                    geometry = new THREE.Geometry();
                
                    for(var u in l) {
                    
                        var lat = l[u].t.lat;
                        var lng = l[u].t.lon;
                        var phi = (90 - lat) * Math.PI / 180;
                        var theta = (180 - lng) * Math.PI / 180;
                                                                
                        var x = (200+((l[u].man)/5)) * Math.sin(phi) * Math.cos(theta);
                        var y = (200+((l[u].man)/5)) * Math.cos(phi);
                        var z = (200+((l[u].man)/5)) * Math.sin(phi) * Math.sin(theta);   
                        
                        d  = Math.sqrt(x*x + y*y + z*z);                                    
                        
                        colors[ u ] = new THREE.Color( 0xffffff );					
                        colors[ u ].setHSV( (0.7 - ( ((l[u].man)/750) * 0.8 ) ), 0.9, 1.0 );
//                        colors[ u ].setHSV( (0.6 - ( ((l[u].man)/850) * 0.8 ) ), (0.6 - ( ((l[u].man)/850) * 0.8 ) ), (0.6 - ( ((l[u].man)/850) * 0.8 ) ) );                        
//					    colors[ u ].setHSV( 0.6, ( 0.1 * l[u].man )/10, 1.0 );
                                            
                        var vertex = new THREE.Vertex( new THREE.Vector3( x, y, z ) );
                		geometry.vertices.push( vertex );                        
                        
                    }                    

                    geometry.colors = colors;                    
                    m1 = new THREE.LineBasicMaterial( { color: 0xFFFFFF, opacity: 1, blending: THREE.AdditiveBlending, transparent: true, linewidth: 2 } );
    				m1.vertexColors = true;
                    line = new THREE.Line( geometry,  m1 );
                    line.scale.x = line.scale.y = line.scale.z = 1;
                    scene.addObject(line);
                    
                }     
        });

//    material = new THREE.MeshPhongMaterial( { ambient: 0x030303, color: 0xdddddd, opacity:0.5, shading: THREE.FlatShading } );
//    material = new THREE.MeshBasicMaterial( {  ambient: 0x0F0F0F,color:0x0F0F0F, opacity:0.7 } );
//	material = new THREE.MeshBasicMaterial( { color: 0xffaa00, wireframe: true } );

    mesh = new THREE.Mesh(geometry, material);
    mesh.matrixAutoUpdate = false;
    mesh.materials[0].opacity = 0.5;
    console.log(mesh);
    scene.addObject(mesh);

    shader = Shaders['atmosphere'];
    uniforms = THREE.UniformsUtils.clone(shader.uniforms);

    material = new THREE.MeshShaderMaterial({

          uniforms: uniforms,
          vertexShader: shader.vertexShader,
          fragmentShader: shader.fragmentShader

        });  
        
    mesh = new THREE.Mesh(geometry, material);
    mesh.scale.x = mesh.scale.y = mesh.scale.z = 1.1;
    mesh.flipSided = true;
    mesh.matrixAutoUpdate = false;
    mesh.updateMatrix();
    sceneAtmosphere.addObject(mesh);
    
	scene.fog = new THREE.FogExp2( 0x000000, 0.00007 );    

//    geometry = new THREE.Cube(0.75, 0.75, 1, 1, 1, 1, null, false, { px: true,
//          nx: true, py: true, ny: true, pz: false, nz: true});

        
        
   geometry = new THREE.Cylinder(6, 1, 1, null, false, { px: true,
          nx: true, py: true, ny: true, pz: false, nz: true});            

    for (var i = 0; i < geometry.vertices.length; i++) {

      var vertex = geometry.vertices[i];
      vertex.position.z += 0.5;

    } 

    point = new THREE.Mesh(geometry);

    renderer = new THREE.WebGLRenderer( { clearColor: 0x000000, clearAlpha: 1, antialias: true } );
    renderer.autoClear = false;
    renderer.setClearColorHex(0x000000, 0.0);
    renderer.setSize(w, h);

    friends_marker();

    renderer.domElement.style.position = 'absolute';

    container.appendChild(renderer.domElement);

    container.addEventListener('mousedown', onMouseDown, false);

    container.addEventListener('mousewheel', onMouseWheel, false);

    document.addEventListener('keydown', onDocumentKeyDown, false);

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

    container.addEventListener('mouseover', function() {
      overRenderer = true;
    }, false);

    container.addEventListener('mouseout', function() {
      overRenderer = false;
    }, false);
    
    
  }

    function friends_marker(data) {
    
        $.getJSON('friends.json', function(cities) {                

                var color = 0xAAFFAAA;       
//                var wireframe_material = new THREE.MeshBasicMaterial( { color: 0x000000, wireframe: true, wireframe_linewidth: 1 } );
                var material_p = new THREE.ParticleBasicMaterial( { color: 0x00FF00, size: 2, sizeAttenuation: false, opacity: 0.15 } );
//                var material = new THREE.MeshPhongMaterial( { ambient: color, color: color, specular: 0x009900, shininess: 30, shading: THREE.FlatShading } );        
                var material = new THREE.MeshBasicMaterial( { ambient:color, color: color, size: 2, opacity: 0.8 } );                
                var geometry = new THREE.IcosahedronGeometry(0.001);                            
        
            for(var i in cities.data) {
            
                var t = cities.data[i];
                var diam = 280 + cities.data[i].man;
                
                var mesh = new THREE.Mesh(geometry, material);
                mesh.scale.x = mesh.scale.y = mesh.scale.z = 1 + ((cities.data[i].man)/500);   
                
                mesh.lat = cities.data[i].pos.lon;
                mesh.lng = cities.data[i].pos.lat;
                var phi = (90 - mesh.lat) * Math.PI / 180;
                var theta = (180 - mesh.lng) * Math.PI / 180;
                                                        
                mesh.position.x = diam * Math.sin(phi) * Math.cos(theta);
                mesh.position.y = diam * Math.cos(phi);
                mesh.position.z = diam * Math.sin(phi) * Math.sin(theta);                 
                
                var geometry_p = new THREE.Geometry();
                                
                var nb_p = 50;
                            
/*                for(var u=0; u<20; u++) {
                
                    var diam_p = Math.random() * (diam - 200);
                    
                    diam_p += 200;
                
                    var phi = (90 - mesh.lat) * Math.PI / 180;
                    var theta = (180 - mesh.lng) * Math.PI / 180;
                                                                
                    var x = diam_p * Math.sin(phi) * Math.cos(theta);
                    var y = diam_p * Math.cos(phi);
                    var z = diam_p * Math.sin(phi) * Math.sin(theta);                                    
                
                    vector = new THREE.Vector3(x,y,z);        
                    geometry_p.vertices.push( new THREE.Vertex( vector ) );                
                                
                } */
//                var p = new THREE.ParticleSystem( geometry_p, material_p );                
                
                vector = new THREE.Vector3(mesh.position.x,mesh.position.y,mesh.position.z);        
                geometry_p.vertices.push( new THREE.Vertex( vector ) );                                
                
                var diam_p = 200;            
                var phi = (90 - mesh.lat) * Math.PI / 180;
                var theta = (180 - mesh.lng) * Math.PI / 180;                                                            
                var x = diam_p * Math.sin(phi) * Math.cos(theta);
                var y = diam_p * Math.cos(phi);
                var z = diam_p * Math.sin(phi) * Math.sin(theta);                                    
            
                vector = new THREE.Vector3(x,y,z);        
                geometry_p.vertices.push( new THREE.Vertex( vector ) );                
                    
                var edge_m = new THREE.LineBasicMaterial( { color: 0xFFFFFF, opacity: 0.1,  transparent: true, linewidth: 1 } );
                line = new THREE.Line( geometry_p,  edge_m );                
                                                                
                scene.addObject(mesh);                       
//                scene.addObject(p);                       
                scene.addObject(line);                       
                
                friends_mk.push({b:mesh,l:line});
            
            }

            console.log(cities);
        
        })
    
    }

    function satelites() {
    
        var diam = 300;
    
        for(var i=0; i<5; i++) {
    
            var geometry = new THREE.IcosahedronGeometry(0.1);            
            
            var color = 0xAADDAA;
            var material = new THREE.MeshPhongMaterial( { vertexColors: THREE.FaceColors, ambient: color, color: color, specular: 0x009900, shininess: 30, shading: THREE.FlatShading } );

            for ( var u = 0; u < geometry.faces.length; u ++ ) {
                var face = geometry.faces[ u ];
                var H = (Math.random() * 40)+200;
                var S = (Math.random() * 0.15)+0.80;
                var V = (Math.random() * 0.30)+0.6;
                face.color.setHSV( H/360 , S, V );                        
            }

            var mesh = new THREE.Mesh(geometry, material);
            
            mesh.scale.x = mesh.scale.y = mesh.scale.z = 10;            
            
            var H = (Math.random() * 40)+100;
            var S = (Math.random() * 0.15)+0.70;
            var V = (Math.random() * 0.30)+0.5;
            mesh.materials[0].color.setHSV( H/360 , S, V );  
            
            mesh.lat = (Math.random() * 180)-90;
            mesh.lng = (Math.random() * 180)-90;
            var phi = (90 - mesh.lat) * Math.PI / 180;
            var theta = (180 - mesh.lng) * Math.PI / 180;
                                                    
            mesh.position.x = diam * Math.sin(phi) * Math.cos(theta);
            mesh.position.y = diam * Math.cos(phi);
            mesh.position.z = diam * Math.sin(phi) * Math.sin(theta);   
                
            mesh.velocity = (Math.random() * 5)-2.5;   
            mesh.diam = diam;
               
            sat.push(mesh);
            
       }
       
       for(var i in sat) {       
            var s = sat[i];
            scene.addObject(s);       
       }
       
    }

  addData = function(data, opts) {
    var lat, lng, size, color, i, step, colorFnWrapper;

    opts.animated = opts.animated || false;
    this.is_animated = opts.animated;
    opts.format = opts.format || 'magnitude'; // other option is 'legend'
    console.log(opts.format);
    if (opts.format === 'magnitude') {
      step = 3;
      colorFnWrapper = function(data, i) { return colorFn(data[i+2]*10); }
    } else if (opts.format === 'legend') {
      step = 4;
      colorFnWrapper = function(data, i) { return colorFn(data[i+3]); }
    } else {
      throw('error: format not supported: '+opts.format);
    }

    if (opts.animated) {
      if (this._baseGeometry === undefined) {
        this._baseGeometry = new THREE.Geometry();
        for (i = 0; i < data.length; i += step) {
          lat = data[i];
          lng = data[i + 1];
//        size = data[i + 2];
          color = colorFnWrapper(data,i);
          size = 0;
          addPoint(lat, lng, size, color, this._baseGeometry);
        }
      }
      if(this._morphTargetId === undefined) {
        this._morphTargetId = 0;
      } else {
        this._morphTargetId += 1;
      }
      opts.name = opts.name || 'morphTarget'+this._morphTargetId;
    }
    var subgeo = new THREE.Geometry();
    for (i = 0; i < data.length; i += step) {
      lat = data[i];
      lng = data[i + 1];
      color = colorFnWrapper(data,i);
      size = data[i + 2];
      size = size*200;
      addPoint(lat, lng, size, color, subgeo);
    }
    if (opts.animated) {
      this._baseGeometry.morphTargets.push({'name': opts.name, vertices: subgeo.vertices});
    } else {
      this._baseGeometry = subgeo;
    }

  };

  function createPoints() {
    if (this._baseGeometry !== undefined) {
      if (this.is_animated === false) {
        this.points = new THREE.Mesh(this._baseGeometry, new THREE.MeshBasicMaterial({
              color: 0xffffff,
              vertexColors: THREE.FaceColors,
              morphTargets: false
            }));
      } else {
        if (this._baseGeometry.morphTargets.length < 8) {
          console.log('t l',this._baseGeometry.morphTargets.length);
          var padding = 8-this._baseGeometry.morphTargets.length;
          console.log('padding', padding);
          for(var i=0; i<=padding; i++) {
            console.log('padding',i);
            this._baseGeometry.morphTargets.push({'name': 'morphPadding'+i, vertices: this._baseGeometry.vertices});
          }
        }
        this.points = new THREE.Mesh(this._baseGeometry, new THREE.MeshBasicMaterial({
              color: 0xffffff,
              vertexColors: THREE.FaceColors,
              morphTargets: true
              
            }));
      }
      scene.addObject(this.points);
    }
  }

  function lauve() {

    var geom = new THREE.Geometry();
    var particle = new THREE.Vertex(new THREE.Vector3( 0, 0, 0)); 				
    geom.vertices.push(particle);                        
    
    for(var i=0; i<6; i++) {
        var rad = Math.PI * ((360/6*i)/180);
        var px = Math.cos(rad) * (10);
        var py = Math.sin(rad) * (10);
        var particle = new THREE.Vertex(new THREE.Vector3( px, py, 0)); 
        geom.vertices.push(particle);                            
    }

    geom.faces.push( new THREE.Face3(0, 1, 2) );                            
    geom.faces.push( new THREE.Face3(0, 2, 3) );                            
    geom.faces.push( new THREE.Face3(0, 3, 4) );                            
    geom.faces.push( new THREE.Face3(0, 4, 5) );                            
    geom.faces.push( new THREE.Face3(0, 5, 6) );                            
    geom.faces.push( new THREE.Face3(0, 6, 1) );                            
    
/*    for ( var i = 0; i < geom.faces.length; i ++ ) {
    
        var face = geom.faces[ i ];
        if(i<6) { 
            var H = (Math.random() * 40)+100;
            var S = (Math.random() * 0.15)+0.70;
            var V = (Math.random() * 0.30)+0.5;
            face.color.setHSV( H/360 , S, V );                        
        } else {
            var H = (Math.random() * 40)+100;
            var S = (Math.random() * 0.15)+0.70;
            var V = (Math.random() * 0.30)+0.7;
            face.color.setHSV( H/360 , S, V );                        
        }
    
    } */
    
    return geom;  
  }

  function addPoint(lat, lng, size, color, subgeo) {
    var phi = (90 - lat) * Math.PI / 180;
    var theta = (180 - lng) * Math.PI / 180;

    point.position.x = 200 * Math.sin(phi) * Math.cos(theta);
    point.position.y = 200 * Math.cos(phi);
    point.position.z = 200 * Math.sin(phi) * Math.sin(theta);

    point.lookAt(mesh.position);

    point.scale.z = -size;
    point.updateMatrix();
    
    for (var i = 0; i < point.geometry.faces.length; i++) {

      point.geometry.faces[i].color = color;

    }

    GeometryUtils.merge(subgeo, point);
  }

  function onMouseDown(event) {
    event.preventDefault();

    container.addEventListener('mousemove', onMouseMove, false);
    container.addEventListener('mouseup', onMouseUp, false);
    container.addEventListener('mouseout', onMouseOut, false);

    mouseOnDown.x = - event.clientX;
    mouseOnDown.y = event.clientY;

    targetOnDown.x = target.x;
    targetOnDown.y = target.y;

    container.style.cursor = 'move';
  }

  function onMouseMove(event) {
    mouse.x = - event.clientX;
    mouse.y = event.clientY;

    var zoomDamp = distance/1000;

    target.x = targetOnDown.x + (mouse.x - mouseOnDown.x) * 0.005 * zoomDamp;
    target.y = targetOnDown.y + (mouse.y - mouseOnDown.y) * 0.005 * zoomDamp;

    target.y = target.y > PI_HALF ? PI_HALF : target.y;
    target.y = target.y < - PI_HALF ? - PI_HALF : target.y;
  }

  function onMouseUp(event) {
    container.removeEventListener('mousemove', onMouseMove, false);
    container.removeEventListener('mouseup', onMouseUp, false);
    container.removeEventListener('mouseout', onMouseOut, false);
    container.style.cursor = 'auto';
  }

  function onMouseOut(event) {
    container.removeEventListener('mousemove', onMouseMove, false);
    container.removeEventListener('mouseup', onMouseUp, false);
    container.removeEventListener('mouseout', onMouseOut, false);
  }

  function onMouseWheel(event) {
    event.preventDefault();
    if (overRenderer) {
      zoom(event.wheelDeltaY * 0.3);
    }
    return false;
  }

  function onDocumentKeyDown(event) {
    switch (event.keyCode) {
      case 38:
        zoom(100);
        event.preventDefault();
        break;
      case 40:
        zoom(-100);
        event.preventDefault();
        break;
    }
  }

  function onWindowResize( event ) {
    console.log('resize');
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize( window.innerWidth, window.innerHeight );
  }

  function zoom(delta) {
    distanceTarget -= delta;
    distanceTarget = distanceTarget > 2000 ? 2000 : distanceTarget;
    distanceTarget = distanceTarget < 330 ? 330 : distanceTarget;
  }

  function animate() {
    requestAnimationFrame(animate);
    render();
  }

  function render() {
    zoom(curZoomSpeed);
    
    for(var i in sat) {
    
        var mesh = sat[i];
        
        mesh.lat += mesh.velocity/2;
        mesh.lng += mesh.velocity/2;
        var phi = (90 - mesh.lat) * Math.PI / 180;
        var theta = (180 - mesh.lng) * Math.PI / 180;
                                                
        mesh.position.x = mesh.diam * Math.sin(phi) * Math.cos(theta);
        mesh.position.y = mesh.diam * Math.cos(phi);
        mesh.position.z = mesh.diam * Math.sin(phi) * Math.sin(theta);   
                                
    }
    
    pointLight.position.z = camera.position.z;
    pointLight.position.y = camera.position.y + 100;
    pointLight.position.x = camera.position.x + 100;

    target.x += 0.001;
    target.y += 0.001;

    rotation.x += (target.x - rotation.x) * 0.1;
    rotation.y += (target.y - rotation.y) * 0.1;
    distance += (distanceTarget - distance) * 0.3;

    camera.position.x = distance * Math.sin(rotation.x) * Math.cos(rotation.y);
    camera.position.y = distance * Math.sin(rotation.y);
    camera.position.z = distance * Math.cos(rotation.x) * Math.cos(rotation.y);

    vector.copy(camera.position);

    renderer.clear();
    renderer.render(scene, camera);
    renderer.render(sceneAtmosphere, camera);
  }

  init();
  this.animate = animate;


  this.__defineGetter__('time', function() {
    return this._time || 0;
  });

  this.__defineSetter__('time', function(t) {
/*    var validMorphs = [];
    var morphDict = this.points.morphTargetDictionary;
    for(var k in morphDict) {
      if(k.indexOf('morphPadding') < 0) {
        validMorphs.push(morphDict[k]);
      }
    }
    validMorphs.sort();
    var l = validMorphs.length-1;
    var scaledt = t*l+1;
    var index = Math.floor(scaledt);
    for (i=0;i<validMorphs.length;i++) {
      this.points.morphTargetInfluences[validMorphs[i]] = 0;
    }
    var lastIndex = index - 1;
    var leftover = scaledt - index;
    if (lastIndex >= 0) {
      this.points.morphTargetInfluences[lastIndex] = 1 - leftover;
    }
    this.points.morphTargetInfluences[index] = leftover;
    this._time = t; */
  });

  this.addData = addData;
  this.createPoints = createPoints;
  this.renderer = renderer;
  this.friends = friends_mk;
  this.scene = scene;

  return this;

};


