w = 800;
h = 600;

music = new AudioStream("data/edzes_fastintro.ogg");

SetupFullscreen(w, h, "INVADERCRAFT");
fb = new Framebuffer(w, h, 0, PixelFormatR8G8B8A8, true, true);
fb2 = new Framebuffer(w, h, 0, PixelFormatR8G8B8A8, true, true);
fb3 = new Framebuffer(w, h, 0, PixelFormatR8G8B8A8, true, true);

intro_layer = new Layer();
intro_layer.SetBlendMode(BlendModeReplace);
intro = new Quad(intro_layer, 0, 0, w, h);
intro.SetImage("data/invadercraft.png");
 
//BG
bg_layer = new Layer();
bg_layer.SetBlendMode(BlendModeReplace);
bg = new Quad(bg_layer, 0, 0, w, h);
bg.SetImage("data/bluesky.png");

//BIGBEN
bigben_layer = new Layer();
bigben_layer.SetBlendMode(BlendModeReplace);
bigben = new Quad(bigben_layer, 0, 0, 200, 350);
bigben.SetImage("data/bigben.png");

//TRUCK
truck_layer = new Layer();
truck_layer.SetBlendMode(BlendModeReplace);
truck = new Quad(truck_layer, 0, 0, 300, 100);
truck.SetImage("data/truck.png");

//LONDON BRIDGE
lb_layer = new Layer();
lb_layer.SetBlendMode(BlendModeReplace);
lb = new Quad(lb_layer, 0, 0, 780, 553);
lb.SetImage("data/lb.png");

//VIKINGSKIPET
viking_layer = new Layer();
viking_layer.SetBlendMode(BlendModeReplace);
viking = new Quad(viking_layer, 0, 0, 700, 377);
viking.SetImage("data/vikingskipet.png");

//GRASS
grass_layer = new Layer();
grass_layer.SetBlendMode(BlendModeReplace);
grass = new Quad(grass_layer, 0, 0, 2480, h);
grass.SetImage("data/grass.png");

//WORLD
world = new World();
world2 = new World();
world3 = new World();

//ROOM
room = new WorldObject(world, "data/primitives/cube.dae");
room_args = {};
room_args.DiffuseMap = "data/bluesky.png";
room.SetParameters(room_args);
room.SetProgram("data/shaders/texturing.cg");
room.SetScale(20,20,20);

room2 = new WorldObject(world3, "data/primitives/cube.dae");
room2_args = {};
room2_args.DiffuseMap = "data/textures/rb.jpg";
room2.SetParameters(room2_args);
room2.SetProgram("data/shaders/envmapping_with_bump.cg");
room2.SetScale(50,50,50);

//CUBES
cube_i = 0;
cube_list = []
cube_pos = []
cube_args = {}

size = 2;
positions = [];
function makeCube(x, y, z, texture, entity) {

  cube_args.DiffuseMap = texture;
  cube_args.NormalMap = "data/textures/cracky_nm.jpg"
  
  cube_list[cube_i] = new WorldObject(world2, "data/primitives/smooth_cube.dae");	  
  cube_list[cube_i].SetParameters(cube_args);
  cube_list[cube_i].SetScale(size/10,size/10,size/10);
  cube_list[cube_i].SetPosition(entity.position.x+x, entity.position.z+z, entity.position.y+y);
  cube_list[cube_i].SetProgram("data/shaders/envmapping_with_bump.cg");
  
  cube_pos[cube_i] = {x: x, y: y, z: z};
  entity.cubes.push(cube_i); 
  
  cube_i++;
}

