// Core frameworks
var io = require('socket.io')(server);
var _ = require('underscore');
var repo = require('./repository');

// Sockets!
io.on('connection', function(socket){

  // User enters room
  socket.on("joinRoom", function(data){
    socket.join(data.roomkey, function(error){
      socket.username = data.username;
      repo.createUser(data.roomkey, data.username, socket.id);

      repo.getUsers(data.roomkey, function(err, users){
        socket.emit("joinedGame", users);
      });

      socket.broadcast.to(data.roomkey).emit('newPlayer', data.username);

      if(error){console.log("error:" + error);}
    });
  });

  // need to use inside every getHand callback
  function jsonParser(data) {
    var jsonCards = [];
    for ( i=0; i < data.length; i++) {
      jsonCards.push(JSON.parse(data[i]))
    }
    return jsonCards;
  }

  // Deal cards to all users in a room
  socket.on("dealCards", function(data){
    console.log(data);
    // need to transfer the data of faceDown card attribute to cards
    var roomKey = socket.rooms[1];
    repo.createDeck(roomKey);
    repo.dealUsersCards(roomKey, parseInt(data.dealingCount));
    updateAllUserHands(roomKey);
  });

  // Pass a card from one user to another
  socket.on("passCard", function(data){
    var roomKey = socket.rooms[1];
    repo.passCard(roomKey, socket.username, data.toUser, data.cardId);
    updateAllUserHands(roomKey);
  });

  // Draw a card from the deck
  socket.on("drawCard", function(){
    var roomKey = socket.rooms[1];
    var username = socket.username;
    var socketId = socket.id;
    repo.dealUserCard(roomKey, username);
    updateUserHand(roomKey, username, socketId);
  });

  // Pass a card to the table from the user's hand
  socket.on("passTable", function(cardId){
    var roomKey = socket.rooms[1];
    var username = socket.username;
    var socketId = socket.id;
    repo.passCard(roomKey, username, "Table", cardId);
    updateUserHandAndTable(roomKey, username, socketId);
  });

  // User collects all the cards on the table
  socket.on("userCollectsTable", function(){
    var roomKey = socket.rooms[1];
    var username = socket.username;
    var socketId = socket.id;
    repo.getTable(roomKey, username);
    // Possible to get around setTimeout?
    setTimeout(function(){
      updateUserHandAndTable(roomKey, username, socketId);
    }, 105);
  });

  // User discards a card from his/her hand
  socket.on("userDiscardsCard", function(cardId){
    var roomKey = socket.rooms[1];
    var username = socket.username;
    var socketId = socket.id;
    repo.passCard(roomKey, username, "Discard", cardId);
    updateUserHand(roomKey, username, socketId);
  });

  // User obtains a card from a table
  socket.on("getTableCard", function(cardId){
    var roomKey = socket.rooms[1];
    var username = socket.username;
    var socketId = socket.id;
    repo.passCard(roomKey, "Table", username, cardId);
    // Possible to get around setTimeout?
    setTimeout(function(){
      updateUserHandAndTable(roomKey, username, socketId);
    }, 105);
  });

  // Discard a card from the table
  socket.on("discardTableCard", function(cardId){
    var roomKey = socket.rooms[1];
    repo.passCard(roomKey, "Table", "Discard", cardId);
    updateTableView(roomKey);
  });

});

// Refactored Functions

// Update User's Hand
function updateUserHand(roomKey, username, socketId){
  repo.getHand(roomKey, username, function(err, data){
    io.to(socketId).emit("updateHand", data.sort());
  });
}

// Update Table for each client
function updateTableView(roomKey){
  repo.getUserKeys(roomKey, function(err, keys){
    keys.forEach(function(key){
      repo.getHand(roomKey, "Table", function(err, data){
        io.to(key).emit("updateTable",  jsonParser(data));
      })
    })
  })
}

// Update Hands for all users
function updateAllUserHands(roomKey){
  repo.getUserKeys(roomKey, function(err, keys){
    keys.forEach(function(key){
      repo.getUser(roomKey, key, function(err, username){
        repo.getHand(roomKey, username, function(err, data){
          io.to(key).emit("updateHand", jsonParser(data));
        })
      })
    })
  })
}

// Update the user's hand that activated the event and update the table
function updateUserHandAndTable(roomKey, username, socketId){
  repo.getHand(roomKey, username, function(err, data){
    io.to(socketId).emit("updateHand", data.sort());
    updateTableView(roomKey);
  });
}
@@ -381,17 +381,16 @@
 et.id);%0A
-%0A
       re
@@ -489,17 +489,16 @@
     %7D);%0A
-%0A
       so
@@ -563,17 +563,16 @@
 rname);%0A
-%0A
       if
@@ -623,230 +623,15 @@
 %7D);%0A
+
   %7D);%0A%0A
-  // need to use inside every getHand callback%0A  function jsonParser(data) %7B%0A    var jsonCards = %5B%5D;%0A    for ( i=0; i %3C data.length; i++) %7B%0A      jsonCards.push(JSON.parse(data%5Bi%5D))%0A    %7D%0A    return jsonCards;%0A  %7D%0A%0A
   //
@@ -3091,16 +3091,215 @@
 ctions%0A%0A
+// need to use inside every getHand callback%0Afunction jsonParser(data) %7B%0A  var jsonCards = %5B%5D;%0A  for ( i=0; i %3C data.length; i++) %7B%0A    jsonCards.push(JSON.parse(data%5Bi%5D))%0A  %7D%0A  return jsonCards;%0A%7D%0A%0A
 // Updat
@@ -3312,16 +3312,16 @@
 's Hand%0A
-
 function
@@ -3452,32 +3452,43 @@
 t(%22updateHand%22, 
+jsonParser(
 data.sort());%0A  
@@ -3479,24 +3479,25 @@
 data.sort())
+)
 ;%0A  %7D);%0A%7D%0A%0A/
@@ -3748,32 +3748,39 @@
  jsonParser(data
+.sort()
 ));%0A      %7D)%0A   
@@ -4114,16 +4114,23 @@
 ser(data
+.sort()
 ));%0A    
@@ -4388,16 +4388,27 @@
 eHand%22, 
+jsonParser(
 data.sor
@@ -4411,16 +4411,17 @@
 .sort())
+)
 ;%0A    up

fix merge conflicts and reimplement mild sort functionality