import copy
import time
from Code.UI.Field import Field
from Code.UI.Square import Square
from Code.helpers import index_2d


class Rules:
    def __init__(self):
        pass

    def _get_neighborhood(self,mid_y, mid_x, field_of_squares: list) -> list:
        # mid_y, mid_x = index_2d(field_of_squares, target)

        top = field_of_squares[mid_y - 1][mid_x - 1], field_of_squares[mid_y - 1][mid_x], field_of_squares[mid_y - 1][
            mid_x + 1]
        middle = field_of_squares[mid_y][mid_x - 1], field_of_squares[mid_y][mid_x + 1]
        bottom = field_of_squares[mid_y + 1][mid_x - 1], field_of_squares[mid_y + 1][mid_x], \
                 field_of_squares[mid_y + 1][mid_x + 1]

        neighborhood = [top[0], top[1], top[2], middle[0], middle[1], bottom[0], bottom[1], bottom[2]]
        return neighborhood

    def _number_of_alive_nigbohrs(self, neighborhood: list) -> int:
        count = 0
        for square in neighborhood:
            if square.active:
                count += 1
        #print("count {}".format(count))
        return count

    def _use_rules_on_square(self, target: Square, index_y, index_x, field_of_squares: list):
        #print(f"Checking field: y:{index_y} x:{index_x} state: {field_of_squares[index_y][index_x].active}")
        neighborhood = self._get_neighborhood(index_y, index_x, field_of_squares)
        number_of_alive_nigbohrs = self._number_of_alive_nigbohrs(neighborhood)

        old_target = field_of_squares[index_y][index_x]
        if not old_target.active:
            if number_of_alive_nigbohrs == 3:
                target.update(True)
        else:
            if number_of_alive_nigbohrs < 2:
                target.update(False)
            if number_of_alive_nigbohrs == 2 or number_of_alive_nigbohrs == 3:
                target.update(True)  # eigentlich unnötig da es einfach den zustand beibehalten kann
            if number_of_alive_nigbohrs > 3:
                target.update(False)

        return target


    def evolve_field(self, field_old) -> Field:
        start = time.time()
        field_new = Field()
        end = time.time()
        #print(end - start)

        index_x = 0
        index_y = 0
        lenght=len(field_new.squares)
        for x in field_new.squares:
            index_y=0
            for square in x:
                if (index_y != 0 and index_x != 0 and index_y < lenght -1 and index_x < lenght-1):
                    new_field=self._use_rules_on_square(field_new.squares[index_y][index_x], index_y, index_x, field_old.squares)
                    field_new.squares[index_y][index_x] = new_field

                index_y +=1
            index_x += 1
        return field_new.squares
