import pygame
import random
import math

# Window dimensions
WIDTH, HEIGHT = 800, 600

# Square dimensions
SQUARE_SIZE = 300
SQUARE_X, SQUARE_Y = (WIDTH - SQUARE_SIZE) // 2, (HEIGHT - SQUARE_SIZE) // 2

# Ball properties
BALL_RADIUS = 10

class Ball:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.speed_x = 0
        self.speed_y = 0

    def move(self):
        self.x += self.speed_x
        self.y += self.speed_y

        if self.x - BALL_RADIUS < SQUARE_X or self.x + BALL_RADIUS > SQUARE_X + SQUARE_SIZE:
            self.speed_x *= -1
        if self.y - BALL_RADIUS < SQUARE_Y or self.y + BALL_RADIUS > SQUARE_Y + SQUARE_SIZE:
            self.speed_y *= -1

def check_collision(ball1, ball2):
    dx = ball1.x - ball2.x
    dy = ball1.y - ball2.y
    dist = math.hypot(dx, dy)
    if dist < 2 * BALL_RADIUS:
        # Calculate new speeds
        normal_x = dx / dist
        normal_y = dy / dist
        tangent_x = -normal_y
        tangent_y = normal_x

        v1n = ball1.speed_x * normal_x + ball1.speed_y * normal_y
        v1t = ball1.speed_x * tangent_x + ball1.speed_y * tangent_y

        v2n = ball2.speed_x * normal_x + ball2.speed_y * normal_y
        v2t = ball2.speed_x * tangent_x + ball2.speed_y * tangent_y

        v1n, v2n = v2n, v1n

        ball1.speed_x = v1n * normal_x + v1t * tangent_x
        ball1.speed_y = v1n * normal_y + v1t * tangent_y

        ball2.speed_x = v2n * normal_x + v2t * tangent_x
        ball2.speed_y = v2n * normal_y + v2t * tangent_y

def main():
    pygame.init()
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    clock = pygame.time.Clock()

    balls = [Ball(random.randint(SQUARE_X, SQUARE_X + SQUARE_SIZE), random.randint(SQUARE_Y, SQUARE_Y + SQUARE_SIZE)) for _ in range(10)]
    for ball in balls:
        ball.speed_x = random.uniform(-1, 1)
        ball.speed_y = random.uniform(-1, 1)
    player_ball = Ball(WIDTH // 2, HEIGHT - 50)
    player_ball.speed_x = 0
    player_ball.speed_y = 0
    player_turn = True
    score = [0, 0]
    aiming = False
    aim_start = (0, 0)
    aim_end = (0, 0)

    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE and player_turn:
                dx = SQUARE_X + SQUARE_SIZE // 2 - player_ball.x
                dy = SQUARE_Y + SQUARE_SIZE // 2 - player_ball.y
                dist = math.hypot(dx, dy)
                if dist > 0:
                    player_ball.speed_x = dx / dist * 10
                    player_ball.speed_y = dy / dist * 10
                player_turn = False
            elif event.type == pygame.MOUSEBUTTONDOWN and player_turn:
                aiming = True
                aim_start = (player_ball.x, player_ball.y)
            elif event.type == pygame.MOUSEBUTTONUP and aiming:
                aiming = False
                aim_end = event.pos
                dx = aim_end[0] - aim_start[0]
                dy = aim_end[1] - aim_start[1]
                dist = math.hypot(dx, dy)
                if dist > 0:
                    player_ball.speed_x = dx / dist * 5
                    player_ball.speed_y = dy / dist * 5
                player_turn = False

        screen.fill((255, 255, 255))

        # Draw square
        pygame.draw.rect(screen, (0, 0, 0), (SQUARE_X, SQUARE_Y, SQUARE_SIZE, SQUARE_SIZE), 1)

        # Move and draw balls
        for ball in balls:
            ball.move()
            pygame.draw.circle(screen, (255, 0, 0), (int(ball.x), int(ball.y)), BALL_RADIUS)

        # Check collisions
        if not player_turn:
            player_ball.move()
            pygame.draw.circle(screen, (0, 0, 255), (int(player_ball.x), int(player_ball.y)), BALL_RADIUS)
            for ball in balls:
                check_collision(player_ball, ball)
            if (player_ball.x - BALL_RADIUS < SQUARE_X or
                player_ball.x + BALL_RADIUS > SQUARE_X + SQUARE_SIZE or
                player_ball.y - BALL_RADIUS < SQUARE_Y or
                player_ball.y + BALL_RADIUS > SQUARE_Y + SQUARE_SIZE):
                player_turn = True
                # Check if balls are outside square
                for ball in balls[:]:
                    if (ball.x < SQUARE_X or ball.x > SQUARE_X + SQUARE_SIZE or
                        ball.y < SQUARE_Y or ball.y > SQUARE_Y + SQUARE_SIZE):
                        score[0] += 1
                        balls.remove(ball)
                player_ball.x, player_ball.y = WIDTH // 2, HEIGHT - 50
                player_ball.speed_x = 0
                player_ball.speed_y = 0

        # Draw aim line
        if aiming:
            mouse_pos = pygame.mouse.get_pos()
            pygame.draw.line(screen, (0, 0, 255), aim_start, mouse_pos, 2)

        # Draw player ball
        if player_turn:
            pygame.draw.circle(screen, (0, 0, 255), (int(player_ball.x), int(player_ball.y)), BALL_RADIUS)

        # Display score
        font = pygame.font.Font(None, 36)
        text = font.render(f"Score: {score[0]} - {score[1]}", True, (0, 0, 0))
        screen.blit(text, (10, 10))

        pygame.display.flip()
        clock.tick(60)

    pygame.quit()

if __name__ == "__main__":
    main()