entity = function (x, y, z) {
  self = {};
  self.cubes = [];
  self.position = {x: x, y: y, z: z};
  self.velocity = {x: 0, y: 0, z: 0};
  self.animationSpeed = 0;
  self.animationCurrent = 0;
  self.animationTick = 0;
  
  self.move = function (time) {   
    this.position.x += this.velocity.x;
    this.position.y += this.velocity.y;
    this.position.z += this.velocity.z;
    
    for (j = 0; j < this.cubes.length; j++) {   
      c = this.cubes[j];  
      
      if (cube_list[c] == undefined)
        continue;
                           
      cube_list[c].SetPosition(this.position.x + cube_pos[c].x, 
                               this.position.z + cube_pos[c].z, 
                               this.position.y + cube_pos[c].y);
    }
  }
  
  self.animate = function (time) {
  
    if (this.pattern.length == 1) {
      return;
    }

    this.animationTick++;

    if (this.animationTick == this.animationSpeed) {
      this.animationCurrent++;
      
      if (this.animationCurrent >= this.pattern.length) {
        this.animationCurrent = 0; 
      }
      
                      
    
      for (i = 0; i < this.cubes.length; i++) {
        if (cube_list[this.cubes[i]] == undefined) {
          continue;
        }
          
        cube_list[this.cubes[i]].Delete();
        cube_list[this.cubes[i]] = undefined;
      }
       
      this.cubes = [];

      cubeFromString(this, this.animationCurrent);
      this.animationTick = 0;
    }  
  }
  
  self.accelerate = function (time) {
  
  }
  
  return self;
}

man = function (x, y, z) { 
  self = entity(x, y, z);
  
  self.velocity = {x: -0.1, y: 0, z: 0};
  self.animationSpeed = 50;
   
  self.pattern = ["  ###  \n" +
                  "  ###  \n" + 
                  "  ###  \n" + 
                  "#  #   \n" + 
                  "#######\n" + 
                  "   #  #\n" + 
                  "   #   \n" + 
                  "  ###  \n" + 
                  "  # #  \n" + 
                  "  # ## ",
                  
                  "  ###  \n" +
                  "  ###  \n" + 
                  "  ###  \n" + 
                  "   #  #\n" + 
                  "#######\n" + 
                  "#  #   \n" + 
                  "   #   \n" + 
                  "  ###  \n" + 
                  "  # #  \n" + 
                  "  # ## "];
  return self;
            
};


cyborg = function (x, y, z) {
  self = entity(x, y, z);
  self.velocity = {x: -0.1, y: 0, z: 0};
  self.animationSpeed = 20;
   
  self.pattern = ["  %%%  \n" +
                  "  ¤¤¤  \n" + 
                  "  %%%  \n" + 
                  "#  #   \n" + 
                  "#####%%\n" + 
                  "   #  %\n" + 
                  "   #   \n" + 
                  "  ###  \n" + 
                  "  # #  \n" + 
                  "  # ## ",
                  
                  "  %%%  \n" +
                  "  ¤¤¤  \n" + 
                  "  %%%  \n" + 
                  "   #  %\n" + 
                  "#####%%\n" + 
                  "#  #   \n" + 
                  "   #   \n" + 
                  "  ###  \n" + 
                  "  # #  \n" + 
                  "  # ## "];
                  
  return self;
            
}

invader = function (x, y, z) {
  parent = entity(x, y, z);
  
  self.velocity = {x: -0.2, y: 0, z: 0};
   
  self.pattern = ["  #     #  \n" +
                  "   #   #   \n" +
                  "  #######  \n" +
                  " ## ### ## \n" +
                  "###########\n" +
                  "# ####### #\n" +
                  "# #     # #\n" + 
                  "   ## ##   "];
                  
  self.accelerate = function (time) {
    if ((time*10 % 12) < 6) {
      this.velocity.y = -0.1;
    }
    else {
      this.velocity.y = 0.1;
    }
    
    this.animationTick++;
    
    if (this.animationTick == 100) {
      makeNew(shot, this.position.x+10, this.position.y-20, this.position.z);
      this.animationTick = 0;
    }
    
  }
                 
  return self;
            
}

shot = function (x, y, z) {
  self = entity(x, y, z);
  self.velocity = {x: 0.0, y: -0.5, z: 0};
   
  self.pattern = ["¤\n" +
                  "¤\n"];
                  
  return self;
            
}

function cubeFromString(entity, pat) {      
  lines = entity.pattern[pat].split("\n");
  for (row = 0; row < lines.length; row++) { 
    line = lines[row];   
    for (i = 0; i < line.length; i++) {
      
      if (line.charAt(i) == '#') {
        texture = "data/textures/rb.jpg";
      }
      else if (line.charAt(i) == "¤") {
        texture = "data/textures/red.png";
      }  
      else if (line.charAt(i) == "%") {
        texture = "data/textures/grey.png";
      }     
        
      if (line.charAt(i) != ' ') {     
        makeCube(i*size*1.0, -row*size*1.0, 0, texture, entity);
      }
    } 
  }
}

