YUI().use("node",function(Y){

  Y.on("domready", function()
  {
    var FACE = '23456789TJQKA';
    var SUIT = {
      'spades': 0,
      'hearts': 1,
      'clubs': 2,
      'diamonds': 3
    }
    
    var handbox = document.createElement('div');
    handbox.id = 'handbox';
    document.body.appendChild(handbox);
    
    Y.all('ol.deck').each(function()
    {
      var str = '';
      var deck = [];
      
      this.all('li').each(function(node, index, nodeList)
      {
        deck[index] = [FACE.indexOf(node.get('innerHTML').charAt(0)), getSuit(node)];
      });
      
      this.on("mouseover", function(evt)
      {
        mouseover(evt, evt.target, deck);
      });
      
      function getSuit(node)
      {
        for (var i in SUIT)
          if (node.hasClass(i)) return SUIT[i];
        throw new Error();
      }
    });
    
    function mouseover(evt, li, deck)
    {
      if (li.get('tagName') != 'LI')
      {
        return;
      }
     
      var parent = li.ancestor();
      var index = parent.all('li').indexOf(li);
      
      var players = parent.getAttribute('data-players');
      var isOmaha = parent.getAttribute('data-game')=='omaha';
      
      if (!(isOmaha ? window.solveOmaha : window.solveHand))
        return;
      
      if (players.indexOf('-')+1)
      {
        players = players.split('-');
        var str = '';
        for (i=0; i<players.length; i++)
        {
          str += getDealString(isOmaha, parseInt(players[i]), deck, index);;
        }
        handbox.style.width = '442px';
        handbox.innerHTML = str;
      }
      else
      {
        handbox.style.width = Math.ceil(players/6)*(isOmaha ? 240 : 200) + 20 + 'px';
        handbox.innerHTML = getDealString(isOmaha, parseInt(players), deck, index);;
      }
      
      Y.on('mousemove', mousemove);
      parent.on('mouseout', mouseout);
      
      handbox.style.display = 'block';
      
      mousemove(evt);
    }
    
    function mousemove(evt)
    {
      var target = evt.target;
      
      handbox.style.left = Math.round(Math.max(
        0,
        Math.min(evt.pageX, target.get('winWidth') - handbox.offsetWidth-30)
      )) + 'px';
      
      var scrollY = target.get('docScrollY');
      
      handbox.style.top = Math.round(
	  evt.pageY + handbox.offsetHeight + 30 < scrollY + target.get('winHeight')
          ||
          evt.pageY - handbox.offsetHeight - 30 < scrollY
          ?
          evt.pageY + 30
          :
          evt.pageY - handbox.offsetHeight - 30
        ) + 'px';
    }
    
    function mouseout()
    {
      Y.detach('mousemove', mousemove);
      Y.detach('mouseout', mouseout);
      handbox.style.display = 'none';
    }
    
    function getPlayerName(n, total)
    {
      return n==0 ? 'SB' :
       n+1==total ? 'DE' :
             n==1 ? 'BB' :
             n==2 ? 'UG' :
       n+2==total ? 'CO' :
                    'P'+(n+1);
    }
    /*var PLAYER_NAMES = {
      2: ['SB','DE'],
      3: ['SB','BB','DE'],
      4: ['SB','BB','UG','DE'],
      5: ['SB','BB','UG','CO','DE'],
      6: ['SB','BB','UG','','CO','DE'],
    }*/
    
    function getDealString(isOmaha, players, deck, index)
    {
      var hands = [];
      var table = [];
      var winStrings = [
        'Straight flush',
        'Four of a kind',
        'Full house',
        'Flush',
        'Straight',
        'Three of a kind',
        'Two pair',
        'Pair',
        'High card'
      ];
      var i,j;
      var holeCount = isOmaha ? 4 : 2; // how many cards to get
      
      for (i=0; i<players; i++)
      {
        hands[i] = [];
        for (j=0; j<holeCount; j++)
          hands[i][j] = deck[(index+i+players*j)%52];
      }
      
      table = [
        deck[(index+players*holeCount+1)%52],
        deck[(index+players*holeCount+2)%52],
        deck[(index+players*holeCount+3)%52],
        deck[(index+players*holeCount+5)%52],
        deck[(index+players*holeCount+7)%52]
      ];
      
      var solveFunc = isOmaha ? window.solveOmaha : window.solveHand;
      
      var result = solveFunc(hands, table);
      
      var str = '<div class="deal'+(isOmaha ? ' omaha':'')+'"><strong>'+players + ' Players'+(isOmaha ? ' (Omaha)':'')+'</strong>';
      
      str += '<ul>';
      
      for (i=0; i<players; i++)
      {
        str += '<li'+(result && i==result[0]?' class="winner"':'')+'><b>'+getPlayerName(i, players)+':</b> ';
        str += '<ol class="deck">';
        for (j=0; j<hands[i].length; j++)
          str += createCard(hands[i][j]);
        str += '</ol>';
        
        if (result && i==result[0])
        {
          str += '<span class="desc">'+winStrings[result[1]]+'</span>';
        }
        else
        {
          str += '<span class="desc">'+winStrings[solveFunc([hands[i]], table)[1]]+'</span>';
        }
        
        // columns
        if (i>0 && i+1<players && (i+1)%6==0) str += '</ul><ul>';
        
      }
      
      str += '</ul>';
      
      str += '<div class="table">';
      str += '<b>Table:</b> ';
      str += '<ol class="deck">';
      for (i=0; i<5; i++)
      {
        str += createCard(table[i]);
      }
      str += '</ol>';
      
      str += '</div>';
      str += '</div>';
      
      return str;
    }
    
    function createCard(card)
    {
      var SUIT = ['spades','hearts','clubs','diamonds'];
      var FACE = '23456789TJQKA';
      return '<li class="'+SUIT[card[1]]+'">'+FACE.charAt(card[0]);
    }
    
  });
});
