// A GAME MECHANIC EXPLORER DEMO
// http://gamemechanicexplorer.com/#bullets-5
var GameState = function(game) {};

// Load images and sounds
GameState.prototype.preload = function() {
    this.game.load.image('canon', 'img/canon.png');
    this.game.load.image('bullet', 'img/bullet.png');
    this.game.load.image('ground', 'img/ground.png');
    this.game.load.image('background', 'img/background.png');
    this.game.load.audio('shot', 'audio/shot.wav');
    this.game.load.spritesheet('blast', 'img/explosion.png', 128, 128);
    this.game.load.audio('explosion', 'audio/explosion.wav');
    this.game.load.image('enemy','img/enemy.png');
    this.game.load.audio('enemyexplosion', 'audio/enemy.wav');
    //this.game.load.spritesheet('explosion', 'explosion.png', 128, 128);
};

// Setup the example
GameState.prototype.create = function() {
    // Set stage background color
    this.game.stage.backgroundColor = 0x4488cc;
    this.game.sound.volume = 0.05;

    // Define constants
    this.SHOT_DELAY = 200; // milliseconds (10 bullets/3 seconds)
    this.BULLET_SPEED = 800; // pixels/second
    this.NUMBER_OF_BULLETS = 20;
    this.GRAVITY = 980; // pixels/second/second

    //Audio
    shotSound = this.game.add.audio('shot');
    explosionSound = this.game.add.audio('explosion');
    enemySound = this.game.add.audio('enemyexplosion');
    explosionSound.volume == 0.01;

    //Background
    this.game.add.tileSprite(0,0,6400,6400,'background');

    // Create an object representing our gun
    this.gun = this.game.add.sprite(50, this.game.height - 64, 'canon');

    // Set the pivot point to the center of the gun
    this.gun.anchor.setTo(0.5, 0.5);

    // Enemy
    this.enemies = this.game.add.group();
    var enemy1 = this.game.add.sprite(this.game.width-500, this.game.height-100,'enemy');
    var enemy2 = this.game.add.sprite(this.game.width-300, this.game.height-100,'enemy');
    this.game.physics.enable(enemy1, Phaser.Physics.ARCADE);
    this.game.physics.enable(enemy2, Phaser.Physics.ARCADE);
    enemy1.body.bounce.setTo(1,0.5);
    enemy1.body.collideWorldBounds=true;
    enemy1.body.mass=5000;
    enemy1.body.drag.setTo(100,100);
    enemy1.body.friction.setTo(5000,100);
    this.enemies.add(enemy1);

    enemy2.body.collideWorldBounds=true;
    enemy2.body.bounce.setTo(1,1);
    enemy2.body.mass=100;
    this.enemies.add(enemy2);

    // Create an object pool of bullets
    this.bulletPool = this.game.add.group();
    for(var i = 0; i < this.NUMBER_OF_BULLETS; i++) {
        // Create each bullet and add it to the group.
        var bullet = this.game.add.sprite(0, 0, 'bullet');
        this.bulletPool.add(bullet);

        // Set its pivot point to the center of the bullet
        bullet.anchor.setTo(0.5, 0.5);

        // Enable physics on the bullet
        this.game.physics.enable(bullet, Phaser.Physics.ARCADE);

        // Set its initial state to "dead".
        bullet.kill();
    }

    // Create some ground
    this.ground = this.game.add.group();
    for(var x = 0; x < this.game.width; x += 32) {
        // Add the ground blocks, enable physics on each, make them immovable
        var groundBlock = this.game.add.sprite(x, this.game.height - 32, 'ground');
        this.game.physics.enable(groundBlock, Phaser.Physics.ARCADE);
        groundBlock.body.friction.setTo(1000,1000);
        groundBlock.body.immovable = true;
        groundBlock.body.allowGravity = false;
        this.ground.add(groundBlock);
    }

    // Create a group for explosions
    this.explosionGroup = this.game.add.group();

    // Setup a canvas to draw the trajectory on the screen
    this.bitmap = this.game.add.bitmapData(this.game.width, this.game.height);
    this.bitmap.context.fillStyle = 'rgb(255, 255, 255)';
    this.bitmap.context.strokeStyle = 'rgb(255, 255, 255)';
    this.game.add.image(0, 0, this.bitmap);

    // Simulate a pointer click/tap input at the center of the stage
    // when the example begins running.
    this.game.input.activePointer.x = this.game.width/2;
    this.game.input.activePointer.y = this.game.height/2 - 100;

    // Show FPS
    this.game.time.advancedTiming = true;
    this.debugText = this.game.add.text(
        20, 20, '', { font: '16px Tahoma', fill: '#ffffff' }
    );
    this.debugText.setShadow(1,1,'rgba(0,0,0,0.5)',1);
    this.enemyText1 = this.game.add.text(enemy1.x,enemy1.y-36,'', {font: '16px Tahoma', fill: '#00ff24'});
    this.enemyText1.setShadow(1,1,'rgba(0,0,0,1)',1);
    this.enemyText2 = this.game.add.text(enemy2.x,enemy2.y-36,'', {font: '16px Tahoma', fill: '#00ff24'});
    this.enemyText2.setShadow(1,1,'rgba(0,0,0,1)',1);
};

