/*
 * Game state
 * ============================================================================
 *
 * A sample Game state, displaying the Phaser logo.
 */

import LeMap from '../objects/LeMap';

// TODO: change masses
//       play around with spring settings


var static1;
var static2;
var button1;
var button2;
var cursors;
var kinematic1;
var kinematic2;
var text;
var line;
var spring = null;
var result = 'none';

var level = 0;

var settings = {
    button_movespeed: 4,
    win_width: 780,
    win_height: 600,
    air_resistance: 10
};

var leveldata = {
    level0: {
        time: 12
    },
    level1: {
        time: 23
    },
    level2: {
        time: 40
    },
    level3: {
        time: 60
    },
    level4: {
        time: 60
    },
    level5: {
        time: 60
    },
    level6: {
        time: 60
    },
    level7: {
        time: 60
    },
    level8: {
        time: 60
    },
    level9: {
        time: 60
    },
    level10: {
        time: 20
    }
}

export default class Game extends Phaser.State {

    preload () {
        this.levelmap = new LeMap(this, 'level' + level);
        this.levelmap.preload();
    }

    create () {

        //restartkey = this.game.input.keyboard.addKey( Phaser.Keyboard.R );
        //restartkey.onDown.add( this.restartpressed(), this);
        //this.game.input.keyboard.removeKeyCapture(Phaser.Keyboard.R);

        this.restartkey = 'up';

        console.log("LEVEL: ", level);

        this.stopped = false;

        this.buttoncount = 2;

        // this.world = {x: ..., y: ...}
        // => const centerX = this.world.x;
        // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
        const { centerX: x, centerY: y } = this.world;

        this.world.setBounds(0, 0, settings.win_width, settings.win_height);

        // this.add.image(0, 0, 'sky');

        //	Enable p2 physics
        this.physics.startSystem(Phaser.Physics.P2JS);

        //  Make things a bit more bouncey
        this.physics.p2.restitution = 0.8;

        this.physics.p2.setImpactEvents(true);

    // INIT LEVEL
    // -----------

        this.levelmap.init();


    // BUTTON 1
    // ------------
        this.button1 = this.add.sprite(100, 300, 'buttons');
        this.button1.animations.add('button1',[0 ,1 ,2 ,3 ,4 ,5, 6, 7 ], 7, true);
        this.button1.animations.play('button1');
        this.physics.p2.enable(this.button1);
        this.button1.body.setCircle(30);
        this.button1.body.my_props = { name: '1'};


    // BUTTON 2
    // ------------
        this.button2 = this.add.sprite(680, 300, 'buttons');
        this.button2.animations.add('button2',[14 ,15 ,16 ,17 ,18 ,19, 20, 21 ], 8, true);
        this.button2.animations.play('button2');
        this.physics.p2.enable(this.button2);
        this.button2.body.setCircle(30);
        this.button2.body.my_props = { name: '2'};


    // BOUNCE SOUNDS
        this.button1.body.onBeginContact.add( this.blockHit, this);
        this.button2.body.onBeginContact.add( this.blockHit, this);

        //button2.body.onBeginContact.add(this.blockHit, this);

        //sprite.body.velocity.x = 0;
        //sprite.body.velocity.y = 0;
        //sprite.body.thrust(0);

        //  Create two kinematic objects
        //kinematic1 = this.add.sprite(200, 200, 'phaser');
        //kinematic2 = this.add.sprite(500, 500, 'phaser');

        //  Enable if for physics. This creates a default rectangular body.
        //this.physics.p2.enable( [ kinematic1, kinematic2 ]);

        //  Make kinematic - Kinematic means that the body will not be effected by
        //  physics such as gravity and collisions, but can still move and
        //  will fire collision events
        //kinematic1.body.kinematic = true;
        //kinematic2.body.kinematic = true;
        //
        ////  Give the kinematic objects some velocity
        //kinematic1.body.velocity.x = 10;
        //kinematic2.body.velocity.x = -10;


    // INFO DISPLAY
    // --------------

        this.leveltext = this.add.text(20, 20, 'Level '+level, { fill: '#ffffff'});

        this.text = this.add.text(20, 560, 'move with arrow keys, click to TIE them, R to restart Level', { fill: '#ffffff', font: "17px Arial" });


        this.counter = leveldata['level' + level].time;
        this.timetext = this.add.text(650, 20, '', { fill: '#ffffff' });
        this._updateTimer();


        this.countertimer = this.game.time.create(false);

        //  Set a TimerEvent to occur after 2 seconds
        this.countertimer.loop(1000, this._updateTimer, this);

        //  Start the timer running - this is important!
        //  It won't start automatically, allowing you to hook it to button events and the like.
        this.countertimer.start();


        cursors = this.input.keyboard.createCursorKeys();

        //  Change the directions of the kinematic objects after 20 seconds
        this.time.events.loop(Phaser.Timer.SECOND * 20, this.switchDirections, this);

    // SPRING
    // --------
        line = new Phaser.Line(this.button1.x, this.button1.y, this.button2.x, this.button2.y);
        //                                                           restlength, stiffness, damping
        // spring = this.game.physics.p2.createSpring(button1, button2, 30, 3, 1); // 70, 0, 1
        // spring = this.game.physics.p2.createSpring(button1, button2, 0, 30, 1);

        this.game.input.onDown.add(this.mouseclick, this);

        this.levelmap.initTriggers();

    // SOUNDS
    // --------
        this.sounds = {
            bump: this.game.add.audio('bump', 0.5, false),
            exit: this.game.add.audio('exit', 0.5, false),
            tied: this.game.add.audio('tied', 0.1, true)
            //smilee: this.game.add.audio('snd_smilee', 1, false),
            //dud: this.game.add.audio('snd_dud', 1, false)
        }

  }

