var Shadercubes = function(){
  PartBase.call(this);
  //this.setHorizontalBlur(8);
  //this.setVerticalBlur(8);
  //this.setEdgeDetection();
  this.setBloom(2);
  this.createThings();
};

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

Shadercubes.prototype.circlesOn = function(value) {
  if (value !== 0 && this.circlesCount !== 0) {
    this.circlesCount = 3;
    this.uniforms.circlesOn.value = 3;
  } else {
    this.uniforms.circlesOn.value = value;
    this.circlesCount = value;
  }
};

Shadercubes.prototype.animateShader = function() {
  var trig = TDEMO.SYNC.getCircle();
  var bgControl = TDEMO.SYNC.getShaderBg();

  if(this.elapsed == 0) { 
    this.timepoint1 = 0;
    this.timepoint2 = 0;
    this.circleStarted = false;
    this.circleStarted2 = false;
  }  

  this.uniforms.bgpart.value = bgControl;

  if (trig === 1 && !this.circleStarted) {
    this.circlesOn(1);
    this.timepoint1 = (this.elapsed*0.75) % Math.PI;
    this.circleStarted = true;
  }

  if (trig === 2 && !this.circleStarted2) {
    this.circlesOn(2);
    this.timepoint2 = (this.elapsed*0.525) % Math.PI;
    this.circleStarted2 = true;
  }

  if (trig === 3) {
    this.circleStarted = false;
  }

  if (trig === 4) {
    this.circleStarted2 = false;
  }
  
  if (trig === 0) {
    this.circlesOn(0);
  }

  this.uniforms.circleTime.value = (Math.PI/2+this.elapsed*0.75 - this.timepoint1);
  this.uniforms.circleTime2.value = (Math.PI/2+this.elapsed*0.525 - this.timepoint2);

  this.uniforms.gtime.value = this.elapsed;
  this.uniforms.time.value = (10+this.elapsed*0.75);
};


Shadercubes.prototype.animate = function(elapsedTime, delta){
  PartBase.prototype.animate.call(this, elapsedTime, delta, true);
  if (this.elapsed == 0) {
    for(var i = 0; i<this.cubearr.length; i++) {
      this.cubearr[i].position.x = this.cubepositions[i].x;
      this.cubearr[i].position.y = this.cubepositions[i].y;
      this.cubearr[i].position.z = this.cubepositions[i].z;
    }
  }

  this.animateShader();
  this.objcontainer.rotation.y += 0.02;
  var trig = TDEMO.SYNC.getHeartBeat();

  if(trig===1) {  
    for (var i = 0; i<this.cubearr.length; i++) {
      this.cubearr[i].position.x += Math.random()*20 - 10;
      this.cubearr[i].position.y += Math.random()*10 - 5;
      this.cubearr[i].position.z += Math.random()*10 - 5;       
    }
  }
  
  if(trig===2) {
    for(var i = 0; i<this.cubearr.length; i++) {    
      if(this.cubearr[i].position.x != this.cubepositions[i].x || 
      this.cubearr[i].position.y != this.cubepositions[i].y || 
      this.cubearr[i].position.z != this.cubepositions[i].z) {
        var xdiff = this.cubepositions[i].x - this.cubearr[i].position.x;
        var ydiff = this.cubepositions[i].y - this.cubearr[i].position.y;
        var zdiff = this.cubepositions[i].z - this.cubearr[i].position.z;

        this.cubearr[i].position.x += xdiff*0.06;
        this.cubearr[i].position.y += ydiff*0.06;
        this.cubearr[i].position.z += zdiff*0.06;
      } 
      
    }
  }
};


Shadercubes.prototype.createThings = function() {  
  this.cubepositions = [];
  this.planeMaterial = this.createMaterial();
  this.objcontainer = new THREE.Object3D();
  this.scene.add(this.objcontainer);

  var cubeSize = 21;

  this.cube2 = new THREE.Mesh(new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize), this.planeMaterial);
  this.cubearr = [];

  var startx = -30;
  var starty = 30;
  var startz = -30;

  for(var i = 0; i<3; i++) {
    startx=-30;
    for(var j = 0; j<3; j++) {
      startz = -30;
      for(var k = 0; k<3; k++) {
        var c = this.cube2.clone();
        c.position.x = startx;
        c.position.y = starty;
        c.position.z = startz;

        this.objcontainer.add(c);
        this.cubearr.push(c);
        this.cubepositions.push({x : c.position.x, y : c.position.y, z : c.position.z})
        startz +=30;
      }
      startx +=30;
    }
    starty -=30;
  }
};

Shadercubes.prototype.createMaterial = function(){
  this.timepoint1 = 0;
  this.timepoint2 = 0;
  this.circleStarted = false;
  this.circleStarted2 = false;
  this.circlesCount = 0;

  this.uniforms = {
    time : {type : "f", value: 0.0},
    resolution : {type : "v2", value: new THREE.Vector2(this.width, this.height)},
    gtime : {type : "f", value: 0.0},
    circleTime : {type : "f", value: 0.0},
    circleTime2 : {type : "f", value: 0.0},
    circlesOn : {type : "i", value: 0},
    bgpart : {type: "i", value: 1}
  };

  var material = new THREE.ShaderMaterial({
    uniforms : this.uniforms,
    vertexShader: MSHADERS.mvertex,
    fragmentShader: MSHADERS.circlesFragment,
    side : THREE.DoubleSide
  });
  
  return material; 
};
