//Joku shader-efekti juttu


var Grid = function(){
  //kantaluokan rakentajan kutsu
  PartBase.call(this);
  this.initScene();
}

Grid.prototype = PartBase.prototype.inheritance();

//scene is initialized before demo starts
Grid.prototype.initScene = function(){
  
  //MAIN SCENE
  this.scene = new THREE.Scene();
  this.camera = new THREE.PerspectiveCamera(TDEMO.fov, TDEMO.aspect, TDEMO.near, TDEMO.far);
  this.camera.position.z = 400;
  this.scene.add(this.camera);
  
  THREE.ImageUtils.crossOrigin = true;
  //var texture = THREE.ImageUtils.loadTexture("bin/i-want-you-256x256.png");
  //Jos tekstuuri ei toimi firefoxissa, niin kommentoi almpi rivi pois ja poista kommentit rivi ylempää.
  var texture = THREE.ImageUtils.loadTexture( iwantyou );
  
  this.uniforms =  {
    time : {type : "f", value: 0.0},
    texture : {type : "t", value : texture},
    phase : {type : "f", value: -2.0}
  };
  
  this.material = new THREE.ShaderMaterial({
      uniforms: this.uniforms,
      vertexShader: document.getElementById( 'vertex' ).textContent,
      fragmentShader: document.getElementById( 'grid' ).textContent,
      side : THREE.DoubleSide
  });
  
  this.plane = new THREE.Mesh(new THREE.PlaneGeometry(400, 400), this.material);
  this.plane.position.z = -299;
  this.plane.rotation.y = Math.PI;
  this.scene.add(this.plane);
  
  this.geometry = new THREE.BoxGeometry(200, 200, 200);
  this.createCubes();
  
  this.createSurroundings();
}

Grid.prototype.createCubes = function(){
  this.cubes = new THREE.Object3D();
  
  this.front = new THREE.Object3D();
  this.middle = new THREE.Object3D();
  this.back = new THREE.Object3D();
  
  this.front.position.z = -200;
  this.middle.position.z = 0;
  this.back.position.z = 200;

  var step = 200;
  var start = -200;
  var x = start;

  for(var i = 0; i < 3; ++i){
    var top = new THREE.Object3D();
    var middle = new THREE.Object3D();
    var bottom = new THREE.Object3D();
    
    top.position.y = 200;
    middle.position.y = 0;
    bottom.position.y = -200;
    
    for(var k = 0; k < 9; ++k){
      var cube = new THREE.Mesh(this.geometry, this.material);
      cube.position.x = x;
      
      if(k < 3 ){
        top.add(cube);
      }
      else if(k < 6){
        middle.add(cube);
      }
      else{
        bottom.add(cube);
      }
    
      if((k+1)%3 == 0){
        x = start;
      }
      else{
        x += step;
      }
    }
    if(i == 0){
      this.front.add(top);
      this.front.add(middle);
      this.front.add(bottom);
    }
    else if(i == 2){
      this.middle.add(top);
      this.middle.add(middle);
      this.middle.add(bottom);
    }
    else{
      this.back.add(top);
      this.back.add(middle);
      this.back.add(bottom);
    }
  }

  this.cubes.add(this.front);
  this.cubes.add(this.middle);
  this.cubes.add(this.back);
  this.scene.add(this.cubes);
}

Grid.prototype.createSurroundings = function(){
  
  var skyMaterial = new THREE.MeshBasicMaterial({color : 0x2E0854 /*0x4D6FAC 0x6B238E*/, side: THREE.BackSide});
  this.skySphere = new THREE.Mesh(new THREE.SphereGeometry(600, 16, 16), skyMaterial);
  this.scene.add(this.skySphere);

}