  blockHit () {
      this.sounds.bump.play();
  }

  _updateTimer() {
      var t = new Date(1970,0,1);
      t.setSeconds(this.counter);
      this.counter--;
      //console.log(t.toTimeString());
      var s = t.toTimeString().substr(3,5);
      this.timetext.setText(s);

      if (this.counter < 0) {
          this.failed('time');
      }
  }


  mouseclick(pointer) {

      console.log(pointer);

      if (this.stopped) {

          if (result === 'alldone') {
              return;
          }

          if (result === 'success') {
              this.nextLevel();
          } else {
              this.restartLevel();
          }
          return;
      }

      if (this.buttoncount <= 1) {
          return;
      }

      if (spring === null) {
          spring = this.game.physics.p2.createSpring(this.button1, this.button2, 30, 3, 1);
          line.setTo(this.button1.x, this.button1.y, this.button2.x, this.button2.y);
          this.sounds.tied.play();
      } else {
          this.removeSpring();
      }
  }

  removeSpring() {
      if (spring !== null) {
          this.game.physics.p2.removeSpring(spring);
          spring = null;
          this.game.debug.dirty = true;
          this.sounds.tied.stop();
      }
  }

    //test connection only active when mouse pressed
    //add level

  exiting (button) {

      this.removeSpring();

      //                            to(properties, duration, ease,               autoStart, delay, repeat, yoyo)
      // stop moving and fade out
      button.body.destroy();
      this.game.add.tween(button).to( { alpha: 0 }, 333, Phaser.Easing.Linear.None, true, 0, 0, false);

      this.sounds.exit.play();

      this.buttoncount--;

      if (this.buttoncount == 0) {
          this.finished();
      }

  }

  stopAll() {

      this.stopped = true;

      if (this.button1.body !== null) {
          this.button1.body.destroy();
      }
      if (this.button2.body !== null) {
          this.button2.body.destroy();
      }
      this.countertimer.stop();

      this.removeSpring();

      this.button1.animations.stop(true);
      this.button2.animations.stop(true);

  }

