{% extends "layout.jinja" %}

{% block content %}
  <h1>
    {% if follow_username %}Following {{ follow_username }}:<br/>{% endif %}
    Game #<a id="game_id"></a>: 
    <a id='name1'></a>
    <sub>vs</sub>
    <a id='name2'></a>
    <span id="elodiff"></span>
  </h1>
  <p class='lead'>
    <span class="name1"></span> currently has rank #<span id="rank1"></span>,
    <span class="name2"></span> currently has rank #<span id="rank2"></span>.
    <a id="gameloglink"'>raw gamelog</a>
    <span class="control">
      <span id="back" title="step back">⇤</span>
      <span id="playpause" title="play/pause">▶</span>
      <span id="forward" title="step forward">⇥</span>
    </span>
  </p>
  <div class="row">
    <div class="span12">
      <div id='timegraph'></div>
      <canvas width="0" height="0" id='planets'></div>
      <table class='table rounds fixed-header'>
        <thead class='header'>
          <tr>
            <th>Round</th>
            <th>Total Fleets</th>
            <th class='player1'>Planets<br><span class="name1"></span></th>
            <th class='player2'>Planets<br><span class="name2"></span></th>
            <th class='player1'>Ships<br><span class="name1"></span></th>
            <th class='player2'>Ships<br><span class="name2"></span></th>
            <th class='player1'>Production<br><span class="name1"></span></th>
            <th class='player2'>Production<br><span class="name2"></span></th>
            <th class='player1'>Fleets<br><span class="name1"></span></th>
            <th class='player2'>Fleets<br><span class="name2"></span></th>
          </tr>
        </thead>
        <tbody>
	  <tr>
	    <td id="round"></td>
	    <td id="fleet_total"></td>

	    <td id="planets_player1"></td>
	    <td id="planets_player2"></td>

	    <td id="ships_player1"></td>
	    <td id="ships_player2"></td>

	    <td id="production_player1"></td>
	    <td id="production_player2"></td>

	    <td id="fleets_player1"></td>
	    <td id="fleets_player2"></td>
	  </tr>
        <tbody>
      </table>
    </div>
  </div>
{% endblock %}

