import pygame
import math
import random

# Initialisation de PyGame
pygame.init()

# Constantes
LARGEUR = 800
HAUTEUR = 600
BLANC = (255, 255, 255)
NOIR = (0, 0, 0)
ROUGE = (255, 0, 0)
VERT = (0, 200, 0)
BLEU = (0, 0, 255)
GRAVITE = 9.81
DUREE_JEU = 60  # secondes
meilleurs_scores = []

# Fenêtre
fenetre = pygame.display.set_mode((LARGEUR, HAUTEUR))
pygame.display.set_caption("Jeu de tir de projectile")
font = pygame.font.SysFont(None, 24)

# Cible
def nouvelle_cible():
    return random.randint(400, 750), random.randint(100, 500)

x_cible, y_cible = nouvelle_cible()

# Classe Projectile
class Projectile:
    def __init__(self, x0, y0, v0, angle):
        self.x = x0
        self.y = y0
        self.vx = v0 * math.cos(math.radians(angle))
        self.vy = -v0 * math.sin(math.radians(angle))  # sens y vers le bas
        self.positions = [(x0, y0)]
        self.dt = 0.1
        self.actif = True

    def update(self):
        if not self.actif:
            return
        # Accélérations
        ax = 0
        ay = GRAVITE

        # Mise à jour vitesse
        self.vx += ax * self.dt
        self.vy += ay * self.dt

        # Mise à jour position
        self.x += self.vx * self.dt
        self.y += self.vy * self.dt

        if self.y > HAUTEUR:
            self.actif = False
        else:
            self.positions.append((self.x, self.y))

# Curseur
class Curseur:
    def __init__(self, x, y, min_val, max_val, val_init, label):
        self.x = x
        self.y = y
        self.largeur = 200
        self.hauteur = 6
        self.min_val = min_val
        self.max_val = max_val
        self.val = val_init
        self.label = label
        self.curseur_rect = pygame.Rect(x, y, self.largeur, self.hauteur)
        self.police = pygame.font.SysFont(None, 26)

    def draw(self, fenetre):
        fond_rect = pygame.Rect(self.x, self.y, self.largeur, self.hauteur)
        pygame.draw.rect(fenetre, (200, 200, 200), fond_rect, border_radius=3)

        progress = int((self.val - self.min_val) / (self.max_val - self.min_val) * self.largeur)
        progress_rect = pygame.Rect(self.x, self.y, progress, self.hauteur)
        pygame.draw.rect(fenetre, VERT, progress_rect, border_radius=3)

        curseur_x = self.x + progress
        curseur_y = self.y + self.hauteur // 2
        pygame.draw.circle(fenetre, (100, 100, 100), (curseur_x + 2, curseur_y + 2), 9)
        pygame.draw.circle(fenetre, (50, 150, 255), (curseur_x, curseur_y), 9)

        label_surface = self.police.render(self.label, True, NOIR)
        val_surface = self.police.render(f"{self.val:.1f}", True, NOIR)
        fenetre.blit(label_surface, (self.x, self.y - 30))
        fenetre.blit(val_surface, (self.x + self.largeur + 15, self.y - 10))

    def update(self, mouse_pos):
        if self.curseur_rect.collidepoint(mouse_pos):
            rel_x = mouse_pos[0] - self.x
            self.val = self.min_val + (rel_x / self.largeur) * (self.max_val - self.min_val)
            self.val = max(self.min_val, min(self.max_val, self.val))

# Curseurs pour vitesse et angle
curseur_vitesse = Curseur(50, 50, 10, 150, 50, "Vitesse (m/s)")
curseur_angle = Curseur(50, 120, 10, 80, 45, "Angle (deg)")

