

const deg2rad = 0.01745329251;
window.camPos = [0.0,0.0,0.0];
window.camPosLength = 1.0;
window.camFov = 0.0;
window.tick = .24
window.beat = 5*window.tick;
window.pattern = window.beat*4;
window.camNear = 0.0;
window.camFar = 0.0;
includeFile('multiSceneEffects/PostProcess.js');
includeFile('multiSceneEffects/dof.js')
includeFile('multiSceneEffects/EffectExplosion.js');
includeFile('multiSceneEffects/EffectStarfield.js');
includeFile('sceneIntro/intro.js');

Demo.prototype.cameraSetup = function(stopCamAt) {
  this.loader.addAnimation({
      "camera": "cam1"
      ,"position":[{"x":0,"y":0,"z":-5}]
      ,"lookAt":[{"x":0.0,"y":0.0,"z":0.0}]
      ,"up":[{"x":0,"y":1,"z":0}]
      ,"perspective":[{"fov":75,"aspect":16/9,"near":.05,"far":1000}]
      ,"distYawPitch":[-5.0,1,2.0]
      ,"instableTimer":[0.0,0.0,0.0,0.0,0.0]
      ,"runPreFunction": (animation)=>{
          if (stopCamAt !== undefined) {
              if (getSceneTimeFromStart() >= stopCamAt) {
                  return;
              }
          }

          for(let i=0;i<animation.instableTimer.length;i++)
              {
                  animation.instableTimer[i]+=Math.random()*getDeltaTime();
              }
          let distance = .05*Sync.get('Cam:Instability')*Math.sin(2*animation.instableTimer[3])+Sync.get('Cam:Distance');
          let pitch = (Sync.get('Cam:Instability')*5*Math.cos(2*animation.instableTimer[1])+Sync.get('Cam:Yaw'))*deg2rad;
          let roll = (Sync.get('Cam:Instability')*5*Math.sin(2*animation.instableTimer[2])+Sync.get('Cam:Pitch'))*deg2rad;
          let yaw = 0.0;
          let target = [Sync.get('Cam:TargetX'),Sync.get('Cam:TargetY'),Sync.get('Cam:TargetZ')]
          let points = [0,0,distance];
          let cosa = Math.cos(yaw),
              sina = Math.sin(yaw);
          let cosb = Math.cos(pitch),
              sinb = Math.sin(pitch);
          let cosc = Math.cos(roll),
              sinc = Math.sin(roll);
          let Axx = cosa*cosb,
              Axy = cosa*sinb*sinc - sina*cosc,
              Axz = cosa*sinb*cosc + sina*sinc;
          let Ayx = sina*cosb,
              Ayy = sina*sinb*sinc + cosa*cosc,
              Ayz = sina*sinb*cosc - cosa*sinc;
          let Azx = -sinb,
              Azy = cosb*sinc,
              Azz = cosb*cosc;
          let px = points[0];
          let py = points[1];
          let pz = points[2];
          let newPoints = [
              (Axx*px + Axy*py + Axz*pz) + target[0],
              Ayx*px + Ayy*py + Ayz*pz + target[1],
              Azx*px + Azy*py + Azz*pz + target[2]
              ];
          window.camPos = newPoints;
          window.camPosLength = Math.sqrt(newPoints[0]*newPoints[0]+newPoints[1]*newPoints[1]+newPoints[2]*newPoints[2]);
          animation.position[0].x = newPoints[0];
          animation.position[0].y = newPoints[1];
          animation.position[0].z = newPoints[2];
          animation.lookAt[0].x = Sync.get('Cam:Instability')*.25*Math.sin(2*animation.instableTimer[3])+Sync.get('Cam:TargetX');
          animation.lookAt[0].y = Sync.get('Cam:Instability')*.25*Math.cos(2*animation.instableTimer[4])+Sync.get('Cam:TargetY');
          animation.lookAt[0].z = Sync.get('Cam:TargetZ');
          animation.perspective[0].fov = Sync.get('Cam:FOV');
          window.camNear = animation.perspective[0].near;
          window.camFar = animation.perspective[0].far;
          window.camFov = animation.perspective[0].fov*deg2rad;
/*
          let totalPatterns = getSceneTimeFromStart()/window.pattern;
          let beatsAfterPatterns = ((totalPatterns-Math.floor(totalPatterns))*window.pattern)/window.beat;
          let ticksAfterBeats = ((beatsAfterPatterns-Math.floor(beatsAfterPatterns))*window.beat)/window.tick;
          console.log("patterns / beat / tick " + totalPatterns + " / " + beatsAfterPatterns + " / " + ticksAfterBeats);
*/
        }
  });      

  this.loader.addAnimation({
      "light": {
          "type": "Directional",
          "properties": { "intensity": 4.85 },
          "castShadow": false
      }
      ,position:[{x:()=>window.camPos[0]+8,y:()=>window.camPos[1]+4,z:()=>window.camPos[2]-4}]
      
      ,"color": [{
          "r": ()=>Sync.get('Light:R'), "g": ()=>Sync.get('Light:G'), "b": ()=>Sync.get('Light:B')
      }]
  });    
};

