const CURSOR_OFFSET_X = 43;
const CURSOR_OFFSET_Y = (FONT_SIZE*2);

class InputPanel extends Phaser.Scene {

    constructor ()
    {
        super({ key: 'InputPanel', active: false });

        this.chars = [
            [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' ],
            [ 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T' ],
            [ 'U', 'V', 'W', 'X', 'Y', 'Z', '.', '-', '<', '>' ]
        ];

        this.cursor = new Phaser.Math.Vector2();

        this.text;
        this.block;

        this.name = '';
        this.charLimit = 3;
    }

    create ()
    {
        this.name = '';

        let text = this.add.bitmapText(config.width / 2, 50, 'atari', 'ABCDEFGHIJ\n\nKLMNOPQRST\n\nUVWXYZ.-', FONT_SIZE);
        text.setLetterSpacing(50);
        text.setPosition(config.width / 2 - text.width / 2, 50);


        text.setInteractive();

        this.add.image(text.x + text.width - 40, text.y + text.height, 'rub').setOrigin(1);
        this.add.image(text.x + text.width, text.y + text.height, 'end').setOrigin(1); // 52

        this.block = this.add.image(text.x - (FONT_SIZE/2), text.y - (FONT_SIZE/3), 'block').setOrigin(0);

        this.text = text;

        this.input.keyboard.on('keyup_LEFT', this.moveLeft, this);
        this.input.keyboard.on('keyup_RIGHT', this.moveRight, this);
        this.input.keyboard.on('keyup_UP', this.moveUp, this);
        this.input.keyboard.on('keyup_DOWN', this.moveDown, this);
        this.input.keyboard.on('keyup_ENTER', this.pressKey, this);
        this.input.keyboard.on('keyup_SPACE', this.pressKey, this);
        this.input.keyboard.on('keyup', this.anyKey, this);

        text.on('pointermove', this.moveBlock, this);
        text.on('pointerdown', this.moveBlock, this);
        text.on('pointerup', this.pressKey, this);

        this.tweens.add({
            targets: this.block,
            alpha: 0.2,
            yoyo: true,
            repeat: -1,
            ease: 'Sine.easeInOut',
            duration: 350
        });
    }

    moveBlock (pointer, x, y)
    {
        let cx = Phaser.Math.Snap.Floor(x, CURSOR_OFFSET_X, 0, true);
        let cy = Phaser.Math.Snap.Floor(y, CURSOR_OFFSET_Y, 0, true);
        let char = this.chars[cy][cx];

        this.cursor.set(cx, cy);

        this.block.x = this.text.x - (FONT_SIZE/2) + (cx * CURSOR_OFFSET_X);
        this.block.y = this.text.y - (FONT_SIZE/3) + (cy * CURSOR_OFFSET_Y);
    }

    moveLeft ()
    {
        if (this.cursor.x > 0)
        {
            this.cursor.x--;
            this.block.x -= CURSOR_OFFSET_X;
        }
        else
        {
            this.cursor.x = 9;
            this.block.x += CURSOR_OFFSET_X * 9;
        }
    }

    moveRight ()
    {
        if (this.cursor.x < 9)
        {
            this.cursor.x++;
            this.block.x += CURSOR_OFFSET_X;
        }
        else
        {
            this.cursor.x = 0;
            this.block.x -= CURSOR_OFFSET_X * 9;
        }
    }

    moveUp ()
    {
        if (this.cursor.y > 0)
        {
            this.cursor.y--;
            this.block.y -= CURSOR_OFFSET_Y;
        }
        else
        {
            this.cursor.y = 2;
            this.block.y += CURSOR_OFFSET_Y * 2;
        }
    }

    moveDown ()
    {
        if (this.cursor.y < 2)
        {
            this.cursor.y++;
            this.block.y += CURSOR_OFFSET_Y;
        }
        else
        {
            this.cursor.y = 0;
            this.block.y -= CURSOR_OFFSET_Y * 2;
        }
    }

    anyKey (event)
    {
        //  Only allow A-Z . and -

        let code = event.keyCode;

        if (code === Phaser.Input.Keyboard.KeyCodes.PERIOD)
        {
            this.cursor.set(6, 2);
            this.pressKey();
        }
        else if (code === Phaser.Input.Keyboard.KeyCodes.MINUS)
        {
            this.cursor.set(7, 2);
            this.pressKey();
        }
        else if (code === Phaser.Input.Keyboard.KeyCodes.BACKSPACE || code === Phaser.Input.Keyboard.KeyCodes.DELETE)
        {
            this.cursor.set(8, 2);
            this.pressKey();
        }
        else if (code >= Phaser.Input.Keyboard.KeyCodes.A && code <= Phaser.Input.Keyboard.KeyCodes.Z)
        {
            code -= 65;

            let y = Math.floor(code / 10);
            let x = code - (y * 10);

            this.cursor.set(x, y);
            this.pressKey();
        }
    }

    pressKey ()
    {
        let x = this.cursor.x;
        let y = this.cursor.y;
        let nameLength = this.name.length;

        this.block.x = this.text.x - (FONT_SIZE/2) + (x * CURSOR_OFFSET_X);
        this.block.y = this.text.y - (FONT_SIZE/3) + (y * CURSOR_OFFSET_Y);

        if (x === 9 && y === 2 && nameLength > 0)
        {
            //  Submit
            this.events.emit('submitName', this.name);
        }
        else if (x === 8 && y === 2 && nameLength > 0)
        {
            //  Rub
            this.name = this.name.substr(0, nameLength - 1);

            this.events.emit('updateName', this.name);
        }
        else if (this.name.length < this.charLimit)
        {
            //  Add
            this.name = this.name.concat(this.chars[y][x]);

            this.events.emit('updateName', this.name);
        }
    }
}

class Scene3 extends Phaser.Scene {

    constructor ()
    {
        //super({ key: 'Highscore', active: true });
        super("endGame");

        this.playerText;

        this.highScores = [];
        this.highScoreNames = [];
        this.newHighScore = false;
        this.newRank;
    }

    preload ()
    {
        this.load.image('block', 'assets/PNG/block.png');
        this.load.image('rub', 'assets/PNG/rub.png');
        this.load.image('end', 'assets/PNG/end.png');
        //this.load.bitmapFont('arcade', 'assets/fonts/bitmap/arcade.png', 'assets/fonts/bitmap/arcade.xml');
    }

    createFireWorksEffect() {
      var p0 = new Phaser.Math.Vector2(config.width / 4, config.height - (config.height / 4));
      var p1 = new Phaser.Math.Vector2(config.width / 4, config.height / 4);
      var p2 = new Phaser.Math.Vector2(config.width - (config.width / 4), config.height / 4);
      var p3 = new Phaser.Math.Vector2(config.width - (config.width / 4), config.height - (config.height / 4));

      var curve = new Phaser.Curves.CubicBezier(p0, p1, p2, p3);

      var max = 28;
      var points = [];
      var tangents = [];

      for (var c = 0; c <= max; c++)
      {
          var t = curve.getUtoTmapping(c / max);

          points.push(curve.getPoint(t));
          tangents.push(curve.getTangent(t));
      }

      var tempVec = new Phaser.Math.Vector2();

      var spark0 = this.add.particles('spark_red');
      var spark1 = this.add.particles('spark_blue');

      for (var i = 0; i < points.length; i++)
      {
          var p = points[i];

          tempVec.copy(tangents[i]).normalizeRightHand().scale(-32).add(p);

          var angle = Phaser.Math.RadToDeg(Phaser.Math.Angle.BetweenPoints(p, tempVec));

          var particles = (i % 2 === 0) ? spark0 : spark1;

          particles.createEmitter({
              x: tempVec.x,
              y: tempVec.y,
              angle: angle,
              alpha: 0.5,
              speed: { min: -100, max: 500 },
              gravityY: 200,
              scale: { start: 1.0, end: 0.1 },
              lifespan: 800,
              blendMode: 'SCREEN'
          });
      }
    }

    addPaddingToScore(score, width) {
      let newScore = score.toString();
      while (newScore.length < width) {
        newScore = ' ' + newScore;
      }
      return newScore;
    }

    create ()
    {
      // remove any previously saved state.
      localStorage.removeItem('saveRecord');
      this.newHighScore = false;

      this.background = this.add.tileSprite(0, 0, config.width, config.height, "background");
      this.background.setOrigin(0, 0);

      // load the high scores from local storage
      for (let i = 0; i < 5; i++) {
          this.highScores[i] = parseInt(localStorage.getItem('high_score_' + config.questionSet + '_' + i)) || 0;
          this.highScoreNames[i] = localStorage.getItem('high_score_name_' + config.questionSet + '_' + i) || 'AAA';
      }

      // check if the current score is a high score
      for (let i = 0; i < 5; i++) {
        if (config.score > this.highScores[i]) {
          this.createFireWorksEffect();
          this.add.bitmapText(config.width / 2, 230, 'atari', 'You Got a High Score!', 32).setOrigin(0.5).setTint(0xff00ff);
          this.newHighScore = true;
          this.newRank = i;
          this.highScores.splice(i, 0, config.score);
          break;
        }
      }

      if (!this.newHighScore) {
        this.add.bitmapText(config.width / 2, 230, 'atari', 'Your Score: ' + config.score, 32).setOrigin(0.5).setTint(0xff00ff);
      }

        var titleText = this.add.bitmapText(100, 260, 'atari', 'RANK  SCORE   NAME',FONT_SIZE).setTint(0xff00ff);
        var x_offset = config.width/2 - titleText.width/2;
        this.x_offset = x_offset;
        titleText.setPosition(x_offset, 260);

        var leaderboard = [];
        leaderboard[0] = this.add.bitmapText(this.x_offset, 310, 'atari', '1ST   ',FONT_SIZE).setTint(0xff0000);
        leaderboard[1] = this.add.bitmapText(this.x_offset, 360, 'atari', '2ND   ',FONT_SIZE).setTint(0xff8200);
        leaderboard[2] = this.add.bitmapText(this.x_offset, 410, 'atari', '3RD   ',FONT_SIZE).setTint(0xffff00);
        leaderboard[3] = this.add.bitmapText(this.x_offset, 460, 'atari', '4TH   ',FONT_SIZE).setTint(0x00ff00);
        leaderboard[4] = this.add.bitmapText(this.x_offset, 510, 'atari', '5TH   ',FONT_SIZE).setTint(0x00bfff);

        for (let i = 0; i < 5; i++) {
          let text = leaderboard[i].text;
          if (this.newHighScore && this.newRank == i) {
            leaderboard[i].setText(text + this.addPaddingToScore(this.highScores[i], 5));
            this.playerText = this.add.bitmapText(this.x_offset + (14*FONT_SIZE), leaderboard[i].y, 'atari', '',FONT_SIZE).setTint(0xff0000);

            this.tweens.add({
                targets: [leaderboard[i], this.playerText],
                alpha: 0.2,
                yoyo: true,
                repeat: -1,
                ease: 'Sine.easeInOut',
                duration: 350
            });
          } else {
            leaderboard[i].setText(text + this.addPaddingToScore(this.highScores[i], 5) + '   ' + this.highScoreNames[i]);
          }
        }

        // call the input panel to put the name in if this is a new high score.
        if (this.newHighScore) {
          //  Do this, otherwise this Scene will steal all keyboard input
          this.input.keyboard.enabled = false;

          this.scene.launch('InputPanel');

          let panel = this.scene.get('InputPanel');

          //  Listen to events from the Input Panel scene
          panel.events.on('updateName', this.updateName, this);
          panel.events.on('submitName', this.submitName, this);
        } else {
          this.addPlayAgainText();
        }
    }

    addPlayAgainText() {
      let playAgainText = this.add.bitmapText(config.width / 2, config.height / 2 + 235, 'atari', 'Play Again?', FONT_SIZE);
      playAgainText.setOrigin(0.5);
      playAgainText.setInteractive();
      playAgainText.on("pointerup", function() {
        if (false) {
          // reset the high scores.
          for (let i = 0; i < 5; i++ ) {
            localStorage.setItem('high_score_' + config.questionSet + '_' + i, 0);
            localStorage.setItem('high_score_name_' + config.questionSet + '_' + i, 'AAA');
          }
        }
        this.scene.start('bootGame');
      }, this);
    }

    submitName ()
    {
        this.scene.stop('InputPanel');

        // save the high scores to local storage.
        if (this.newHighScore) {
          localStorage.setItem('high_score_' + config.questionSet + '_' + this.newRank, config.score);
          localStorage.setItem('high_score_name_' + config.questionSet + '_' + this.newRank, this.playerText.text);
        }

        this.addPlayAgainText();
    }

    updateName (name)
    {
        this.playerText.setText(name);
    }

    update(time, delta) {
      this.background.tilePositionY -= 1.5;
    }

}

    /*
    Game.saveFile = function(){
        var file = {
            score: Game.scene.score,
            visits: Game.scene.visits
        };
        localStorage.setItem('saveFile',JSON.stringify(file));
    };

    Game.loadFile = function(){
        var file = JSON.parse(localStorage.getItem('saveFile'));
        Game.scene.score = file.score;
        Game.scene.visits = file.visits;
    };
*/
