module PlayTak.Commands (
    client,
    login,
    seek,
    acceptGame,
    sendPlay
) where

import Control.Concurrent
import Data.List

import Tak

import PlayTak.Types

client :: PlayTakClient -> String -> IO ()
client ptc name = do
    sendCmd ptc $ "Client " ++ name

login :: PlayTakClient -> Username -> Password -> IO ()
login ptc username password = do
    sendCmd ptc $ "Login " ++ username ++ " " ++ password

seek :: PlayTakClient -> Size -> Time -> Time -> Maybe Colour -> IO ()
seek ptc size time incr mColour =
    sendCmd ptc $ "Seek " ++ show size ++ " " ++ show time ++ " " ++ show incr ++
        case mColour of
            Nothing -> ""
            Just White -> " W"
            Just Black -> " B"

acceptGame :: PlayTakClient -> GameNumber -> IO ()
acceptGame ptc gameno = do
    sendCmd ptc $ "Accept " ++ show gameno

sendPlay :: PlayTakClient -> GameNumber -> Play -> IO ()
sendPlay ptc gameno play = do
    let cmd = "Game#" ++ show gameno ++ " " ++ case play of
            Place stone loc -> "P " ++ square loc ++ case stone of
                Flat -> ""
                Cap -> " C"
                Standing -> " W"
            Move loc dir drops -> "M " ++ square loc
                ++ " " ++ square (endSquare loc dir $ length drops)
                ++ " " ++ (concat $ intersperse " " $ map show drops)
    sendCmd ptc cmd

sendCmd :: PlayTakClient -> String -> IO ()
sendCmd ptc cmd = writeChan (clientChanCmd ptc) cmd

endSquare :: Loc -> Dir -> Int -> Loc
endSquare (i, j) PosX steps = (i + steps, j)
endSquare (i, j) NegX steps = (i - steps, j)
endSquare (i, j) PosY steps = (i, j + steps)
endSquare (i, j) NegY steps = (i, j - steps)

square :: Loc -> String
square (i, j) = (ranks !! (i - 1)) : show j

ranks :: String
ranks = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"