{% block bottom_scripts %}
  {{ super() }}
  <script src="/static/js/flot/jquery.js"></script>
  <script src="/static/js/flot/jquery.flot.js"></script>
  <script src="/static/js/flot/jquery.flot.crosshair.js"></script>
  <script src="/static/js/table-fixed-header.js"></script>
  <script>
    $('table.fixed-header').fixedHeader();

    var playspeed = 100;
    var polling_freq = 10;
    var info_polling_freq = 1;
    var rounds = []

    var game_id;
    var player1;
    var player2;
    var elodiff;

    var current_round;

    var redrawTimeout = null;
    var redraw = function () {
      console.log("redraw called before defined")
    };

    function playing() {
      return ($('#playpause').text() != '▶');
    }

    function make_timegraph() {
      var height = 200;
      var width = 940;

      var data = [
        { label: 'neutral'
        , color: 'lightgrey'
        , data: []
        },
        { label: player1
        , color: 'steelblue'
        , data: []
        },
        { label: player2
        , color: 'red'
        , data: []
        }]

      for (var idx = 0; idx < rounds.length; idx++) {
        var round = rounds[idx];
	var fleets = [0,0,0];
	for (var fi = 0; fi < round.fleets.length; fi++) {
	  var fleet = round.fleets[fi];
	  fleets[fleet.owner_id] += fleet.ships[0] + fleet.ships[1] + fleet.ships[2];
	}
	for (var pi = 0; pi < round.planets.length; pi++) {
	  var planet = round.planets[pi];
	  fleets[planet.owner_id] += planet.ships[0] + planet.ships[1] + planet.ships[2];
	}
        for (var player_id = 0; player_id <=2; player_id++) {
          data[player_id].data.push([idx, fleets[player_id]]);
        }
      }

      $("#timegraph").width(width).height(height);
      var plot = $.plot($("#timegraph"), data, {
          grid: {
            hoverable: true,
            autoHighlight: false
          },
	  xaxis: {
	    min: 0,
	    max: 500,
	  }
      });
      $("#timegraph").bind("plothover",  function (event, pos, item) {
	  if (!playing()) {
	    current_round = Math.floor(pos.x);
	    if (current_round < 0) current_round = 0;
	    if (current_round >= rounds.length) current_round = rounds.length -1;

	    if (!redrawTimeout) {
	      redrawTimeout = setTimeout(redraw, 50);
	    }
	  }
      });
      plot.hooks.drawOverlay.push(function (plot, ctx) {
            var plotOffset = plot.getPlotOffset();
            var pointOffset = plot.pointOffset({x: current_round, y:0});
           
            ctx.save();
            ctx.translate(pointOffset.left, plotOffset.top);

	    ctx.strokeStyle = "black";
	    ctx.lineWidth = 2;
	    ctx.lineJoin = "round";

	    ctx.beginPath();
	    ctx.moveTo(0, 0);
	    ctx.lineTo(0, plot.height());
	    ctx.stroke();
            ctx.restore();
        });
    }

    var stars_buffer;
    var planets_buffer;

    function make_planets() {
      var height = 500;
      var width = 940;
      var size_scale = 15;
      var planet_canvas_size = 50;
      var fleet_canvas_size = 5;
      var max_production = 18;
      var star_size = 4;


      // Off-screen canvas for stars
      if (!stars_buffer) {
	stars_buffer = document.createElement('canvas');
	stars_buffer.width = width;
	stars_buffer.height = height;
	var c = stars_buffer.getContext("2d");
	var n_stars = Math.floor(50 + Math.random()*50);
	for (var n = 0; n < n_stars; n++) {
	  var x = Math.random()*width;
	  var y = Math.random()*height;
	  var r = Math.random() * star_size / 2;
	  c.beginPath();
	  c.fillStyle = "white";
	  c.moveTo(x, y);
	  c.arc(x, y, r, 0, 2*Math.PI, false);
	  c.fill();
	}
      }


      // Off-screen canvas for planets
      if (!planets_buffer) {
	planets_buffer = document.createElement('canvas');
	planets_buffer.width = width;
	planets_buffer.height = height;
	var bc = planets_buffer.getContext("2d");
	bc.translate(width/2, height/2);

	var planets = rounds[0].planets;
	for (var idx = 0; idx < planets.length; idx++) {
	  var planet = planets[idx];
	  var total_production = planet.production[0] + planet.production[1] + planet.production[2];
	  var r = Math.sqrt(total_production / (max_production*2)) * planet_canvas_size;
	  var alpha = - Math.PI/2;
	  for (var i = 0; i < 3; i++) {
	    var beta = alpha + 2 * Math.PI * (planet.production[i]/total_production);
	    bc.fillStyle = ["#DDD", "#AAA", "#999"][i];
	    bc.beginPath();
	    bc.moveTo(
		planet.x * -size_scale,
		planet.y * size_scale
		);
	    bc.arc(
		planet.x * -size_scale,
		planet.y * size_scale,
		r,
		alpha,
		beta,
		false
		);
	    bc.closePath();
	    bc.fill();
	    alpha = beta;
	  }
	}
      }

      // The proper canvas
      var canvas = document.getElementById("planets");
      canvas.width = width;
      canvas.height = height;
      var c = canvas.getContext("2d");
      c.translate(width/2, height/2);

      // Varying content
      redraw = function() {
	$('#timegraph').data('plot').triggerRedrawOverlay();

        c.clearRect(-canvas.width/2,-canvas.height/2,canvas.width,canvas.height);
        c.drawImage(stars_buffer, -canvas.width/2, -canvas.height/2);

        var planets = rounds[current_round].planets;
        for (var idx = 0; idx < planets.length; idx++) {
          var planet = planets[idx];
          var total_production = planet.production[0] + planet.production[1] + planet.production[2];
	  var r = Math.sqrt(total_production / (max_production*2)) * (planet_canvas_size * 1.1 + 6);
          if (planet.owner_id != 0) {
            c.beginPath();
            c.fillStyle = ["invalid", "steelblue", "red"][planet.owner_id];
            c.moveTo(
                planet.x * -size_scale,
                planet.y * size_scale
                );
            c.arc(
                planet.x * -size_scale,
                planet.y * size_scale,
                r, 0, 2*Math.PI, false);
            c.fill();
          }
        }

        c.drawImage(planets_buffer, -canvas.width/2, -canvas.height/2);

        var fleets = rounds[current_round].fleets;
        for (var idx = 0; idx < fleets.length; idx++) {
          var fleet = fleets[idx];
          var total_ships = fleet.ships[0] + fleet.ships[1] + fleet.ships[2];
	  if (total_ships == 0) {
	    continue;
	  }

          var dx = planets[fleet.target].x - planets[fleet.origin].x;
          var dy = planets[fleet.target].y - planets[fleet.origin].y;
          var d = Math.ceil(Math.sqrt(dx * dx + dy * dy));
          var tl = (fleet.eta + 1) - current_round;
          var done = 1 - (tl / d);
          var x = planets[fleet.origin].x + done * dx;
          var y = planets[fleet.origin].y + done * dy;
	  var r = Math.sqrt(total_ships / (max_production*2)) * fleet_canvas_size;

	  c.save();
	  c.translate(x * -size_scale, y * size_scale);
	  c.rotate(Math.atan2(dx,dy));

	  // Triangle
	  c.beginPath();
          c.fillStyle = ["invalid", "steelblue", "red"][fleet.owner_id];
	  c.moveTo(-(r+1),0);
	  c.lineTo(0,2*r);
	  c.lineTo( (r+1),0);
	  c.closePath();
          c.fill();

	  c.beginPath();
	  c.moveTo(0,0);
	  c.arc(0,0,r+1,Math.PI,0,false);
	  c.closePath();
	  c.fill();

	  // Pie-Chart at the end
	  var alpha = Math.PI;
	  for (var i = 0; i < 3; i++) {
	    var beta = alpha + Math.PI * (fleet.ships[i]/total_ships);
	    c.fillStyle = ["#DDD", "#AAA", "#999"][i];
	    c.beginPath();
	    c.moveTo(0,0);
	    c.arc(0,0,r,alpha,beta,false);
	    c.closePath();
	    c.fill();
	    alpha = beta;
	  }
	  c.restore();
        }

	// Last round
	if (rounds[current_round].game_over) {
	  var winner = rounds[current_round].winner;
	  if (!winner) { winner = 0};
	  c.fillStyle = ["lightgrey", "sleelblue", "red"][winner];
	  c.font = "bold 60px sans-serif";
	  c.textAlign = "center";
	  c.textBaseline = "ideographic";
	  c.fillText([
	    "draw!",
	    player1 + " wins!",
	    player2 + " wins!"][winner], 0, 0);
	}

        var round = rounds[current_round];
	var ships      = [[0,0,0],[0,0,0],[0,0,0]];
	var planets    = [0,0,0];
	var fleets     = [0,0,0];
	var production = [[0,0,0],[0,0,0],[0,0,0]];
	var add = function (a,b) {
	  a[0] += b[0];
	  a[1] += b[1];
	  a[2] += b[2];
	}

	for (var fi = 0; fi < round.fleets.length; fi++) {
	  var fleet = round.fleets[fi];
	  fleets[fleet.owner_id] += 1;
	  add(ships[fleet.owner_id], fleet.ships);
	}
	for (var pi = 0; pi < round.planets.length; pi++) {
	  var planet = round.planets[pi];
	  planets[planet.owner_id] += 1;
	  add(ships[planet.owner_id], planet.ships);
	  add(production[planet.owner_id], planet.production);
	}
	$('#round')             .text(current_round == rounds.length -1 ?
	                              'Endzustand' : current_round);
	$('#fleet_total')       .text(
	  ships[0][0] + ships[0][1] + ships[0][2] + 
	  ships[1][0] + ships[1][1] + ships[1][2] + 
	  ships[2][0] + ships[2][1] + ships[2][2]); 
	$('#planets_player1')   .text(planets[1]);
	$('#planets_player2')   .text(planets[2]);
	$('#ships_player1')     .text(ships[1]);
	$('#ships_player2')     .text(ships[2]);
	$('#production_player1').text(production[1]);
	$('#production_player2').text(production[2]);
	$('#fleets_player1')    .text(fleets[1]);
	$('#fleets_player2')    .text(fleets[2]);

        redrawTimeout = null;
      }
      redraw();
    }

    var playInterval= null;
    var stop_playing = function() {
	clearInterval(playInterval);
	$('#playpause').text('▶');
    }
    var play = function() {
      if (current_round < rounds.length -1) {
	current_round++;
	redraw();
      } else {
	stop_playing();
      }
    }
    $("body").keydown(function(e) {
      if(e.keyCode == 37) { // left
	$("#back").click();
      }
      else if(e.keyCode == 39) { // right
	$("#forward").click();
      }
    });
    $('#forward').click(function() {
      if (current_round < rounds.length -1) {
	current_round++;
	redraw();
      }
    });
    $('#back').click(function() {
      if (current_round > 0) {
	current_round--;
	redraw();
      }
    });
    $('#playpause').click(function() {
      if (!playing()) {
	if (current_round >= rounds.length -1) {
	  current_round = 0;
	}

	playInterval = setInterval(play, playspeed);
	$(this).text('❚❚');
      } else {
	stop_playing();
      }
    });

    function setup_game() {
      make_timegraph();
      make_planets();
    }

    function poll() {
      $.ajax({  
	  url: "/game/" + game_id + "/rounds/" + rounds.length, success: function(data){
	    if (data.length > 0) {
	      // Race-Condition-Avoiding
	      if (data[0].round == rounds.length) {
		rounds = rounds.concat(data);
		current_round = rounds.length - 1;
		setup_game();
	      }
	    }
	    if (! rounds[rounds.length-1].game_over) {
	      setTimeout(poll,1000 / polling_freq);
	    }
	  }, dataType: "json"});
    }

    function setup_game_info(data) {
      var first_data = ! player1;
      game_id = data.game_id;
      player1 = data.player1;
      player2 = data.player2;
      elodiff = data.elodiff;
      $("#game_id").text(game_id).attr('href',"/game/" + game_id);
      $("#gameloglink").attr('href', "/" + data.game_log_name);
      if (data.finished) {
	if (elodiff > 0) {
	  $('#name1').attr('href', '/player/' + player1)
	             .text(player1)
		     .attr('class','winner player1');
	  $('#name2').attr('href', '/player/' + player2)
	             .text(player2)
		     .attr('class','loser player2');
	  $('#elodiff').show().text("+" + elodiff.toFixed(3));
	} else {
	  $('#name1').attr('href', '/player/' + player2)
	             .text(player2)
		     .attr('class','winner player2');
	  $('#name2').attr('href', '/player/' + player1)
	             .text(player1)
		     .attr('class','loser player1');
	  $('#elodiff').show().text("+" + (-elodiff.toFixed(3)));
	}
      } else {
	  $('#name1').attr('href', '/player/' + player1)
	             .text(player1)
		     .attr('class','player1');
	  $('#name2').attr('href', '/player/' + player2)
	             .text(player2)
		     .attr('class','player2');
	  $('#elodiff').hide();
      }
      $('.name1').text(player1);
      $('#rank1').text(data.rank1);
      $('.name2').text(player2);
      $('#rank2').text(data.rank2);

      if (first_data)
	poll();
    }

    function poll_info() {
      $.ajax({  
	  url: "/game/" + game_id + "/info.json", success: function(data){
	    setup_game_info(data);
	    setTimeout(poll_info,1000 / info_polling_freq);
	  }, dataType: "json"});
    }

    function poll_latest_id() {
      $.ajax({  
	url: "/player/{{ follow_username }}/latest_game.json", success: function(data){
	  if (game_id != data.last) {
	    game_id = data.last;
	    rounds = [];
	    stars_buffer = null;
	    planets_buffer = null;
	    poll();
	  }
	  $.ajax({  
	      url: "/game/" + game_id + "/info.json", success: function(data){
		setup_game_info(data);
	      }, dataType: "json"});
	  setTimeout(poll_latest_id,1000 / info_polling_freq);
	}, dataType: "json"});
    }

    {% if game_id %}
      game_id = {{ game_id }};
      poll_info();
    {% else %}
      poll_latest_id();
    {% endif %}
  </script>
{% endblock %}
