import pyxel
import random

# Configuration de la taille de la fenêtre
BLOCK_SIZE = 8
GRID_WIDTH, GRID_HEIGHT = 10, 25
WIDTH, HEIGHT = GRID_WIDTH * BLOCK_SIZE, GRID_HEIGHT * BLOCK_SIZE

# Les formes des pièces Tetris avec couleurs associées
SHAPES = [
    ([[1, 1, 1, 1]], 7),  # ———
    ([[1, 1, 1], [0, 1, 0]], 1),  # T
    ([[1, 1], [1, 1]], 2),  # ■
    ([[0, 1, 1], [1, 1, 0]], 3),  # Z 
    ([[1, 1, 0], [0, 1, 1]], 4),  # S
    ([[1, 1, 1], [1, 0, 0]], 5),  # L
    ([[1, 1, 1], [0, 0, 1]], 6),  # J
]

class Tetris:
    def __init__(self):
        self.width, self.height = GRID_WIDTH, GRID_HEIGHT
        self.score, self.high_score = 0, 0
        self.game_over = False
        self.grid = [[0] * self.width for _ in range(self.height)]
        self.current_shape, self.next_shape = self.new_piece(), self.new_piece()
        
        if self.current_shape == SHAPES[2]:
            self.position = [self.width // 2 - 1, 3]
        else:
            self.position = [self.width // 2 - 2, 3]

        self.timers = {'move': 0, 'rotate': 0, 'side': 0, 'down': 0}
        self.intervals = {'move': 15, 'rotate': 5, 'side': 5, 'down': 5}

        pyxel.init(WIDTH, HEIGHT, title="Tetris")
        pyxel.load("res1.pyxres")
        pyxel.run(self.update, self.draw)

    def new_piece(self):
        return random.choice(SHAPES)

    def update(self):
        if self.game_over:
            if pyxel.btn(pyxel.KEY_R) or pyxel.btnp(pyxel.MOUSE_BUTTON_LEFT):  # Appuyez sur R pour redémarrer
                self.restart()
            return

        for key in self.timers:
            self.timers[key] += 1
        
        if pyxel.btnp(pyxel.MOUSE_BUTTON_LEFT):
            
            # Récupère les coordonnées de la souris
            x, y = pyxel.mouse_x, pyxel.mouse_y
            
            print(x, y)
            
            # Zone supérieure pour la rotation
            if y < 50 and self.timers['rotate'] >= self.intervals['rotate']:
                print("R")
                self.rotate_piece()
                self.timers['rotate'] = 0
            elif 40 > x > 0 and 50 < y < 150:
                print("L")
                self.handle_movement(pyxel.MOUSE_BUTTON_LEFT, -1)
            elif 80 > x > 40 and 50 < y < 150:
                print("Ri")
                self.handle_movement(pyxel.MOUSE_BUTTON_LEFT, 1)
            else:
                print("D")
                self.handle_movement(pyxel.MOUSE_BUTTON_LEFT, 0)
        
        self.handle_movement(pyxel.KEY_LEFT, -1)
        self.handle_movement(pyxel.KEY_RIGHT, 1)
        self.handle_movement(pyxel.KEY_DOWN, 0)

        if self.timers['rotate'] >= self.intervals['rotate'] and pyxel.btn(pyxel.KEY_UP):  # Rotation
            self.rotate_piece()
            self.timers['rotate'] = 0  # Réinitialiser le timer de rotation

        if self.timers['move'] >= self.intervals['move']:
            self.timers['move'] = 0
            self.position[1] += 1
            if self.collision():
                self.position[1] -= 1
                self.lock_piece()
                self.clear_lines()
                self.current_shape, self.next_shape = self.next_shape, self.new_piece()
                
                if self.current_shape == SHAPES[2]:
                    self.position = [self.width // 2 - 1, 3]
                else:
                    self.position = [self.width // 2 - 2, 3]

                if self.collision():
                    self.game_over = True
                    if self.score > self.high_score:  # Mettre à jour le high score
                        self.high_score = self.score

    def restart(self):
        self.timers = {'move': 0, 'rotate': 0, 'side': 0, 'down': 0}
        self.intervals = {'move': 15, 'rotate': 5, 'side': 5, 'down': 5}
        self.score = 0
        self.grid = [[0] * self.width for _ in range(self.height)]
        self.current_shape, self.next_shape = self.new_piece(), self.new_piece()

        if self.current_shape == SHAPES[2]:
            self.position = [self.width // 2 - 1, 3]
        else:
            self.position = [self.width // 2 - 2, 3]
            
        self.game_over = False

    def handle_movement(self, key, direction):
        if direction == 0:  # Mouvement vers le bas
            if pyxel.btn(key) and self.timers['down'] >= self.intervals['down']:
                self.position[1] += 1
                self.timers['down'] = 0  # Réinitialiser le timer de descente
                if self.collision():
                    self.position[1] -= 1
                    self.timers['move'] = 50
        else:  # Mouvement latéral
            if pyxel.btn(key) and self.timers['side'] >= self.intervals['side']:
                self.position[0] += direction
                if self.collision():
                    self.position[0] -= direction
                self.timers['side'] = 0  # Réinitialiser le timer latéral

    def rotate_piece(self):
        original_shape = self.current_shape[0]
        self.current_shape = (list(zip(*self.current_shape[0][::-1])), self.current_shape[1])
        
        if self.collision():
            self.current_shape = (original_shape, self.current_shape[1])  # Annuler la rotation si collision

    def collision(self):
        for y, row in enumerate(self.current_shape[0]):
            for x, value in enumerate(row):
                if value:
                    grid_x, grid_y = x + self.position[0], y + self.position[1]
                    if (grid_x < 0 or grid_x >= self.width or
                        grid_y >= self.height or
                        (grid_y >= 0 and self.grid[grid_y][grid_x])):
                        return True
        return False

    def lock_piece(self):
        self.intervals['move'] = self.intervals['move'] * 0.98
        for y, row in enumerate(self.current_shape[0]):
            for x, value in enumerate(row):
                if value:
                    self.grid[y + self.position[1]][x + self.position[0]] = self.current_shape[1]  # Utilise la couleur de la pièce

    def clear_lines(self):
        lines_to_clear = [i for i, row in enumerate(self.grid) if all(row)]
        
        if len(lines_to_clear) == 1:
            self.score += 1  # 1 ligne
        elif len(lines_to_clear) == 2:
            self.score += 3  # Combo de 2
        elif len(lines_to_clear) == 3:
            self.score += 5  # Combo de 3
        elif len(lines_to_clear) >= 4:
            self.score += 10  # Combo de 4 ou plus
        
        for i in lines_to_clear:
            del self.grid[i]
            self.grid.insert(0, [0] * self.width)

    def draw(self):
        pyxel.cls(0)
        self.draw_grid()
        self.draw_shape(self.current_shape[0], self.position, self.current_shape[1])
        self.draw_next_shape()
        pyxel.text(4, 4, f'Score: {self.score}', 7)
        pyxel.text(4, 14, f'High: {self.high_score}', 7)

        # Dessiner la ligne limite en haut
        pyxel.line(0, 3 * BLOCK_SIZE, WIDTH, 3 * BLOCK_SIZE, 7)

        if self.game_over:
            pyxel.rect(0, HEIGHT // 2 - 10, 80, 24, 0)
            pyxel.text(WIDTH // 2 - 20, HEIGHT // 2 - 5, "GAME OVER", 8)
            pyxel.text(WIDTH // 2 - 35, HEIGHT // 2 + 5, "Press R to Restart", 8)

    def draw_grid(self):
        for y in range(self.height):
            for x in range(self.width):
                color = self.grid[y][x]
                if color:  # Vérifie si la case est occupée
                    pyxel.blt(x * BLOCK_SIZE, y * BLOCK_SIZE, 2, color * 8, 0, 8, 8)

    def draw_shape(self, shape, position, color):
        for y, row in enumerate(shape):
            for x, value in enumerate(row):
                if value:
                    pyxel.blt((position[0] + x) * BLOCK_SIZE, (position[1] + y) * BLOCK_SIZE, 2, color * 8, 0, 8, 8)

    def draw_next_shape(self):
        if self.next_shape == SHAPES[2]:
            next_shape_x = (GRID_WIDTH - 3) * BLOCK_SIZE  # Position à droite
            next_shape_y = 0.5 * BLOCK_SIZE  # Position en haut
        elif self.next_shape == SHAPES[0]:
            next_shape_x = (GRID_WIDTH - 4.5) * BLOCK_SIZE  # Position à droite
            next_shape_y = 1 * BLOCK_SIZE  # Position en haut
        else:
            next_shape_x = (GRID_WIDTH - 3.5) * BLOCK_SIZE  # Position à droite
            next_shape_y = 0.5 * BLOCK_SIZE  # Position en haut

        for y, row in enumerate(self.next_shape[0]):
            for x, value in enumerate(row):
                if value:
                    pyxel.blt(next_shape_x + x * BLOCK_SIZE, next_shape_y + y * BLOCK_SIZE, 2, self.next_shape[1] * 8, 0, 8, 8)

if __name__ == "__main__":
    Tetris()