# Ian Binstock
# 6/4/26
# targets.py
# Showing how to use mouse inputs and click detection in the context of moving targets

import pygame, sys, random
from pygame.locals import * 

pygame.init()

# Variables
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 500
GAME_DURATION = 60

# Colors
WHITE = (255, 255, 255)
YELLOW = (255, 212, 0)
BLACK = (0, 0, 0)

# set up the display window
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Target Practice")
clock = pygame.time.Clock()

# set up fonts
smallfont = pygame.font.Font(None, 30)
largefont = pygame.font.Font(None, 60)

# c = sqrt(a^2 + b^2)
def hypotenuse(a, b):
    return (a**2 + b**2)**0.5

class Target:
    def __init__(self, y_pos, color, direction="right"):
        self.radius = random.randint(10, 50)
        self.y = y_pos
        self.color = color
        self.direction = direction
        
        # 6 speed * 20 frames = 120 pixels of seperation between targets
        base_speed = 6 
        
        # set target starting position and velocity based on direction
        if self.direction == "right":
            self.x = -self.radius
            self.speed = base_speed
        else:
            self.x = SCREEN_WIDTH + self.radius
            self.speed = -base_speed

    def move(self):
        self.x += self.speed

    def draw(self, surface):
        pygame.draw.circle(surface, self.color, (int(self.x), int(self.y)), self.radius)

    def is_clicked(self, mouse_pos):
        distance = hypotenuse(mouse_pos[0] - self.x, mouse_pos[1] - self.y)
        return distance <= self.radius

def main():
    targets = []
    score = 0
    frame_count = 0
    game_over = False

    while True:
        frame_count += 1
        
        # countdown
        if not game_over:
            seconds_passed = frame_count // 60
            time_left = max(0, GAME_DURATION - seconds_passed)
            if time_left <= 0:
                game_over = True

        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            
            # mouse click handling
            elif event.type == MOUSEBUTTONDOWN:
                # left mouse button
                if pygame.mouse.get_pressed()[0]:
                    for target in targets:
                        if target.is_clicked(event.pos):
                            score += (100 - target.radius)
                            targets.remove(target)
                            break

        if not game_over:
            # spawn new targets every 20 frames
            if frame_count % 20 == 0:
                targets.append(Target(y_pos=100, color=YELLOW, direction="right")) # row 1
                targets.append(Target(y_pos=300, color=BLACK, direction="left")) # row 2

            # target handling
            for target in targets[:]:
                # move targets
                target.move()
                
                # remove targets when they go off screen
                if target.direction == "right" and target.x - target.radius > SCREEN_WIDTH:
                    targets.remove(target)
                elif target.direction == "left" and target.x + target.radius < 0:
                    targets.remove(target)

        # draw elements
        screen.fill(WHITE)
        for target in targets:
            target.draw(screen)

        # draw UI
        score_text = smallfont.render(f"Score: {score}", True, BLACK)
        time_text = smallfont.render(f"{int(time_left)}", True, BLACK)
        
        screen.blit(score_text, (20, 20))
        screen.blit(time_text, (SCREEN_WIDTH - 40, 20))

        # end screen
        if game_over:
            screen.fill(WHITE)
            
            # render text
            score_text = largefont.render(f"{score}", True, BLACK)
            screen.blit(score_text, (SCREEN_WIDTH // 2 - score_text.get_width() // 2, SCREEN_HEIGHT // 2 - 20))

        pygame.display.update()
        clock.tick(60)

main()