# Sparsh Pandey
# 22 Jun 2025
# Game Screen for balloon game

import pygame, sys, random

# Setup for our play screen
pygame.init()
WIDTH, HEIGHT = 640, 480
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 36)

# R G B
colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255)]

# getters for color name
def color_name(color):
    if color == (255, 0, 0): return "red"
    if color == (0, 255, 0): return "green"
    if color == (0, 0, 255): return "blue"
    return "unknown"

# make circles randomly. Don't make it too close to edges (would be off screen or look bad)
def make_circle():
    return {
        "color": random.choice(colors),
        "pos": (random.randint(50, WIDTH - 50), random.randint(100, HEIGHT - 50)),
        "radius": 30,
        "spawn_time": pygame.time.get_ticks(), # saves how long it's been alive
        "lifespan": random.randint(1000, 2000) # random lifespan
    }

# main game loop
def run():

    # Game setup
    score = 0
    time_limit = 30  # seconds
    circle_count = 6
    target_color = random.choice(colors) # can be any color
    start_time = pygame.time.get_ticks()

    # kinda cool I can do this in 1 short line
    circles = [make_circle() for i in range(circle_count)]

    while True:

        # get time now
        now = pygame.time.get_ticks()

        # Make new circle since we lost our old ones
        for circle in circles:
            if now - circle["spawn_time"] > circle["lifespan"]:
                circle.update(make_circle())

        # Bakcground and text
        screen.fill((0, 0, 0))
        label = font.render(f"Tap the {color_name(target_color)} circles!", True, (255, 255, 255))
        screen.blit(label, (20, 10))

        # time elpased and remaining, along with printing a timer
        elapsed = (now - start_time) // 1000
        remaining = max(0, time_limit - elapsed)
        timer_text = font.render(f"Time: {remaining}", True, (255, 255, 255))
        score_text = font.render(f"Score: {score}", True, (255, 255, 255))
        screen.blit(timer_text, (WIDTH - 150, 10))
        screen.blit(score_text, (WIDTH - 150, 40))

        # draw every circle in our list
        for circle in circles:
            if circle["color"] is not None:
                pygame.draw.circle(screen, circle["color"], circle["pos"], circle["radius"])

        pygame.display.update()

        # Check events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            # mouse down
            elif event.type == pygame.MOUSEBUTTONDOWN:

                # get pos (only when mouse button is down, not every iteratio )
                mx, my = event.pos

                # iterate through circle list
                for circle in circles:

                    # dead circle
                    if circle["color"] is None:
                        continue

                    # center and r of circle
                    cx, cy = circle["pos"]
                    r = circle["radius"]

                    # distance forumla, I should have written a method but it's fine now
                    dist = ((mx - cx) ** 2 + (my - cy) ** 2) ** 0.5

                    # check result to see if we're in the circle
                    if dist <= r:

                        # add to score
                        if circle["color"] == target_color:
                            score += 1

                        # sub from score
                        else:
                            score -= 1
                        
                        # circle clicked, so update ballon stats
                        circle["color"] = None
                        circle["spawn_time"] = now
                        circle["lifespan"] = random.randint(1000, 3000)

                        # can only click 1 balloon per click (would be too op otherwise)
                        break

        # check time limit
        if now - start_time >= time_limit * 1000:
            break
            
        # 60 fps
        clock.tick(60)

    # Game over screen
    screen.fill((0, 0, 0))
    text = font.render(f"Game Over! Final Score: {score}", True, (255, 255, 255))
    screen.blit(text, text.get_rect(center=(WIDTH // 2, HEIGHT // 2)))
    pygame.display.flip()
    pygame.time.wait(3000)

