class NodeVisual(object):
    def __init__(self, node, draw_pos, scale, draw_surface):
        '''Initializes the visual node. The node argument is the a_star node that we will be
        polling property information from.'''
        self.node = node  #A_Star node
        self.shape = Rectangle(draw_pos, (255, 255, 255), scale, draw_surface,
                               0)  #Visual drawn to the screen
        self.is_hoovered = False  #True if the mouse is hoovering over the node
        self.is_start = False  #True if the node is the starting node of the algorithm
        self.is_goal = False  #True if the node is the goal node of the algorithm
        self.is_path = False  #True if the node is part of the algorithm path
        self.is_open = False  #True if the node is in the open list
        self.is_closed = False  #True if the node is in the closed list
        self.show_scores = False  #Toggles the node scores to be drawn to the screen
        self.border = Rectangle(
            draw_pos, (255, 255, 255), scale, draw_surface,
            4)  #Highlight border for when the mouse is over the node

    def update(self, events):
        '''Handles all the bevhavious and color changes of the visual node'''
        self.node_clicked(events)
        if not self.node.traversable:
            self.shape.change_color((0, 0, 0))
        elif self.is_closed and not self.is_start and not self.is_goal:
            self.shape.change_color((247, 143, 143))
        elif self.is_open and not self.is_start and not self.is_goal:
            self.shape.change_color((143, 183, 247))
        elif self.is_start:
            self.shape.change_color((0, 255, 0))
        elif self.is_goal:
            self.shape.change_color((255, 0, 0))
        else:
            self.shape.change_color((255, 255, 255))
        if self.is_hoovered:
            self.border.change_color((255, 0, 0))
        else:
            self.border.change_color((0, 0, 0))

    def reset_node(self):
        '''Resets the node to its initial state'''
        self.is_closed = False
        self.is_open = False
        self.is_path = False
        self.node.parent = None

    def draw(self, graph_visual):
        '''All the drawing behaviours for the visual node'''
        self.shape.draw()
        self.border.draw()
        #If the nodes has a parent we will draw a line from the parent to this node
        if self.node.parent is not None:
            par = graph_visual.get_visual(self.node.parent)
            line = pygame.draw.lines(
                self.shape.draw_surface, (0, 255, 0), True,
                [[
                    self.shape.position.x_pos + self.shape.scale[0] / 2,
                    self.shape.position.y_pos + self.shape.scale[1] / 2
                ],
                 [
                     par.shape.position.x_pos + par.shape.scale[0] / 2,
                     par.shape.position.y_pos + par.shape.scale[1] / 2
                 ]], 1)
        #Drawing of the text to the screen
        #Will only draw if the node was used in the algorithm and show_scores is true
        if (self.is_open or self.is_closed or self.is_goal
                or self.is_start) and self.show_scores:
            text = Text(Vector2(5, 5), (0, 0, 0), str(self.node.f_score), 12,
                        self.shape.draw_surface)
            text.draw_on_surface(self.shape.rect)
            text2 = Text(Vector2(25, 20), (0, 0, 0), str(self.node.h_score),
                         12, self.shape.draw_surface)
            text2.draw_on_surface(self.shape.rect)
            text3 = Text(Vector2(5, 20), (0, 0, 0), str(self.node.g_score), 12,
                         self.shape.draw_surface)
            text3.draw_on_surface(self.shape.rect)

    def node_clicked(self, events):
        '''Click behaviour for the visual node. Highlights the node if it is being hoovered.
        Also if the mouse was clicked while it was hoovered it will make the node not traversable'''
        mouse_position = pygame.mouse.get_pos()
        if self.shape.rect.collidepoint(mouse_position):
            self.is_hoovered = True
            for event in events:
                if event.type == pygame.MOUSEBUTTONDOWN:
                    self.node.traversable = not self.node.traversable
        else:
            self.is_hoovered = False