# Menu d’accueil
def menu():
    en_menu = True
    while en_menu:
        fenetre.fill(BLANC)
        titre = font.render("Jeu de tir de projectile", True, NOIR)
        jouer_texte = font.render("Clique ici pour jouer", True, BLANC)
        bouton_rect = pygame.Rect(LARGEUR//2 - 100, HAUTEUR//2, 200, 50)

        fenetre.blit(titre, (LARGEUR//2 - titre.get_width()//2, HAUTEUR//2 - 100))
        pygame.draw.rect(fenetre, VERT, bouton_rect)
        fenetre.blit(jouer_texte, (bouton_rect.x + 30, bouton_rect.y + 15))

        for i, sc in enumerate(meilleurs_scores):
            txt_score = font.render(f"{i+1}) {sc}", True, NOIR)
            fenetre.blit(txt_score, (LARGEUR//2 - 50, HAUTEUR//2 - 60 + i*20))

        pygame.display.update()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if bouton_rect.collidepoint(pygame.mouse.get_pos()):
                    en_menu = False

# Calcul de la trajectoire attendue
def calculer_trajectoire_temporaire(x0, y0, v0, angle_deg):
    angle = math.radians(angle_deg)
    t = 0
    dt = 0.01
    points = []
    while True:
        x = v0 * math.cos(angle) * t
        y = v0 * math.sin(angle) * t - 0.5 * GRAVITE * t**2
        if y < 0:
            break
        points.append((x0 + x, y0 - y))
        t += dt
    return points

# Dessin de la scène
def dessiner(fenetre, trajectoire, projectile, score, temps_restant):
    fenetre.fill((245, 245, 245))
    pygame.draw.circle(fenetre, ROUGE, (x_cible, y_cible), 10)

    if trajectoire and len(trajectoire) > 1:
        pygame.draw.lines(fenetre, NOIR, False, trajectoire, 2)

    curseur_vitesse.draw(fenetre)
    curseur_angle.draw(fenetre)
    txt_score = font.render(f"Score : {score}", True, NOIR)
    txt_temps = font.render(f"Temps restant : {int(temps_restant)}s", True, NOIR)
    fenetre.blit(txt_score, (600, 20))
    fenetre.blit(txt_temps, (600, 50))

    if projectile and projectile.positions:
        x_balle, y_balle = projectile.positions[-1]
        pygame.draw.circle(fenetre, BLEU, (int(x_balle), int(y_balle)), 6)

    pygame.display.update()

# Lancement du jeu
def jouer_une_partie():
    global x_cible, y_cible, meilleurs_scores

    clock = pygame.time.Clock()
    trajectoire = []
    projectile = None
    running = True
    souris_active = False
    score = 0
    start_time = pygame.time.get_ticks()

    
    while running:
        dt = clock.tick(60)
        temps_ecoule = (pygame.time.get_ticks() - start_time) / 1000
        temps_restant = max(0, DUREE_JEU - temps_ecoule)
        if temps_restant <= 0:
            running = False

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                souris_active = True
            elif event.type == pygame.MOUSEBUTTONUP:
                souris_active = False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    v = curseur_vitesse.val
                    a = curseur_angle.val
                    projectile = Projectile(50, HAUTEUR - 50, v, a)
                    trajectoire = []

                elif event.key == pygame.K_RIGHT:
                    curseur_vitesse.val = min(curseur_vitesse.val + 1, curseur_vitesse.max_val)
                elif event.key == pygame.K_LEFT:
                    curseur_vitesse.val = max(curseur_vitesse.val - 1, curseur_vitesse.min_val)
                elif event.key == pygame.K_UP:
                    curseur_angle.val = min(curseur_angle.val + 1, curseur_angle.max_val)
                elif event.key == pygame.K_DOWN:
                    curseur_angle.val = max(curseur_angle.val - 1, curseur_angle.min_val)

        if souris_active:
            curseur_vitesse.update(pygame.mouse.get_pos())
            curseur_angle.update(pygame.mouse.get_pos())

        if not projectile or not projectile.actif:
            trajectoire = calculer_trajectoire_temporaire(50, HAUTEUR - 50, curseur_vitesse.val, curseur_angle.val)

        if projectile and projectile.actif:
            projectile.update()
            trajectoire = projectile.positions

            # Collision avec la cible
            if projectile.positions:
                x, y = projectile.positions[-1]
                if (x - x_cible)**2 + (y - y_cible)**2 < 100:
                    score += 1
                    x_cible, y_cible = nouvelle_cible()
                    projectile.actif = False

        dessiner(fenetre, trajectoire, projectile, score, temps_restant)

    meilleurs_scores.append(score)
    meilleurs_scores.sort(reverse=True)
    meilleurs_scores = meilleurs_scores[:5]

# Boucle principale
while True:
    menu()
    jouer_une_partie()
