"use strict";

var generate = require('./base');
var room = require('../room');
var verbose = require('debug')('verbose:queue');

var TEAMSIZE = 6;

var user = {};
var teams = { waitPlayer: [], waitConfirm: [] };
var queue = [];

function Team() {
  verbose('Team() constructor called');
  this.room = new room.Room();
  this.members = [];
}

Team.prototype.push = function (username) {
  verbose('Team.push(%s)', username);
  var socket = user[username].socket;
  this.room.push(socket);
  this.members.push(username);
};

Team.prototype.move = function (src, dest) {
  verbose('Team.move(%s, %s)', src, dest);
  var index = src.indexOf(this);
  if (index > -1) {
    src.splice(index, 1);
    if (dest) {
      dest.push(this);
    }
  }
};

function updateClient(team, state) {
  verbose('emit queue/update, state: %s, current: %s', state, team.members.length);
  team.room.emit('queue/update', {
    state: state,
    current: team.members.length
  });
}

function assignTeam() {
  verbose('assignTeam');
  if (queue.length && teams.waitPlayer.length === 0) {
    verbose('no team waiting player. make a new one.');
    teams.waitPlayer.push(new Team());
    verbose('teams.waitPlayer.length = %s', teams.waitPlayer.length);
  }

  for (var i = 0; i < teams.waitPlayer.length && queue.length; i++) {
    var team = teams.waitPlayer[i];
    var changed = false;
    while (team.members.length < TEAMSIZE && queue.length) {
      team.push(queue.shift());
      changed = true;
    }

    // if any changes, emit queue/update(wait-player) to every team member
    if (changed) {
      verbose('player(s) assigned. broadcast wait-player');
      updateClient(team, 'wait-player');
    }

    if (team.members.length === TEAMSIZE) {
      verbose('team is full(%s). move this team to wait-confirm list', TEAMSIZE);
      // add this team to wait-confirm list
      team.move(teams.waitPlayer, teams.waitConfirm);

      // emit wait-confirm to every team member.
      updateClient(team, 'wait-confirm');
    }
  }
}

function join() {
  verbose('queue/join, username: %s', this.socket.username);
  queue.push(this.socket.username);
  user[this.socket.username] = { socket: this.socket };
  assignTeam();
}

function exit() {
}

function confirm() {
}

function dodge() {
}

module.exports = generate({
  'queue/join': { name: 'join', function: join },
  'queue/exit': { name: 'exit', function: exit },
  'queue/confirm': { name: 'confirm', function: confirm },
  'queue/dodge': { name: 'dodge', function: dodge }
});

@@ -8,16 +8,55 @@
 rict%22;%0A%0A
+var error = require('debug')('error');%0A
 var gene
@@ -77,24 +77,24 @@
 ('./base');%0A
-
 var room = r
@@ -552,16 +552,46 @@
 rname);%0A
+  user%5Busername%5D.team = this;%0A
 %7D;%0A%0ATeam
@@ -806,16 +806,296 @@
   %7D%0A%7D;%0A%0A
+Team.prototype.removeUser = function (username) %7B%0A  verbose('Team.removeUser(%25s)', username);%0A  var index = this.members.indexOf(username);%0A  if (index %3E -1) %7B%0A    this.members.splice(index, 1);%0A    this.room.remove(user%5Busername%5D.socket);%0A    user%5Busername%5D.team = null;%0A  %7D%0A%7D;%0A%0A
 function
@@ -2546,24 +2546,24 @@
 nTeam();%0A%7D%0A%0A
-
 function exi
@@ -2564,24 +2564,532 @@
 on exit() %7B%0A
+  var username = this.socket.username;%0A  verbose('queue/exit, username: %25s', username);%0A  var team = user%5Busername%5D.team;%0A%0A  var isWaitingPlayer = teams.waitPlayer.indexOf(team) %3E -1;%0A  var isWaitingConfirm = teams.waitConfirm.indexOf(team) %3E -1;%0A  if (isWaitingPlayer %7C%7C isWaitingConfirm) %7B%0A    team.removeUser(username);%0A    if (isWaitingConfirm) %7B%0A      updateClient(team, 'wait-player');%0A      team.move(teams.waitConfirm, teams.waitPlayer);%0A    %7D%0A  %7D else %7B%0A    error('queue/exit, abnormal state');%0A  %7D%0A
 %7D%0A%0Afunction 

Implement queue/exit.