module T3.Server.Lobby where

import Prelude
import Control.Monad
import Control.Concurrent.STM
import System.Random
import Data.Maybe
import T3.Match

type Lobby = [(UserName, StartCallback)]

addUserToLobby :: TVar Lobby  -> UserName -> (StartCallback) -> IO Bool
addUserToLobby lobby un cb = atomically $ do
  lob <- readTVar lobby
  let shouldAdd = isNothing (lookup un lob)
  when shouldAdd $ writeTVar lobby ((un, cb) : lob)
  return shouldAdd

userPairFromLobby :: TVar Lobby -> IO (Maybe ((UserName, StartCallback), (UserName, StartCallback)))
userPairFromLobby lobby = do
  a <- randomIO
  b <- randomIO
  atomically $ do
    lob <- readTVar lobby
    let len = length lob
    if len < 2 then return Nothing else grabEm lob (mod a len) (mod b (len - 1))
  where
    grabEm lob i j = do
      let (x, lob') = grab lob i
      let (y, lob'') = grab lob' j
      writeTVar lobby lob''
      return $ Just (x, y)
    grab :: [a] -> Int -> (a, [a])
    grab xs idx = (xs !! idx, take idx xs ++ drop (idx + 1) xs)