/**
 * @author Lewis Dunstall lewisdunstall@gmail.com
 * @version 
 * 
*/

var config = {
    type: Phaser.AUTO,
    width: 1024,
    height: 2048,
    scale: {
        /** Fit to window */
        mode: Phaser.Scale.FIT,
        /** Center vertically and horizontally */
        autoCenter: Phaser.Scale.CENTER_BOTH
    },

    physics: {
        default: 'arcade',
        arcade: {
            gravity: {
                y: 3000
            },
            debug: false
        }
    },
    scene: {
        preload: preload,
        create: create,
        update: update
    }
};

var Height = 2048;

let playing_bool = false;

let start_txt = "";

let score_str = 'The score : ';
let score = 0;

var player1_spr;

var collect;

var platform_grp;

var cursors;

var Platform_spr;

var background_spr;

var enemySpike_spr;

var Coin_grp;

var WormEnemy_spr;

var highScore_str;

var highScore = 100;


// global music variable

var music;

var canmove = false;


var game = new Phaser.Game(config);

function preload() {

    this.load.audio('theme', [
        'assets/audio/BackBeat.ogg',
        'assets/audio/BackBeat.mp3'
    ]);

    this.load.image('background', 'assets/Background.png');
    
    this.load.image('coin', 'assets/Coin.png',{
        frameWidth: 60,
        frameHeight: 60
    });

    this.load.image('platform', 'assets/PlatformGreen.png');


    this.load.spritesheet('Wormspr', 'assets/Worm.png',{
        frameWidth: 153,
        frameHeight: 170
    });

    this.load.spritesheet('enemySpike', 'assets/enemySpike.png',{
        frameWidth: 96,
        frameHeight: 96
    });

    this.load.spritesheet('player', 'assets/PlayerSpriteSheet.png',{
        frameWidth: 80,
        frameHeight: 80
    });

    this.load.audio('BackBeat', ['assets/audio/BackBeat.mp3', 'assets/audio/BackBeat.ogg']);

    this.load.audio('collect', ['assets/audio/collect.mp3', 'assets/audio/collect.ogg']);

    this.load.audio('death', ['assets/audio/death.mp3', 'assets/audio/death.ogg']);
}