Grid.prototype.prepare = function(elapsedTime){
  this.startTime = elapsedTime;
  
  this.transformations = [
    {
      start: this.startTime + 2*TDEMO.barLength,
      end : this.startTime + 10*TDEMO.barLength,
      position : 400,
      v : (620 - 400)/(8*TDEMO.barLength),
      callback : function(transform, time){
        var t = time - transform.start;
        var s = transform.v * t;
        this.camera.position.z = transform.position + s;
      },
      done : false
    },
    
    {
      start : this.startTime + 6*TDEMO.barLength,
      end : this.startTime + 8*TDEMO.barLength,
      v : (Math.PI/2)/(2*TDEMO.barLength),
      callback : function(transform, time){
        var t = time - transform.start;
        var s = transform.v * t;
        for(var i = 0; i < this.cubes.children.length; ++i){
          for(var j = 0; j < this.cubes.children[i].children.length; ++j){
            var cube = this.cubes.children[i].children[j];
            cube.rotation.x = s;
          }
        }
      },
      done : false
    },
    
    {
      start : this.startTime + 8*TDEMO.barLength,
      end : this.startTime + 9*TDEMO.barLength,
      v : (Math.PI/2)/(TDEMO.barLength),
      started : false,
      callback : function(transform, time){
        if(!transform.started){
          transform.started = true;
          for(var i = 0; i < this.cubes.children.length; ++i){
            for(var j = 0; j < this.cubes.children[i].children.length; ++j){
              var cube = this.cubes.children[i].children[j];
              cube.rotation.x = Math.PI/2;
            }
          }
        }
      
        var t = time - transform.start;
        var s = transform.v * t;
        
        for(var i = 0; i < this.front.children.length; ++i){
          if(i == 1){
            this.front.children[i].children[0].rotation.z = -s;
            this.front.children[i].children[2].rotation.z = s;
            this.middle.children[i].children[0].rotation.z = -s;
            this.middle.children[i].children[2].rotation.z = s;
            this.back.children[i].children[0].rotation.z = -s;
            this.back.children[i].children[2].rotation.z = s;
          }
          else{
            this.front.children[i].children[0].rotation.z = s;
            this.front.children[i].children[2].rotation.z = -s;
            this.middle.children[i].children[0].rotation.z = s;
            this.middle.children[i].children[2].rotation.z = -s;
            this.back.children[i].children[0].rotation.z = s;
            this.back.children[i].children[2].rotation.z = -s;
          }
        }
      },
      done : false
    },
    
    {
      start: this.startTime + 9*TDEMO.barLength,
      end: this.startTime + 10*TDEMO.barLength,
      v : 200/(TDEMO.barLength),
      started : false,
      callback : function(transform, time){
        if(!transform.started){
          transform.started = true;
          for(var i = 0; i < this.front.children.length; ++i){
            if(i == 1){
              this.front.children[i].children[0].rotation.z = -Math.PI/2;
              this.front.children[i].children[2].rotation.z = Math.PI/2;
              this.middle.children[i].children[0].rotation.z = -Math.PI/2;
              this.middle.children[i].children[2].rotation.z = Math.PI/2;
              this.back.children[i].children[0].rotation.z = -Math.PI/2;
              this.back.children[i].children[2].rotation.z = Math.PI/2;
            }
            else{
              this.front.children[i].children[0].rotation.z = Math.PI/2;
              this.front.children[i].children[2].rotation.z = -Math.PI/2;
              this.middle.children[i].children[0].rotation.z = Math.PI/2;
              this.middle.children[i].children[2].rotation.z = -Math.PI/2;
              this.back.children[i].children[0].rotation.z = Math.PI/2;
              this.back.children[i].children[2].rotation.z = -Math.PI/2;
            }
          }
        }
        var t = time - transform.start;
        var s = transform.v * t;       
        this.front.children[1].children[1].position.x = s;
        this.middle.children[1].children[1].position.x = -s;
        this.back.children[1].children[1].position.x = s;
      },
      done : false,
    },
    
    {
      start: this.startTime + 10*TDEMO.barLength,
      end : this.startTime + 11*TDEMO.barLength+(TDEMO.spb*0.5),
      position : 620,
      v : (160-620)/(TDEMO.barLength+(TDEMO.spb*0.5)),
      callback : function(transform, time){
        var t = time - transform.start;
        var s = transform.v * t;
        this.camera.position.z = transform.position + s;
      },
      done : false
    },
    
    {
      start : this.startTime + 10.5*TDEMO.barLength,
      end : this.startTime + 10.5*TDEMO.barLength+TDEMO.spb,
      p : Math.PI/2,
      v : -(Math.PI/2)/(TDEMO.spb),
      started : false,
      callback : function(transform, time){
      
        if(!transform.started){
          transform.started = true;
          this.front.children[1].children[1].position.x = 200;
          this.middle.children[1].children[1].position.x = -200;
          this.back.children[1].children[1].position.x = 200; 
        }
      
        var t = time - transform.start;
        var s = transform.v * t;
        for(var i = 0; i < this.cubes.children.length; ++i){
          for(var j = 0; j < this.cubes.children[i].children.length; ++j){
            var cube = this.cubes.children[i].children[j];
            cube.rotation.x = transform.p+s;
          }
        }
        for(var i = 0; i < this.front.children.length; ++i){
          if(i == 1){
            this.front.children[i].children[0].rotation.z = transform.p-s;
            this.front.children[i].children[2].rotation.z = transform.p+s;
            this.middle.children[i].children[0].rotation.z = transform.p-s;
            this.middle.children[i].children[2].rotation.z = transform.p+s;
            this.back.children[i].children[0].rotation.z = transform.p-s;
            this.back.children[i].children[2].rotation.z = transform.p+s;
          }
          else{
            this.front.children[i].children[0].rotation.z = transform.p+s;
            this.front.children[i].children[2].rotation.z = transform.p-s;
            this.middle.children[i].children[0].rotation.z = transform.p+s;
            this.middle.children[i].children[2].rotation.z = transform.p-s;
            this.back.children[i].children[0].rotation.z = transform.p+s;
            this.back.children[i].children[2].rotation.z = transform.p-s;
          }
        }
      },
      done : false
    },
    
    {
      start: this.startTime + 11*TDEMO.barLength,
      end: this.startTime + 11*TDEMO.barLength+TDEMO.spb,
      p: -2.0,
      v : (2.0+2.0)/(TDEMO.spb),
      started : false,
      callback: function(transform, time){
        if(!transform.started){
          transform.started = true;
          
          for(var i = 0; i < this.cubes.children.length; ++i){
            for(var j = 0; j < this.cubes.children[i].children.length; ++j){
              var cube = this.cubes.children[i].children[j];
              cube.rotation.x = 0;
            }
          }
          
          for(var i = 0; i < this.front.children.length; ++i){
            this.front.children[i].children[0].rotation.z = 0;
            this.front.children[i].children[2].rotation.z = 0;
            this.middle.children[i].children[0].rotation.z = 0;
            this.middle.children[i].children[2].rotation.z = 0;
            this.back.children[i].children[0].rotation.z = 0;
            this.back.children[i].children[2].rotation.z = 0;
          }
          
        }
      
        var t = time - transform.start;
        var s = transform.v * t;
        this.uniforms.phase.value = transform.p + s;
      },
      done : false
    },
    
    {
      start: this.startTime + 11*TDEMO.barLength,
      end: this.startTime + 11*TDEMO.barLength+(TDEMO.spb*0.5),
      position : 200,
      v : -200/(TDEMO.spb*0.5),
      callback : function(transform, time){
        var t = time - transform.start;
        var s = transform.v * t;
        this.front.children[1].children[1].position.x = transform.position+s;
      },
      done : false
    },
    {
      start: this.startTime + 11.5*TDEMO.barLength,
      end: this.startTime + 11.5*TDEMO.barLength+(TDEMO.spb*0.5),
      position : -200,
      v : 200/(TDEMO.spb*0.5),
      callback : function(transform, time){
        var t = time - transform.start;
        var s = transform.v * t;
        this.middle.children[1].children[1].position.x = transform.position+s;
      },
      done : false
    },
    {
      start: this.startTime + 12*TDEMO.barLength,
      end: this.startTime + 12*TDEMO.barLength+(TDEMO.spb*0.5),
      position : 200,
      v : -200/(TDEMO.spb*0.5),
      callback : function(transform, time){
        var t = time - transform.start;
        var s = transform.v * t;
        this.back.children[1].children[1].position.x = transform.position+s;
      },
      done : false
    },
    
    {
      start: this.startTime + 11*TDEMO.barLength+(TDEMO.spb*0.5),
      end : this.startTime + 12*TDEMO.barLength+(TDEMO.spb*0.5),
      position : 160,
      v : (800-160)/(TDEMO.barLength),
      callback : function(transform, time){
        var t = time - transform.start;
        var s = transform.v * t;
        this.camera.position.z = transform.position + s;
      },
      done : false
    },
    
    {
      start: this.startTime + 12*TDEMO.barLength+(TDEMO.spb*0.5),
      end: this.startTime + 13*TDEMO.barLength,
      v : (Math.PI*2.0)/((TDEMO.barLength)-(TDEMO.spb*0.5)), 
      pc : 800,
      vc : (400-800)/((TDEMO.barLength)-(TDEMO.spb*0.5)),
      started : false,
      callback : function(transform, time){
        if(!transform.started){
          transform.started = true;
          this.front.children[1].children[1].position.x = 0;
          this.middle.children[1].children[1].position.x = 0;
          this.back.children[1].children[1].position.x = 0;
        }
        var t = time - transform.start;
        var s = transform.v * t;
        var sc = transform.vc * t;
        this.cubes.rotation.z = s;
        this.cubes.rotation.x = s/2;
        this.camera.position.z = transform.pc + sc;
      }
    }
  ];
}

//Operations tahta takes place before rendering in every cycle
Grid.prototype.animate = function(elapsedTime){
  this.uniforms.time.value = ((elapsedTime- this.startTime)*1.5);
  
  for(var i = 0; i < this.transformations.length; ++i){
    var transform = this.transformations[i];
    if(!transform.done && elapsedTime >= transform.start && elapsedTime <= transform.end){
      transform.callback.call(this, transform, elapsedTime);
    }
    else if(!transform.done && elapsedTime >= transform.end){
      transform.done = true;
    }
  }
}

//rendering function
Grid.prototype.render = function(elapsedTime, rtt){
  TDEMO.renderer.render(this.scene, this.camera, rtt);
}