Demo.prototype.setScene = function (sceneName) {
    this.loader.setScene(sceneName);
    this.cameraSetup();
};

const settings = new Settings();
settings.engine.preload = false;
settings.demo.renderer.sortObjects = false;
settings.demo.renderer.logarithmicDepthBuffer = false;
settings.demo.sync.rocketFile = 'sync/demo.rocket';
settings.demo.sync.beatsPerMinute = 50;
settings.demo.sync.rowsPerBeat = 10;
settings.demo.camera.near = 0.1;
settings.demo.camera.far = 1000.0;
settings.demo.image.texture.minFilter = 'NearestFilter';
settings.demo.image.texture.magFilter = 'NearestFilter';
//settings.demo.image.texture.wrapS = 'RepeatWrapping';
//settings.demo.image.texture.wrapT = 'RepeatWrapping';
settings.demo.fbo.color.texture.minFilter = 'NearestFilter';
settings.demo.fbo.color.texture.magFilter = 'NearestFilter';
//settings.demo.fbo.color.texture.wrapS = 'RepeatWrapping';
//settings.demo.fbo.color.texture.wrapT = 'RepeatWrapping';

Demo.prototype.init = function () {
  const start = 0;
  const duration = 180;
  const bpm = 80;
  const beat = 60/bpm;
  const pattern = beat*6;

  this.sceneIntro();

  this.loader.setScene('main');

  const scenes = [
    {start: 0*window.pattern, duration: 400*window.pattern, name: 'intro',dof:true},
  ];

  scenes.forEach((scene) => {
    this.loader.addAnimation({start: scene.start, duration: scene.duration, scene:{name:scene.name, fbo:{name:scene.name + 'Fbo'}}});
  });

  this.loader.addAnimation({fbo:{name:'screenDof',action:'begin',storeDepth:false}});
    scenes.forEach((scene) => {
        if (scene.dof) {
            this.loader.addAnimation({start: scene.start, duration: scene.duration, color:scene.color, image: [scene.name + 'Fbo.depth.fbo',scene.name + 'Fbo.color.fbo'],
            material:{blending:'CustomBlending', blendEquation:'MaxEquation', blendSrc:'SrcColorFactor', blendDst:'SrcColorFactor'},
            shader: {name: 'multiSceneEffects/depthToColor.fs'}
            });
        }
    });
  this.loader.addAnimation({fbo:{name:'screenDof',action:'unbind'}});

  this.loader.addAnimation({fbo:{name:'screenFbo',action:'begin',storeDepth:false}});
    scenes.forEach((scene) => {
        if (!scene.prePostProcessing) {
            this.loader.addAnimation({start: scene.start, duration: scene.duration, color:scene.color, image: scene.name + 'Fbo.color.fbo'
            ,material:{blending:'NormalBlending'}
            });
            
        }

    });
            // text

  this.showText(0,20,
    0,1.0,0
    ,4.0,'JUMALAUTA', 'TEXT:jmlpresents');
  this.showText(0,20,
    0,.5,0
    ,3.0,'PRESENTS', 'TEXT:jmlpresents');

  this.showText(0,20,
    0,1.0,0
    ,4.0,'UNDERWATER', 'TEXT:uadventure');
 this.showText(0,20,
    0,.5,0
    ,3.0,'ADVENTURE', 'TEXT:uadventure');

  this.endText(104.5,40,
    0,.5,0
    ,3.0,'Fin.', null);
    
  this.loader.addAnimation({fbo:{name:'screenFbo',action:'unbind'}});
  
  this.loader.addAnimation({fbo:{name:'blur',action:'begin',storeDepth:false}});
    this.loader.addAnimation({image: 'screenFbo.color.fbo',
        material:{blending:'NormalBlending'},
        shader: { name: 'multiSceneEffects/gaussianBlur.fs',
            variable: [
            {"name":"directions", "value":[16.0]},
            {"name":"quality", "value":[4.0]},
            {"name":"size", "value":[16.0]}
            ]}
    });



  this.loader.addAnimation({fbo:{name:'blur',action:'unbind'}});

  this.loader.addAnimation({fbo:{name:'postProcessableFbo',action:'begin',storeDepth:false}});
    this.loader.addAnimation({
        image: ['screenFbo.color.fbo', 'blur.color.fbo', 'screenDof.color.fbo'],
        shader: { name: 'multiSceneEffects/dof.fs',
            variable: [
                {"name":"dofCenter", "value":[()=>Sync.get('General:dofCenter')]},
                {"name":"dofWidth", "value":[()=>Sync.get('General:dofWidth')]}
                ]}
    });
    this.showText(0,20,
        0,1.0,0
        ,4.0,'JUMALAUTA', 'TEXT:jmlpresents');
      this.showText(0,20,
        0,.5,0
        ,3.0,'PRESENTS', 'TEXT:jmlpresents');
    
      this.showText(0,20,
        0,1.0,0
        ,4.0,'UNDERWATER', 'TEXT:uadventure');
      this.showText(0,20,
        0,.5,0
        ,3.0,'ADVENTURE', 'TEXT:uadventure');

      this.endText(104.5,40,
        0,.5,0
        ,3.0,'Fin.', null);
        
  this.loader.addAnimation({fbo:{name:'postProcessableFbo',action:'unbind'}});

  this.addPostProcess('postProcessableFbo.color.fbo');

};

