from pygame import mixer

from util.ConfigurationManager import ConfigurationManager
from entity.Piece import Piece
from entity.Well import Well
from entity.Entity import Entity

class Stack(Entity):

    def __init__(self, color: str, border_color: str):
        super().__init__([], color, border_color)
        self.rows_completed_count = 0
        self.row_completion_sound = mixer.Channel(1)

    def update(self, elapsed_time) -> None:
        super().update(elapsed_time)
        self.rows_completed_count += self.__complete_rows()

    def add_piece(self, piece: Piece) -> None:
        self.points += piece.points

    def __complete_rows(self) -> int:
        squares_by_row = {}
        for square in self.points:
            top_left_vertex = square[0]
            if top_left_vertex[1] not in squares_by_row:
                squares_by_row[top_left_vertex[1]] = []
            if square not in squares_by_row[top_left_vertex[1]]:
                squares_by_row[top_left_vertex[1]].append(square)

        squares_to_exclude = []
        rows_completed = []
        for key in squares_by_row:
            if len(squares_by_row[key]) == Well.WIDTH:
                squares_to_exclude += squares_by_row[key]
                rows_completed.append(key)

        if len(squares_to_exclude) == 0:
            return 0

        self.__play_row_completion_sound()

        tile_size =  ConfigurationManager.configuration["engine"]["tile-size"]
        new_points = []
        for square in self.points:
            if square not in squares_to_exclude:
                for vertex in square:
                    distance_to_move = 0
                    for row_completed in rows_completed:
                        if vertex[1] <= row_completed:
                            distance_to_move += 1
                    vertex[1] += tile_size * distance_to_move
                new_points.append(square)
        self.points = new_points

        return len(rows_completed)

    def __play_row_completion_sound(self) -> None:
        row_completion_sound_file = ConfigurationManager.configuration["sound"]["row-completion"]
        self.row_completion_sound.play(mixer.Sound(row_completion_sound_file))