angular.module("FICApp", ["ngSanitize", "ngAnimate"])
    .controller("EventsController", function($scope, $rootScope, $http, $interval) {
	$scope.events = [];
	var refreshEvents = function() {
	    // Update times
	    var time = angular.fromJson(sessionStorage.time);
	    var now = Date.now();
	    if (time)
		now += time.cu - time.he;
	    now = new Date(now);
	    $scope.events.forEach(function(ev) {
		ev.since = now - ev.time;
	    });

	    $http.get("./events.json").then(function(response) {
		// Don't make anything if the page hasn't changed
		if ($scope.lasteventsetag != undefined && $scope.lasteventsetag == response.headers()["last-modified"])
		    return;
		$scope.lasteventsetag = response.headers()["last-modified"];

		var lastExercice = undefined;

		$scope.events = response.data;
		$scope.events.forEach(function(event) {
		    if (!lastExercice && $scope.themes) {
			var res = event.txt.match(/<strong>(\d+)<sup>e<\/sup><\/strong> défi ([^&]+)/);
			if (res) {
			    for (var tid in $scope.themes) {
			      if ($scope.themes[tid].name == res[2]) {
			        for (var eid in $scope.themes[tid].exercices) {
				    lastExercice = $scope.themes[tid].exercices[parseInt(res[1])-1].id;
				    break;
				}
			      }
                            }
			}
		    }
		    event.time = Date.parse(event.time);
		    event.since = now - event.time;
		    event.kind = ["border-" + event.kind, "alert-" + event.kind];
		});

		$rootScope.lastExercice = lastExercice;
	    });
	}
	$interval(refreshEvents, 2100);
    })
    .controller("TimerController", function($scope, $rootScope, $interval, $timeout) {
	$scope.duration = 0;

	$scope.init = function(end) {
	    $scope.initT(Date.parse(end));
	}
	$scope.initStart = function() {
	    $scope.$watch("settings", function(settings){
		if (settings)
		    $scope.initT(settings.start);
	    })
	}
	$scope.initT = function(end) {
	    var time = angular.fromJson(sessionStorage.time);
	    if (time) {
		var srv_cur = new Date(Date.now() + (time.cu - time.he));
		$scope.duration = Math.floor((end - srv_cur)/1000);
	    } else
		$timeout(function() { $scope.initT(end); }, 1000);
	}

	var stop = $interval(function() {
	    $scope.duration -= 1;
	    if ($scope.duration < -10)
		$interval.cancel(stop);
	}, 1000);
    })
    .controller("DataController", function($scope, $http, $rootScope, $interval) {
	var pathname = window.location.pathname;
	if (pathname == "/")
	    pathname = "/public0.html";
	pathname = pathname.replace(".html", ".json");

	var refreshScene = function() {
	    $http.get(pathname).then(function(response) {
		if ($scope.lastpublicetag != undefined && $scope.lastpublicetag == response.headers()["last-modified"])
		    return;
		$scope.lastpublicetag = response.headers()["last-modified"];

		$scope.display = response.data;
	    });
	}
	refreshScene();
	var refreshSceneInterval = $interval(refreshScene, 900);

	var refreshSettings = function() {
	    $http.get("./settings.json").then(function(response) {
		$rootScope.recvTime(response);
		response.data.start = new Date(response.data.start);
		response.data.end = new Date(response.data.end);
		response.data.generation = new Date(response.data.generation);
	        response.data.awards = new Date(response.data.awards?response.data.awards:"2023-04-06T16:00:00Z");
		$rootScope.settings = response.data;
	    });
	}
	refreshSettings();
	var refreshSettingsInterval = $interval(refreshSettings, 4200);

	var refreshChallengeInfo = function() {
	    $http.get("./challenge.json").then(function(response) {
		$rootScope.challenge = response.data;
	    });
	}
	refreshChallengeInfo();
	var refreshChallengeInfoInterval = $interval(refreshChallengeInfo, 900000);


	$rootScope.refresh = function() {
	    $http.get("./my.json").then(function(response) {
		if ($scope.lastmyetag != undefined && $scope.lastmyetag == response.headers()["last-modified"])
		    return;
		$scope.lastmyetag = response.headers()["last-modified"];

		$scope.my = response.data;
	    });
	    $http.get("./settings.json").then(function(response) {
		$rootScope.recvTime(response);
		response.data.start = new Date(response.data.start);
		response.data.end = new Date(response.data.end);
		response.data.generation = new Date(response.data.generation);
	        response.data.awards = new Date(response.data.awards?response.data.awards:"2023-04-06T16:00:00Z");
		$rootScope.settings = response.data;
	    });
	    $http.get("./themes.json").then(function(response) {
		if ($scope.lastthemeetag != undefined && $scope.lastthemeetag == response.headers()["last-modified"])
		    return;
		$scope.lastthemeetag = response.headers()["last-modified"];

	        var themes = response.data;
                var exercices = {};
		$scope.themes = themes;
		$scope.max_gain = 0;
		angular.forEach(themes, function(theme, key) {
		    if (theme.exercices)
			this[key].exercice_count = Object.keys(theme.exercices).length;
		    else
			this[key].exercice_count = 0;
		    this[key].gain = 0;
		    angular.forEach(theme.exercices, function(ex, k) {
                        exercices[ex.id] = ex;
			this.gain += ex.gain;
		    }, theme);
		    $scope.max_gain += theme.gain;
		}, themes);
                $scope.exercices = exercices;
	    });
	    $http.get("./teams.json").then(function(response) {
		if ($scope.lastteametag != undefined && $scope.lastteametag == response.headers()["last-modified"])
		    return;
		$scope.lastteametag = response.headers()["last-modified"];

		var teams = response.data;

		$scope.teams_count = Object.keys(teams).length
		$scope.teams = teams;

		$scope.rank = [];
		angular.forEach($scope.teams, function(team, tid) {
		    team.id = tid;
		    if (team.rank) {
			this.push(team);
		    }
		}, $scope.rank);
	        $scope.rank.sort(function(a,b) { return a.rank > b.rank ? 1 : -1 })
		$scope.pagesrank = Array(Math.ceil($scope.rank.length / 7)).fill(0).map(function(v, i){ return i; });
	    });
	}
	$rootScope.refresh();
	$interval($rootScope.refresh, 4200);
    })
    .controller("TeamController", function($scope, $http, $interval) {
	$scope.mystats = null;
	$http.get("./api/teams/" + $scope.team.id + "/stats.json").then(function(response) {
	    $scope.mystats = response.data;
	});
    })
  .controller("RankGraphController", function($scope, $q) {
	var margin = {left: 50, right: 20, top: 20, bottom: 50 };

        var width = $("#rank_graph").width() - margin.left - margin.right;
	var height = $scope.s.params.height - margin.top - margin.bottom;

	var xNudge = 50;
	var yNudge = 20;

      var max = 0;
    var minDate = new Date();
    var maxDate = new Date("2017-12-01");
    if ($scope.settings && $scope.settings.end)
      maxDate = $scope.settings.end;


      var teams = {}

    var loopPromises = [];
    $scope.s.params.teams.forEach(function (teamid) {
      var deferred = $q.defer();
      loopPromises.push(deferred.promise);
      d3.json("./api/teams/" + teamid + "/score-grid.json", function (rows) {
	if (rows == null) return;
	rows.sort(function (a,b) { return a.time > b.time ? 1 : -1 })
	var nrows = {};
	var sum = 0;
	rows.forEach(function (row) {
	  if (!nrows[row.time])
	    nrows[row.time] = 0;
	  var pts = row.points * row.coeff;
	  sum += pts;
	  nrows[row.time] = sum;
	  if (sum > max)
	    max = sum
	})
	teams[teamid] = []
	Object.keys(nrows).forEach(function (t) {
	  var d = new Date(t)
	  if (d < minDate)
	    minDate = d;
	  if (d > maxDate)
	    maxDate = d;
	  teams[teamid].push({time: d, points: nrows[t]})
	})
	deferred.resolve();
      });
    })

    $q.all(loopPromises).then(function(){
      var y = d3.scale.linear()
	  .domain([0,max])
	  .range([height,0]);

      var x = d3.time.scale()
	  .domain([minDate,maxDate])
	  .range([0,width]);

      var yAxis = d3.svg.axis()
	  .orient("left")
	  .scale(y);

      var xAxis = d3.svg.axis()
	  .orient("bottom")
	  .tickFormat(d3.time.format("%H:%M"))
	  .scale(x);

      var line = d3.svg.line()
	  .x(function(d){ return x(d.time); })
	  .y(function(d){ return y(d.points); })
	  .interpolate("cardinal");

      var svg = d3.select("#rank_graph").append("svg").attr("id","svg").attr("height",$scope.s.params.height).attr("width","100%");
      var chartGroup = svg.append("g").attr("class","chartGroup").attr("transform","translate("+xNudge+","+yNudge+")");

      chartGroup.append("g")
	.attr("class","axis x")
	.attr("transform","translate(0,"+height+")")
	.call(xAxis);

      chartGroup.append("g")
	.attr("class","axis y")
	.call(yAxis);

      angular.forEach(teams, function(rows, tid) {
	rows.unshift({time: minDate, points: 0})
	var team = $scope.teams[tid]
	chartGroup.append("path")
	  .attr("style","fill: none; stroke: " + team.color + "; stroke-width: 2px;")
	  .attr("d",function(d){ return line(rows); })
      })

      if ($scope.s.params.legend) {
	var legend = svg.append("g")
            .attr("style", "fill: white;")
            .attr("height", 100)
            .attr("width", 100)
            .attr('transform', 'translate(70,20)')

	legend.selectAll('rect')
          .data(Object.keys(teams))
          .enter()
          .append("rect")
          .attr("x", 0)
          .attr("y", function(d, i){ return i * 23;})
          .attr("width", 15)
          .attr("height", 15)
          .style("fill", function(d) {
	    return $scope.teams[d].color;
	  })

	legend.selectAll('text')
          .data(Object.keys(teams))
          .enter()
          .append("text")
          .attr("font-size", "23px")
          .attr("x", 20)
          .attr("y", function(d, i){ return i *  23 + 14;})
          .text(function(d) {
	    return $scope.teams[d].name + " (" + $scope.teams[d].rank + "e : " + Math.ceil($scope.teams[d].score) + " pts)";
	  });
      }
    });
  })