Demo.prototype.showText = function (startTime, duration, x, y, z, scale, text, syncName)
{
  this.loader.addAnimation([{
    "start":startTime,
    "duration":duration,
    "text":{"string":text,"name":"multiSceneEffects/font.ttf"
    },
    "id":text,
    "perspective":"3d", 
    "color":[{"r":.0,"g":.0,"b":1.0}],
    "position":[{"x":()=>Sync.get(syncName)+x,"y":()=>.05*Math.sin(getSceneTimeFromStart()*3)+y,"z":z}],
    "scale":[{"x":scale,"y":scale}],
   // "angle":[{"degreesY":()=>Sync.get('Cam:Yaw')}],
    "material":{
      "emissive": {"r":1.0,"g":1.0,"b":1.0}
    },
    }]);

    this.loader.addAnimation([{
      "start":startTime,
      "duration":duration,
      "text":{"string":text,"name":"multiSceneEffects/font.ttf"
      },
      "id":text,
      "perspective":"3d", 
      "color":[{"r":.0,"g":.0,"b":0.0}],
      "position":[{"x":()=>Sync.get(syncName)+.05+x,"y":()=>.05*Math.sin(getSceneTimeFromStart()*3)+y-.05,"z":z-.01}],
      "scale":[{"x":scale,"y":scale}],
     // "angle":[{"degreesY":()=>Sync.get('Cam:Yaw')}],
      "material":{
        "emissive": {"r":0.0,"g":0.0,"b":0.0}
      },
      }]);
}

Demo.prototype.endText = function (startTime, duration, x, y, z, scale, text, syncName)
{
  this.loader.addAnimation([{
    "start":startTime,
    "duration":duration,
    "text":{"string":text,"name":"multiSceneEffects/font2.ttf"
    },
    "id":text,
    "perspective":"3d", 
    "color":[{"r":.0,"g":.0,"b":1.0}],
    "position":[{"x":()=>Sync.get(syncName)+x,"y":()=>y,"z":z}],
    "scale":[{"x":scale,"y":scale}],
   // "angle":[{"degreesY":()=>Sync.get('Cam:Yaw')}],
    "material":{
      "emissive": {"r":1.0,"g":1.0,"b":1.0}
    },
    }]);

    this.loader.addAnimation([{
      "start":startTime,
      "duration":duration,
      "text":{"string":text,"name":"multiSceneEffects/font2.ttf"
      },
      "id":text,
      "perspective":"3d", 
      "color":[{"r":.0,"g":.0,"b":0.0}],
      "position":[{"x":()=>Sync.get(syncName)+x-.025,"y":()=>y+.025,"z":z+.01}],
      "scale":[{"x":scale,"y":scale}],
     // "angle":[{"degreesY":()=>Sync.get('Cam:Yaw')}],
      "material":{
        "emissive": {"r":0.0,"g":0.0,"b":0.0}
      },
      }]);
}