GameState.prototype.drawTrajectory = function() {
    // Clear the bitmap
    this.bitmap.context.clearRect(0, 0, this.game.width, this.game.height);

    // Set fill style to white
    this.bitmap.context.fillStyle = 'rgba(215, 81, 68, 0.7)';

    // Calculate a time offset. This offset is used to alter the starting
    // time of the draw loop so that the dots are offset a little bit each
    // frame. It gives the trajectory a "marching ants" style animation.
    var MARCH_SPEED = 20; // Smaller is faster
    this.timeOffset = this.timeOffset + 1 || 0;
    this.timeOffset = this.timeOffset % MARCH_SPEED;

    // Just a variable to make the trajectory match the actual track a little better.
    // The mismatch is probably due to rounding or the physics engine making approximations.
    var correctionFactor = 0.99;

    // Draw the trajectory
    // http://en.wikipedia.org/wiki/Trajectory_of_a_projectile#Angle_required_to_hit_coordinate_.28x.2Cy.29
    var theta = -this.gun.rotation;
    var x = 0, y = 0;
    for(var t = 0 + this.timeOffset/(1000*MARCH_SPEED/60); t < 3; t += 0.03) {
        x = this.BULLET_SPEED * t * Math.cos(theta) * correctionFactor;
        y = this.BULLET_SPEED * t * Math.sin(theta) * correctionFactor - 0.5 * this.GRAVITY * t * t;
        this.bitmap.context.fillRect(x + this.gun.x, this.gun.y - y, 3, 3);
        if (y < -15) break;
    }

    this.bitmap.dirty = true;
};

GameState.prototype.shootBullet = function() {
    // Enforce a short delay between shots by recording
    // the time that each bullet is shot and testing if
    // the amount of time since the last shot is more than
    // the required delay.
    if (this.lastBulletShotAt === undefined) this.lastBulletShotAt = 0;
    if (this.game.time.now - this.lastBulletShotAt < this.SHOT_DELAY) return;
    this.lastBulletShotAt = this.game.time.now;

    // Get a dead bullet from the pool
    var bullet = this.bulletPool.getFirstDead();

    // If there aren't any bullets available then don't shoot
    if (bullet === null || bullet === undefined) return;

    // Revive the bullet
    // This makes the bullet "alive"
    bullet.revive();

    // Bullets should kill themselves when they leave the world.
    // Phaser takes care of this for me by setting this flag
    // but you can do it yourself by killing the bullet if
    // its x,y coordinates are outside of the world.
    //bullet.checkWorldBounds = true;
    //bullet.outOfBoundsKill = true;

    // Set the bullet position to the gun position.
    bullet.reset(this.gun.x, this.gun.y);
    bullet.rotation = this.gun.rotation;

    // Shoot it in the right direction
    bullet.body.velocity.x = Math.cos(bullet.rotation) * this.BULLET_SPEED;
    bullet.body.velocity.y = Math.sin(bullet.rotation) * this.BULLET_SPEED;
    shotSound.play();
};

