
// this is so we can pass our object to the timer callback
function bind(toObject, methodName){
    return function(){toObject[methodName]()}
}

// aggression is the probability that the computer will lock your thumb.
// aggression can be 0-4.
var levels = {
  "easy": { 
    "responseTime": 400,
    "delay": 2000,
    "aggression": 0,
    "nextLevel": "medium"
  },
  "medium": {
    "responseTime": 350,
    "delay": 1000,
    "aggression": 1,
    "nextLevel": "hard"
  },
  "hard": {
    "responseTime": 300,
    "delay": 800,
    "aggression": 2,
    "nextLevel": "unpossible"
  },
  "unpossible": {
    "responseTime": 300,
    "delay": 300,
    "aggression": 3,
    "nextLevel": null
  }
};

var quickestIphoneResponse=300;
var quickestComputerResponse=150;
var levelHardUpperComputerResponse=1000; // not counting quickest response time
var quickestComputerResponse=400;

var animateTime=700;

var Gameplay = function() {

  this.lockDelay = $.timer(2000, bind(this, 'lockDelayCallback'));
  this.lockDelay.stop();
  
  this.player = new Player();
  this.computer = new Computer();
  
  
  this.setStatus = function(text, callback) {
    return $('#status').appendTo(this.player.thumb.position).text(text).show().
      animate({top: "40px",opacity: 0.8}, animateTime,null,callback);
  }
  
  this.clearStatus = function(text, callback) {
    return $('#status').text(text).animate({top: "0px",opacity: 0.0},
          animateTime,null,callback);
  }
  
  this.start = function() {
    this.player.start();
    this.computer.start();
  }
  
  this.playerLockedComputer = function() {
    this.lockDelay.stop();
    this.computer.stop();
    this.player.stop();
    var obj=this;
    this.setStatus("Thumb Lock!", function() {
      obj.player.push( function(playerResponseTime) { obj['playerPushResponse'](playerResponseTime); } );
    });
  }
  
  this.playerPushResponse = function( playerResponseTime ) {
      var computerResistTime=this.computer.getComputerResponseTime();
      var damage=Math.max(0, computerResistTime-playerResponseTime);
      if(damage>0){this.computer.reduceEnergy(damage)};
      if(this.computer.energyMeter.energy>0) {
        if(damage==0) {
          this.computer.computerMove();
          var obj=this;
          this.clearStatus("Thumbs Free", function() {
            obj.start();
          });
          
        } else {
          var obj=this;
          this.player.push( function(playerResponseTime) { obj['playerPushResponse'](playerResponseTime); } );
        }
      }
  }

  this.player.lock( bind(this, 'playerLockedComputer'));
  
  this.computerLockedPlayer = function() {
    this.computer.stop();
    
    this.lockDelay.reset(200);
  }

  this.lockDelayCallback = function() {
    this.lockDelay.stop();
      
    if(this.player.thumb.position.attr('id')==this.computer.thumb.position.attr('id')) {
      
      this.player.stop();
      var obj=this;
      this.setStatus("Thumb Lock!", function() {
        obj.player.resist( function(playerResponseTime) { obj['playerResistResponse'](playerResponseTime); } );
      });
    } else {
      this.computer.start();
    }
  }

  this.playerResistResponse = function( playerResponseTime ) {
      var computerResistTime=this.computer.getComputerResponseTime();
      var damage=Math.max(0, playerResponseTime-computerResistTime);
      if(damage>0){this.player.reduceEnergy(damage)};
      if(this.player.energyMeter.energy>0) {
        if(damage==0) {
          this.player.thumb.move($("#resist").parent());
          var obj=this;
          this.clearStatus("Thumbs Free", function() {
            obj.start();
          });
        } else {
          var obj=this;
          this.player.resist( function(playerResponseTime) { obj['playerResistResponse'](playerResponseTime); } );
        }
      }
  }
  this.computer.lock( bind(this, 'computerLockedPlayer') );

  this.playerPinned = function() {
    this.computer.stop();
    this.player.stop();
    $("#winner").html("<strong>You Lost.<strong>");
    $("#gameOver").show();
    $("#dialog").slideDown();
  }
  this.player.pinned( bind(this, 'playerPinned'));
  
  this.computerPinned = function() {
    this.clearStatus('');
    this.computer.stop();
    this.player.stop();
    $("#lastStageName").text("Level: "+this.level.levelName+", Stage: "+this.level.stage);
    $("#stage_end").show();
    var obj=this;
    $("#dialog").slideDown(animateTime, function() {
      $(this).slideUp(animateTime, function() {
        $("#stage_end").hide();
        obj.calculateNextStage();
        obj.beginStage();
      });
    });
  }
  this.computer.pinned( bind(this, 'computerPinned'));
  
  this.calculateNextStage = function() {
    if(this.level.stage<10) {
      var responseTimeIncrement=
        (levels[this.level.levelName].responseTime-levels[this.level.nextLevel].responseTime)/10;
      var delayIncrement=
        (levels[this.level.levelName].delay-levels[this.level.nextLevel].delay)/10;
      this.level.responseTime-=responseTimeIncrement;
      this.level.delay-=delayIncrement;
      this.level.stage++;
    } else {
      // advance to next level
      var nextLevel=this.level.nextLevel;
      if(nextLevel==null) {
        this.gameWon();
      } else {
        this.level = {
          "levelName": nextLevel,
          "stage": 1,
          "responseTime": levels[nextLevel].responseTime,
          "delay": levels[nextLevel].delay,
          "aggression": levels[nextLevel].aggression,
          "nextLevel": levels[nextLevel].nextLevel
        };
      }
    }
  }
  
  this.gameWon = function() {
    alert("You beat the game!");
    $("#show_instructions").click();
  }
  
  this.addBeat = function(el, text) {
    var obj=this;
    this.beats.push(
      function() {
        $("#status").fadeOut(300, function() {
          $("#push").appendTo($(el)).show().click(function() {
            $("#push").unbind('click').hide();
            var pos=$(this).parent();
            var comp_pos;
            switch(pos.attr('id')) {
              case "tr":
                comp_pos="#bl";
                break;
              case "tl":
                comp_pos="#br";
                break;
              case "tm":
                comp_pos="#bm";
                break;
              case "bm":
                comp_pos="#tm";
                break;
            };
            obj.player.thumb.move($(pos));
            obj.computer.thumb.move($(comp_pos));
            $("#status").appendTo($(pos)).text(text).css("opacity",1.0).show();
            var nextFunc=obj.beats.shift();
            if(nextFunc!=null) {
              nextFunc();
            } else {
              $("#status").fadeOut(animateTime, function() {
                obj.player.lock( bind(obj, 'playerLockedComputer'));
                obj.computer.lock( bind(obj, 'computerLockedPlayer'));
                obj.player.start();
                obj.computer.start();
              });
            }
          });
        });
      }
    );
  }
  
  this.gameStart = function() {
    var func=this.beats.shift();
    if(func!=null) {
      func();
    }
  }
  
  this.intialize = function(level) {
    this.thumbs=2;
    this.level={
      "levelName": level,
      "stage": 1,
      "responseTime": levels[level].responseTime,
      "delay": levels[level].delay,
      "aggression": levels[level].aggression,
      "nextLevel": levels[level].nextLevel
    };
    this.beginStage();
  }
  
  this.beginStage = function() {
    this.player.lock( function() {} );
    this.computer.lock( function() {} );
    this.player.initialize();
    this.computer.initialize(this.level);

    $("#stageName").text("Level: "+this.level.levelName+", Stage: "+this.level.stage);
    $("#stage").show();
    $("#dialog").slideDown(animateTime);
  }
  
  this.thumbDance = function () {
    var obj=this;
    $("#dialog").slideUp(animateTime, function() {
      $("#stage").hide();
      obj.beats=new Array();
    
      $("#push, #resist").css('top','31px').css('left','26px');
      $("#status").css('top','40px');
      // Time for "one, two, three, four, I declare a Thumb War!"
      var script=[
        ["#tr", '"One!"'],
        ["#tl", '"Two!"'],
        ["#tr", '"Three!"'],
        ["#tl", '"Four!"'],
        ["#tr", '"I -"'],
        ["#tl", '"declare -"'],
        ["#tr", '"a thumb -"'],
        ["#tl", '"War!"'],
        ["#bm", 'Shake'],      
        ["#tm", 'Shake'],      
        ["#bm", 'Game On!']    
      ];

      jQuery.each(script, function() {
        obj.addBeat(this[0],this[1]);
      } );
  
      obj.gameStart();
    });    
  }
  var obj=this;
  $("#play").click(function(){ obj.thumbDance();});


}