# This class implements a thread that handles the networking connection.
# It expects a copy of the board and an open socket to the remote host, which
# it will bind to a GTPSocket.
# This is the only thread that should be calling get(), but send() could be called
# twice, so we wrap it in a mutex.
# The board is also wrapped in a mutex, even though only this thread should modify it
# if it exists.

import select
import threading
import gtpsocket

class NetworkThread(threading.Thread):
    def __init__(self, goban, socket):
        threading.Thread.__init__(self)

        self.dispatcher = {
            'quit': self.do_quit,
            'boardsize': self.do_boardsize,
            'clear_board': self.do_clear_board,
            'komi': self.do_komi,
            'play': self.do_play,
            'genmove': self.do_genmove
            }

        self.goban = goban
        self.goban_lock = threading.Lock()
        self.socket = gtpsocket.GTPSocket(socket)
        self.send_lock = threading.Lock()

        gtpsocket.GTPSocket.known_cmds = gtpsocket.GTPSocket.known_cmds & set(self.dispatcher.keys())


    def run(self):
        while True:
            gtp = self.socket.get()
            if gtp is not None:
                self.dispatcher[gtp.command](gtp)


    def do_quit(self, gtp):
        pass


    def do_boardsize(self, gtp):
        with self.goban_lock:
            self.goban.set_board_size(int(gtp.arguments[0]))


    def do_clear_board(self, gtp):
        with self.goban_lock:
            self.goban.reset()


    def do_komi(self, gtp):
        with self.goban_lock:
            self.goban.komi = float(gtp.arguments[0])


    def do_play(self, gtp):
        if gtp.arguments[0] == 'black':
            color = goban.Goban.BLACK
        elif gtp.arguments[0] == 'white':
            color = goban.Goban.WHITE

        row = int(gtp.arguments[1][1:])
        col = ord(gtp.arguments[1][0]) - 96

        with self.goban_lock:
            self.goban.play_move((row,col), color)


    def do_genmove(self, gtp):
        pass