// The update() method is called every frame
GameState.prototype.update = function() {
    if (this.game.time.fps !== 0) {
        this.debugText.setText(
          this.game.time.fps + ' FPS\n' +
          'Bullet Shot Speed = ' + this.BULLET_SPEED+'\n'+
          'World Gravity = ' + this.GRAVITY+'\n'+
          'Marco Sacristão 11907 - LEI@IPBEJA'
          );

        this.enemyText1.x=this.enemies.getAt(0).x;
        this.enemyText1.y=this.enemies.getAt(0).y-36;
        this.enemyText1.setText(
          'Mass:'+this.enemies.getAt(0).body.mass +'\n'
          );

        this.enemyText2.x=this.enemies.getAt(1).x;
        this.enemyText2.y=this.enemies.getAt(1).y-36;
        this.enemyText2.setText(
          'Mass:'+this.enemies.getAt(1).body.mass +'\n'
          );
    }

    // Turn on gravity
    this.game.physics.arcade.gravity.y = this.GRAVITY;

    // Draw the trajectory every frame
    this.drawTrajectory();

    // Check if bullets have collided with the enemy
    this.game.physics.arcade.collide(this.bulletPool, this.enemies, function(bullet, enemy){
      bullet.kill();
      explosionSound.play();
      this.getExplosion(bullet.x,bullet.y);
      enemy.body.velocity.x = Math.cos(bullet.rotation) * this.BULLET_SPEED;
      enemy.body.velocity.y = Math.sin(bullet.rotation) * this.BULLET_SPEED;
      enemySound.play();
    }, null,this);

    // Check if bullets have collided with the ground
    this.game.physics.arcade.collide(this.bulletPool, this.ground, function(bullet, ground) {
        // Create an explosion
        this.getExplosion(bullet.x, bullet.y);
        // Kill the bullet
        bullet.kill();
        explosionSound.play();
    }, null, this);

    // Check if enemies have collided with the ground
    this.game.physics.arcade.collide(this.enemies, this.ground);

    // Rotate all living bullets to match their trajectory
    this.bulletPool.forEachAlive(function(bullet) {
        bullet.rotation = Math.atan2(bullet.body.velocity.y, bullet.body.velocity.x);
    }, this);

    // Aim the gun at the pointer.
    // All this function does is calculate the angle using
    // Math.atan2(yPointer-yGun, xPointer-xGun)
    this.gun.rotation = this.game.physics.arcade.angleToPointer(this.gun);


    this.handleInput();
};


GameState.prototype.handleInput = function(){
   //KB->UP
    if(game.input.keyboard.isDown(Phaser.Keyboard.DOWN)){
      this.GRAVITY = this.GRAVITY+10;
    }
    //KB->DOWN
    if(game.input.keyboard.isDown(Phaser.Keyboard.UP)){
      this.GRAVITY = this.GRAVITY-10;
    }
    //KB->LEFT
    if(game.input.keyboard.isDown(Phaser.Keyboard.LEFT)){
      this.BULLET_SPEED = this.BULLET_SPEED-10;
    }
    //KB->RIGHT
    if(game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)){
      this.BULLET_SPEED = this.BULLET_SPEED+10;
    }
    // Shoot a bullet
    if (this.game.input.activePointer.isDown) {
        this.shootBullet();
    }
}
// Try to get a used explosion from the explosionGroup.
// If an explosion is not available, create a new one and add it to the group.
// Setup new explosions so that they animate and kill themselves when the
// animation is complete.
GameState.prototype.getExplosion = function(x, y) {
    // Get the first dead explosion from the explosionGroup
    var explosion = this.explosionGroup.getFirstDead();

    // If there aren't any available, create a new one
    if (explosion === null) {

    // Revive the explosion (set it's alive property to true)
    // You can also define a onRevived event handler in your explosion objects
    // to do stuff when they are revived.
    explosion.revive();

    // Move the explosion to the given coordinates
    explosion.x = x;
    explosion.y = y;

    // Set rotation of the explosion at random for a little variety
    explosion.angle = this.game.rnd.integerInRange(0, 360);

    // Play the animation
    explosion.animations.play('boom');

    // Return the explosion itself in case we want to do anything else with it
    return explosion;
};

var game = new Phaser.Game(1024, 600, Phaser.AUTO, 'game');
game.state.add('game', GameState, true);

window.focus();

        explosion = this.game.add.sprite(0, 0, 'blast');
        explosion.anchor.setTo(0.5, 0.5);

        // Add an animation for the explosion that kills the sprite when the
        // animation is complete
        var animation = explosion.animations.add('boom', [0,1,2,3], 60, false);
        animation.killOnComplete = true;

        // Add the explosion sprite to the group
        this.explosionGroup.add(explosion);
    }