entity_i = 0;
entities = [];
function makeNew (entity, x, y, z) {
    entities[entity_i] = entity(x, y, z); 
    cubeFromString(entities[entity_i], 0);
    entity_i++;
    
    return entities[entity_i-1];
}

mainInvader = makeNew(invader, 20, 30, 10);
        
makeNew(man, 0, 0, 0);  
makeNew(man, 10, 0, -20);
makeNew(man, 30, 0, -10);
makeNew(man, 60, 0, -20);
makeNew(man, 80, 0, 0);
makeNew(man, 80, 0, -20);
makeNew(man, 90, 0, -30);
makeNew(cyborg, 130, 0, 0);
makeNew(cyborg, 110, 0, -20);
makeNew(cyborg, 140, 0, -30);

wingmen = [makeNew(invader, -100, 20, 80),
          makeNew(invader, -130, 20, 100),
          makeNew(invader, -160, 20, 70)];

//cubeFromString(str, 0, 0, 2);
//cubeFromString(str, 0, 10, 4);

music.Play();

while (Update() && !KeyDown(KeyEsc))
{
  time = GetTime()+0;
  if(time < 5) {
    intro_layer.Render();
  } else if(time < 36) {
     
      time = time-5;
      bg_layer.Render();
      // Move all objects to the left
      for (i = 0; i < entities.length; i++) {
        e = entities[i];
        e.accelerate(time);  
        e.move(time);
        //e.animate(time); 
      }                      
      
      // Move main invader
      if (time < 5) {
        mainInvader.velocity.x = 0;
        
        for (i = 0; i < wingmen.length; i++) {
          wingmen[i].velocity.x = 3;
        }
      }
      
      else if (time < 6) {
        mainInvader.velocity.x = -0.8;
        
        for (i = 0; i < wingmen.length; i++)
          wingmen[i].velocity.x = -2;  
      }
      
      else if (time < 11) {
        mainInvader.velocity.x = 0;
        
        for (i = 0; i < wingmen.length; i++)  {
          wingmen[i].position.y = 20;
          wingmen[i].position.z = -i*10;
          wingmen[i].velocity.x = -1;  
        }
      }
      
      else if (time < 30) {
        mainInvader.velocity.x = 0;
        
        for (i = 0; i < wingmen.length; i++)  {
          wingmen[i].velocity.x = 0.5;  
        }
      }
      
      // Wingmen invaders
      
    
      PushFramebuffer(fb);
    	Clear(1,0,0,0,1,0);
    	world.SetCameraTarget(0,0,0);
    	//world.SetCameraPosition(Math.sin(GetTime()*2)*80, Math.cos(GetTime())*80, Math.sin(GetTime()*0.5)*100);
    	
    	world.Render();
    	
    	viking_layer.Render();
    	viking.SetPosition(-800+time*20, 100);
    	
    	lb_layer.Render();
    	lb.SetPosition(-200+time*20, 0);
    
      bigben_layer.Render();
    	bigben.SetPosition(500+time*20, 30);
    
    
    	
    	grass_layer.Render();
    	grass.SetPosition(-1024+time*30, 0);
    	
    	PushFramebuffer(fb);
    	world2.SetCameraTarget(0,0,0);
    	world2.Render();
    	PopFramebuffer();
    	
    	if(time > 30) {
        truck_layer.Render();
        truck.SetPosition(800-(time-30)*400, 400);
      }
    	
      PopFramebuffer();
    	fb.Blit();
  } else {
      PushFramebuffer(fb3);
    	Clear(1,0,0,0,1,0);
    	world3.SetCameraTarget(0,0,0);
    	world3.SetCameraPosition(Math.sin(GetTime()*2)*20, Math.cos(GetTime())*20, Math.sin(GetTime()*0.5)*30);
    	
    	
    	
    	world3.Render();
      PopFramebuffer();
    	fb3.Blit();
    	if(time > 55) {
        break;
      }
  }
  
}