function create() {
    
  // logs to see if the game is working all right
    console.log('The game Cyclops is running');

    // create the music

    music = this.sound.add('BackBeat');
    //the background music
 
    background_spr = this.add.image(0, 0, 'background').setOrigin(0).setScrollFactor(1);
    //The background image

    enemySpike_spr = new enemySpike(this, 600, 500, 'enemySpike');
    enemySpike_spr.body.allowGravity = false;

    enemySpike_spr2 = new enemySpike(this, 256, 1100, 'enemySpike');
    enemySpike_spr2.body.allowGravity = false;

    enemySpike_spr3 = new enemySpike(this, 800, 1600, 'enemySpike');
    enemySpike_spr3.body.allowGravity = false;

    enemySpike_spr4 = new enemySpike(this, 400, 1600, 'enemySpike');
    enemySpike_spr4.body.allowGravity = false;
    // enemy spikes



    WormEnemy_spr = new enemyWorm(this, 512, 1200, 'Wormspr');
    WormEnemy_spr.body.allowGravity = false;
    // worm enemy
   
    
    Coin_grp = this.physics.add.staticGroup()// A group to hold things that don't move 
    Coin_grp.create(512, 900, 'coin');
    Coin_grp.create(300, 900, 'coin');
    Coin_grp.create(250, 700, 'coin');
    Coin_grp.create(720, 500, 'coin');
    Coin_grp.create(210, 300, 'coin');
    Coin_grp.create(500, 1100, 'coin');
    Coin_grp.create(1000, 1750, 'coin');
    Coin_grp.create(256, 120, 'coin');
    Coin_grp.create(575, 150, 'coin');
    Coin_grp.create(600, 350, 'coin');
    Coin_grp.create(300, 1920, 'coin');
    Coin_grp.create(760, 1800, 'coin');
    Coin_grp.create(360, 1200, 'coin');
    Coin_grp.create(360, 1200, 'coin');
    Coin_grp.create(900, 900, 'coin');
    Coin_grp.create(750, 300, 'coin');
    Coin_grp.create(120, 200, 'coin');
    Coin_grp.create(200, 1400, 'coin');
    Coin_grp.create(700, 1300, 'coin');
    Coin_grp.create(850, 1700, 'coin');
    Coin_grp.create(550, 600, 'coin');
    Coin_grp.create(512, 1600, 'coin');
    Coin_grp.create(650, 1420, 'coin');
    Coin_grp.create(900, 1480, 'coin');
    Coin_grp.create(80, 1600, 'coin');
    Coin_grp.create(80, 1100, 'coin');
    Coin_grp.create(700, 1000, 'coin');
    Coin_grp.create(700, 700, 'coin');
    Coin_grp.create(400, 450, 'coin');
    Coin_grp.create(50, 575, 'coin');
    Coin_grp.create(900, 535, 'coin');
    Coin_grp.create(950, 250, 'coin');


    platforms_grp = this.physics.add.staticGroup(); // A group to hold things that don't move 
   
    platforms_grp.create(600, 900, 'platform');
    platforms_grp.create(1000, 350, 'platform');
    platforms_grp.create(270, 720, 'platform');
    platforms_grp.create(200, 400, 'platform');
    platforms_grp.create(750, 100, 'platform');
    platforms_grp.create(1000, 1800, 'platform');
    platforms_grp.create(900, 850, 'platform');
    platforms_grp.create(300, 460, 'platform');
    platforms_grp.create(200, 660, 'platform');
    platforms_grp.create(750, 360, 'platform');
    platforms_grp.create(810, 760, 'platform');
    platforms_grp.create(700, 1900, 'platform');
    platforms_grp.create(200, 1840, 'platform');
    platforms_grp.create(500, 1460, 'platform');
    platforms_grp.create(80, 1200, 'platform');
    platforms_grp.create(30, 870, 'platform');
    platforms_grp.create(370, 375, 'platform');
    platforms_grp.create(175, 1700, 'platform');
    platforms_grp.create(170, 980, 'platform');
    platforms_grp.create(130, 720, 'platform');
    platforms_grp.create(800, 880, 'platform');
    platforms_grp.create(250, 1024, 'platform');
    platforms_grp.create(620, 1220, 'platform');
    platforms_grp.create(890, 1350, 'platform');
    platforms_grp.create(670, 1100, 'platform');
    platforms_grp.create(950, 700, 'platform');
    platforms_grp.create(840, 1115, 'platform');
    platforms_grp.create(320, 800, 'platform');
    platforms_grp.create(200, 1500, 'platform');
    platforms_grp.create(300, 1300, 'platform');
    

    // Create a moving platform sprite 
    Platform_spr = this.physics.add.image(300, 50, 'platform');
    Platform_spr.body.allowGravity = false;
    Platform_spr.setVelocityX(100);
    Platform_spr.setImmovable(true);

    Platform_spr2 = this.physics.add.image(600, 250, 'platform');
    Platform_spr2.setImmovable(true);
    Platform_spr2.body.allowGravity = false;
    Platform_spr2.setVelocityX(100);
    
    Platform_spr3 = this.physics.add.image(700, 750, 'platform');
    Platform_spr3.setImmovable(true);
    Platform_spr3.body.allowGravity = false;
    Platform_spr3.setVelocityX(100);

    // creates the player sprite
    player1_spr = new Player(this, 512, 2000, 'player');
    

    // create the animtions 
    this.anims.create({
        key: 'left',
        frames: this.anims.generateFrameNumbers('player', {
            start: 0,
            end: 3
        }),
        frameRate: 10,
        repeat: -1
    });

    this.anims.create({
        key: 'up',
        frames: this.anims.generateFrameNumbers('player', {
            start: 0,
            end: 3
        }),
        frameRate: 10,
        repeat: -1
    });

    this.anims.create({
        key: 'turn',
        frames: this.anims.generateFrameNumbers('player',{
            key: 'player',
            frame: 0
        }),
        frameRate: 20
    });


    this.anims.create({
        key: 'right',
        frames: this.anims.generateFrameNumbers('player', {
            start: 0,
            end: 3
        }),
        frameRate: 10,
        repeat: -1
    });

    this.anims.create({
        key: 'enemy',
        frames: this.anims.generateFrameNumbers('enemySpike', {
            start: 0,
            end: 14
        }),
        frameRate: 10,
        repeat: -1
    });

    this.anims.create({
        key: 'enemy2',
        frames: this.anims.generateFrameNumbers('enemySpike', {
            start: 0,
            end: 14
        }),
        frameRate: 10,
        repeat: -1
    });

    this.anims.create({
        key: 'Wmv',
        frames: this.anims.generateFrameNumbers('Wormspr', {
            start: 0,
            end: 17
        }),
        frameRate: 10,
        repeat: -1
    });
    
  
     // Add the start text
    start_txt = this.add.text(512, 1600, ' ', {
        font: '48px Arial',
        fill: '#000000'
    });
    start_txt.setOrigin(0.5, 0.5);
    start_txt.text = "Click to Start";

    //  Add the score text 
    score_txt = this.add.text(256, 512, '', {
        font: '34px Arial',
        fill: '#0c4aad'
    }).setScrollFactor(0);

    // Add the  high score text 
    highScore_txt = this.add.text(450, 512, '', {
        font: '34px Arial',
        fill: '#0c4aad'
    }).setScrollFactor(0);
    
/**  cursors use the keyboard as a imput this is used by the 
     player class to move it when a player presses said button*/
    cursors = this.input.keyboard.createCursorKeys();

    // camera settings with set bounds and follow player and it is zoomed in.
       this.cameras.main.setBounds(0, 0, 1024, 2048);
       this.cameras.main.startFollow(player1_spr, true, 2, 25);
       this.cameras.main.zoom = 2; 
       /**  This code was based on code from a Phaser example <https://phaser.io/examples/v3/view/camera/follow-zoom> 
                 This original code was modifed to include a set boundary for the camera and the zoom level also changed 
                     alongside values in the startFollow being modified. */

       // the input that is used by the start text.
        this.input.addListener('pointerdown', startGame, this);

        /* these all edit the physics for objects so they collide with the player
        and either collect it or kill it.
        */
        this.physics.add.overlap(player1_spr, Coin_grp, collectCoin, null, this);

        this.physics.add.overlap(player1_spr,platforms_grp, killPlayer, null, this);

    
        this.physics.add.overlap(player1_spr,Platform_spr, killPlayer, null, this);
        this.physics.add.overlap(player1_spr,Platform_spr2, killPlayer, null, this);
        this.physics.add.overlap(player1_spr,Platform_spr3, killPlayer, null, this);

        this.physics.add.overlap(player1_spr,enemySpike_spr, killPlayer, null, this);
        this.physics.add.overlap(player1_spr,enemySpike_spr2, killPlayer, null, this); 
        this.physics.add.overlap(player1_spr,enemySpike_spr3, killPlayer, null, this); 
        this.physics.add.overlap(player1_spr,enemySpike_spr4, killPlayer, null, this); 
       
        this.physics.add.overlap(player1_spr,WormEnemy_spr, killPlayer, null, this); 
}


