--# CardStacker
-- Groups cards by where they are. Every card is hashed to the group it landed
-- in, so stacks[card] is that card's pile and stacks[1..n] are the piles.

CardStacker = class()

function CardStacker:init(cards)
  self.stacks = {}
  self.cards = cards
  self.radiusForStacking = cards[1].width * 0.3
  self:refreshStacks()
end

function CardStacker:refreshStacks()
  self.stacks = self:tablesOfCardsCloserThan(self.radiusForStacking, self.cards)
end

function CardStacker:tablesOfCardsCloserThan(maxDistance, cards)
  local cardsAtLocations = {}
  for _, card in ipairs(cards) do
    if card and card.body and card.body.position then
      self:placeInGroup(card, cardsAtLocations, maxDistance)
    end
  end
  return cardsAtLocations
end

-- a card joins the first group it is close enough to, or starts its own
function CardStacker:placeInGroup(card, cardsAtLocations, maxDistance)
  for _, group in ipairs(cardsAtLocations) do
    if card.body.position:dist(group[1].body.position) <= maxDistance then
      table.insert(group, card)
      cardsAtLocations[card] = group
      return
    end
  end
  table.insert(cardsAtLocations, {card})
  cardsAtLocations[card] = cardsAtLocations[#cardsAtLocations]
end
