import pygame
import math

# Initialisation de Pygame
pygame.init()
LARGEUR, HAUTEUR = 1000, 800
fenetre = pygame.display.set_mode((LARGEUR, HAUTEUR))
pygame.display.set_caption("Simulation de mise en orbite réaliste")
clock = pygame.time.Clock()
font = pygame.font.SysFont("Arial", 16)

# Constantes physiques
G = 6.67430e-11  # constante gravitationnelle
M_TERRE = 5.972e24  # masse de la Terre (kg)
R_TERRE = 6.371e6  # rayon de la Terre (m)

# Échelle graphique
ECHELLE = 0.25e-5  # 1 mètre = ECHELLE pixels

# Position de la Terre (centre écran)
centre_x, centre_y = LARGEUR // 2, HAUTEUR // 2

# Paramètres initiaux : orbite géostationnaire
altitude = 35786e3  # 35 786 km
rayon_orbite = R_TERRE + altitude
position = [rayon_orbite, 0]  # position initiale (x, y) en m
v_orbitale = math.sqrt(G * M_TERRE / rayon_orbite)
vitesse = [0, v_orbitale]  # vecteur vitesse initial (vx, vy) optimal

masse_satellite = 500  # masse arbitraire en kg
dt = 100  # pas de temps en secondes
trajectoire = []

def afficher_texte(surface, texte, x, y, couleur=(255, 255, 255)):
    rendu = font.render(texte, True, couleur)
    surface.blit(rendu, (x, y))

def calcul_force_gravitationnelle(pos):
    x, y = pos
    r = math.hypot(x, y)
    force = -G * M_TERRE * masse_satellite / r**3
    return [force * x, force * y]  # Fx, Fy

def calcul_vitesse_orbitale_theorique(r):
    return math.sqrt(G * M_TERRE / r)

def calcul_vitesse_liberation(r):
    return math.sqrt(2 * G * M_TERRE / r)

def main():
    global vitesse, position
    running = True
    MAX_TRAJECTOIRE = 5000
    statut = ""

    while running:
        clock.tick(60)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

        touches = pygame.key.get_pressed()
        if touches[pygame.K_RIGHT]:
            vitesse[1] += 100  # +1 km/s en y
        if touches[pygame.K_LEFT]:
            vitesse[1] = max(0, vitesse[1] - 100)

        # Calcul des forces
        force = calcul_force_gravitationnelle(position)
        acceleration = [force[0] / masse_satellite, force[1] / masse_satellite]

        # Intégration (Euler)
        vitesse[0] += acceleration[0] * dt
        vitesse[1] += acceleration[1] * dt
        position[0] += vitesse[0] * dt
        position[1] += vitesse[1] * dt

        # Enregistrement de la trajectoire
        x_aff = int(centre_x + position[0] * ECHELLE)
        y_aff = int(centre_y + position[1] * ECHELLE)
        trajectoire.append((x_aff, y_aff))
        if len(trajectoire) > MAX_TRAJECTOIRE:
            trajectoire.pop(0)

        # Distance au centre
        r = math.hypot(*position)
        v_norme = math.hypot(*vitesse)
        v_orbitale = calcul_vitesse_orbitale_theorique(r)
        v_lib = calcul_vitesse_liberation(r)

        # Statut
        if r < R_TERRE:
            statut = "💥 Le satellite s’est écrasé !"
        elif v_norme > v_lib:
            statut = "🛫 Le satellite s’échappe !"
        elif abs(v_norme - v_orbitale) / v_orbitale < 0.05:
            statut = "🛰️ Orbite quasi circulaire"
        else:
            statut = "🔁 Orbite elliptique ou instable"

        # Affichage
        fenetre.fill((0, 0, 10))

        # Terre
        pygame.draw.circle(fenetre, (0, 100, 255), (centre_x, centre_y), int(R_TERRE * ECHELLE))

        # Orbite / trajectoire
        if len(trajectoire) > 1:
            pygame.draw.lines(fenetre, (200, 200, 200), False, trajectoire, 1)

        # Satellite
        pygame.draw.circle(fenetre, (255, 255, 0), (x_aff, y_aff), 4)

        # Infos
        afficher_texte(fenetre, f"Vitesse actuelle : {v_norme / 1000:.2f} km/s", 10, 10)
        afficher_texte(fenetre, f"Altitude : {(r - R_TERRE) / 1000:.0f} km", 10, 30)
        afficher_texte(fenetre, f"Vitesse orbitale idéale : {v_orbitale / 1000:.2f} km/s", 10, 50)
        afficher_texte(fenetre, f"Vitesse de libération : {v_lib / 1000:.2f} km/s", 10, 70)
        afficher_texte(fenetre, f"Statut : {statut}", 10, 100, (255, 180, 180))
        afficher_texte(fenetre, "← / → pour modifier la vitesse (km/s)", 10, 130)

        pygame.display.flip()

    pygame.quit()

if __name__ == "__main__":
    main()