  failed(why) {
      this.stopAll();

      this.infobox = this.add.sprite(90,60,'infobox');

      result = 'failed';

      console.log("Failed because of " + why);



      var style_press = { font: "italic 23px Arial", fill: "#000000", align: "center" };

      var text = this.add.text(120, 200,
          "Unfortunately the time ran out before you\rgot both button out of there.\r" +
          "\rCare to try again?", {fill: "#666666"});

      this.text = this.add.text(260, 400, "Click to restart this level", style_press);

  }

  finished() {
      this.stopAll();
      console.log("Finished");

      var signtext = "";

      var style_press = { font: "italic 23px Arial", fill: "#000000", align: "center" };
      this.infobox = this.add.sprite(90,60,'infobox');

      console.log(level);

      if (level === 10) {
          result = 'alldone';
          signtext = "THATS IT.\r" +
                     "(unfortunately, but it is\r" +
                     "1 in the morning, i have to get up in 6h,\r" +
                     "no time for more love(ls) mr. bond\r" +
                     "\r" +
                     "I hope you enjoyed it,\r" +
                     "So long and thanks for the fi(ni)sh.";
      } else {
          result = 'success';
          signtext = "Well done, you beat the time, and lets be\rhonest, isn't that what we all want ;)\r" +
              "\rCheck out the next level?";
          this.text = this.add.text(260, 400, "Click to go to the next level", style_press);
      }

      var text = this.add.text(120, 200, signtext, {fill: "#666666"});

  }

  update () {

      if (this.stopped) {
          //this.button1.body.velocity.x = 0;
          //this.button1.body.velocity.y = 0;
          //this.button2.body.velocity.x = 0;
          //this.button2.body.velocity.y = 0;
          return;
      }

      if (cursors.left.isDown)
      {
          // sprite.body.rotateLeft(80);
          if (this.button1.body!==null)
            this.button1.body.velocity.x -= settings.button_movespeed;
      }
      else if (cursors.right.isDown)
      {
          // sprite.body.rotateRight(80);
          if (this.button1.body!==null)
            this.button1.body.velocity.x += settings.button_movespeed;
      }

      if (cursors.up.isDown)
      {
          // sprite.body.thrust(400);
          if (this.button2.body!==null)
            this.button2.body.velocity.y -= settings.button_movespeed;
      }
      else if (cursors.down.isDown)
      {
          // sprite.body.reverse(400);
          if (this.button2.body!==null)
            this.button2.body.velocity.y += settings.button_movespeed;
      }

      if (this.game.input.keyboard.isDown(Phaser.Keyboard.R)) {
          this.restartkey = 'down';
      } else {
          if (this.restartkey === 'down') {
               //this.restartLevel();
              this.nextLevel();
          }
      }
      // console.log(sprite.body.velocity);
      // why zero
      //if (sprite.body.velocity.y > 0) {
      //    sprite.body.velocity.y -= settings.air_resistance;
      //}
  }

    switchDirections() {

        //  This simply flips the directions of the kinematic objects. The P2 mpxi function
        //  is used to convert from the p2 physics value back into pxiels.
        //kinematic1.body.velocity.x = game.physics.p2.mpxi(kinematic1.body.velocity.x) * -1;
        //kinematic2.body.velocity.x = game.physics.p2.mpxi(kinematic2.body.velocity.x) * -1;

    }

    preRender() {

        if (spring !== null) {
            line.setTo(this.button1.x, this.button1.y, this.button2.x, this.button2.y);
        }

    }

    restartLevel() {
        console.log('AGAAAAAAAIIIIIIN');
        this.removeSpring();
        this.game.state.start( this.game.state.current );
    }

    nextLevel() {
        level++;
        console.log("NEEEEEEEXT");
        this.game.state.start( this.game.state.current );
    }

    render () {
        this.levelmap.actionobjects

        this.game.debug.geom(this.levelmap.actionobjects);

        //console.log(this.levelmap.actionobjects);
        this.game.debug.dirty = true;

        if (spring !== null) {
            this.game.debug.geom(line);
        } else {
            this.game.debug.dirty = true;
        }
    }
}