function startGame() {

    canmove = true;
    //when this is true things move
   
    //start text and it's listener are added then removed
    this.input.addListener('pointerdown', startGame, this);
    start_txt.visible = false;

    this.input.removeListener('pointerdown', startGame);
    playing_bool = true;
// while this is true the game is played things update


 

    music.play({
        loop: true
    });
    /** The music variable is sourced and plays the audio:
     *  it then loops music making sure it is true.
     */
   
    
    //updates the score and highscore
    score_txt.text = 'Score: ' + score;
    highScore_txt.text = 'High score: ' + highScore;
}


function update() {
//if this is true everything happens
    if (playing_bool = true) {
// text is set up
    score_txt.setText('Score: ' + score)
    highScore_txt.setText('High Score: ' + highScore)
   //loop to update and maintain highscore.
    if(score >= highScore){
        highScore = score;
    }
// moves the background
    background_spr.y += 2;
    if (background_spr.y >= 0) {
        background_spr.y = -Height;
    }      
    // if can move is true 
    if(canmove){
                            // all these functions are allowed to start
                            WormEnemy_spr.WormGetMove()
                            enemySpike_spr.updateMove()
                            enemySpike_spr2.updateMove2()
                            enemySpike_spr3.updateMove3()
                            enemySpike_spr4.updateMove4()
                            player1_spr.updateMe(cursors);
                //moves the platform
                if (Platform_spr.x >= 150) {
                Platform_spr.setVelocityX(-200);
                } else if (Platform_spr.x <= 30) {
                Platform_spr.setVelocityX(200);
                }
                //moves the platform
                if (Platform_spr2.x >= 600) {
                Platform_spr2.setVelocityX(-200);
                } else if (Platform_spr2.x <= 400) {
                Platform_spr2.setVelocityX(200);
                }
                //moves the platform
                if (Platform_spr3.x >= 400) {
                Platform_spr3.setVelocityX(-200);
                } else if (Platform_spr3.x <= 200) {
                Platform_spr3.setVelocityX(200);
            }
         }
    }  


}/* end of update */
function collectCoin(player_spr1, Coin_grp) {
    Coin_grp.disableBody(true, true);//coin disapears 
    score += 50;//update the score
    var collect = this.sound.add('collect');//collect sound is a var
    collect.play();//collect is played
    console.log("A coin has been collected");//logs it to the console
}


function killPlayer(player_spr1, platforms_grp) {
   
    player_spr1.disableBody(true, true);//disables body
    
  
  start_txt.text = "";
  start_txt.visible = true;
 //updates the start text
    
    console.log("Game restart");//logs restart
    score = 0;//score updated
    var death = this.sound.add('death');//death sound added
    death.play();//death sound played

    music.destroy();//music stops
    
    canmove = false;//nothing can move now
    
    for (var count=0; count< Coin_grp.getLength(); count++) {
        Coin_grp.getChildren()[count].enableBody(false, true, true)
      }    //resets the coin if they have been disables

      //restart the scene
      this.scene.restart();
      // I used the following Phaser example <https://phaser.io/examples/v3/view/physics/matterjs/scene-restart> to find out best how to restart the scene.
}