import threading
from common import constante
from common.point import Point


class TopLeftUserMangager(threading.Thread):

    def __init__(self, users, cases, events, finish_event, drawer, nb_users, draw_is_enable):
        super().__init__()
        self.cpt = nb_users
        self.cases = cases
        self.draw_is_enable = draw_is_enable
        self.users = []
        self.events = events
        self.drawer = drawer
        self.finish_event = finish_event
        for i in range(len(users)):
            user = users[i]
            if self.case_is_in_my_responsability(user.X, user.Y):
                self.users.append(user)

    def case_is_in_my_responsability(self, X, Y):
        return X < constante.WIDTH / 2 and Y < constante.HEIGHT / 2

    def can_moove(self, X, Y):
        return X >= 0 and Y >= 0 and (self.cases[X][Y].value == constante.EMPTY or self.cases[X][Y].value == constante.EXIT)

    def moove_user(self, user):
        for mouvement in constante.POSSIBLE_MOUVEMENT:
            X = user.X + mouvement.X
            Y = user.Y + mouvement.Y
            case = self.cases[X][Y]
            case.lock()
            if self.can_moove(X, Y):
                current_case = self.cases[user.X][user.Y]
                current_case.lock()
                current_case.value = constante.EMPTY
                if not case.value == constante.EXIT:
                    case.value = constante.PEOPLE
                case.unlock()
                current_case.unlock()
                self.cases[user.X][user.Y].unlock()
                if not case.value == constante.EXIT:
                    self.update_graphique(user, X, Y)
                    user.X = X
                    user.Y = Y
                else:
                    self.users.remove(user)
                    if len(self.users) <= 0:
                        self.events[0].clear()
                    self.cpt -= 1
                    if self.draw_is_enable:
                        self.drawer.remove_user(Point(user.X, user.Y))
                return
            case.unlock()

    def moove_users(self):
        for user in self.users:
            self.moove_user(user)

    def run(self):
        while self.cpt > 0:
            while len(self.users) <= 0:
                    self.events[0].wait()
            self.moove_users()
        self.finish_event.set()
        for i in range(1, 4):
            self.events[i].set()
        exit()

    def update_graphique(self, user, X, Y):
        if self.draw_is_enable:
            old_point = Point(user.X, user.Y)
            new_point = Point(X, Y)
            self.drawer.draw_user(old_point, new_point, user.color)
