#!/usr/bin/env python
# coding: utf-8

"""Exercise 5: Sprites, Groups & Mouse Click

The lecture introduced pygame.sprite.Sprite and sprite Groups.
This exercise also adds mouse input (requested by several of you!) because
click-to-interact, picking a grocery item, selecting an NPC, answering a quiz,
is the interaction model for most of your game designs.
The scene: colourful "collectible" circles fall from the top of the screen.
The player clicks them to collect them before they leave the bottom.

Your task:
    Part A: Complete the Collectible sprite class:
    1. Give it a random x position and start it at y = 0.
    2. In update(), move it downward by FALL_SPEED each frame.
        If it goes below the screen, remove it from all groups (self.kill()).
    Part B: Spawn and click:
    3. Every SPAWN_INTERVAL milliseconds, add a new Collectible to `all_sprites`.
        HINT: use pygame.time.get_ticks() to track elapsed time.
    4. On a left mouse-button click, check each sprite to see if the click
        position is inside the sprite's rect. If so, call sprite.kill() and
        increment `score`.
        HINT: event.dict["pos"] gives the (x, y) of the click.
        sprite.rect.collidepoint(pos)  returns True if the point is inside.
    Part C: Display the score (text):
    5. Render and blit the score string "Score: X" in the top-left corner.

This is the same pattern as bubble_pop.py from the minigame set, but now
using proper Sprite objects so you can see the difference or on-board (if your
chosen mini-game was not Bubble Pop.

Reference:
  https://www.pygame.org/docs/ref/sprite.html
"""

import pygame
import random

pygame.init()

WIDTH, HEIGHT  = 500, 550
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Exercise 5: Sprites & Mouse")

BACKGROUND = ( 20,  20,  40)
TEXT_COLOUR = (255, 255, 255)
FALL_SPEED = 2 # pixels per frame
RADIUS = 22
SPAWN_INTERVAL = 1200 # milliseconds between new collectibles

pygame.font.init()
font = pygame.font.Font(None, 36)

# color pool for variety
COLOURS = [
    (255, 80, 80), # red
    (80, 200, 80), # green
    (80, 150, 255), # blue
    (255, 200, 50), # yellow
    (200, 80, 255), # purple
]

class Collectible(pygame.sprite.Sprite):
    """ A falling circle that the player clicks to collect. """
    def __init__(self):
        super().__init__()

        self.colour = random.choice(COLOURS)
        # TODO A-1: Create a square Surface of size (RADIUS*2) × (RADIUS*2).
        #   Fill it with a transparent colour first, then draw a filled circle on it.
        # HINT:
        #       self.image = pygame.Surface((RADIUS * 2, RADIUS * 2), pygame.SRCALPHA)
        #       pygame.draw.circle(self.image, self.colour, (RADIUS, RADIUS), RADIUS)
        self.image = None  # replace with your solution, this is a placeholder ^^

        # TODO A-2: Set self.rect using self.image.get_rect().
        #   Position the sprite: random x in [RADIUS, WIDTH - RADIUS], y = -RADIUS
        #   (starts just above the visible screen so it "enters" from the top).
        # HINT:
        #       self.rect = self.image.get_rect()
        #       self.rect.x = random.randint(RADIUS, WIDTH - RADIUS)
        #       self.rect.y = -RADIUS
        self.rect = None  # replace with your solution, this is a placeholder ^^

    def update(self):
        # TODO A-3: Move the sprite downward by FALL_SPEED each frame.
        #   If the top of the sprite has passed the bottom of the screen, kill it.
        # HINT:
        #       self.rect.y += FALL_SPEED
        #       if self.rect.top > HEIGHT: self.kill()
        pass  # replace with your solution, this is a placeholder ^^


# set up
all_sprites = pygame.sprite.Group()
score = 0
last_spawn = pygame.time.get_ticks() # milliseconds since pygame.init()

clock = pygame.time.Clock()
running = True

while running:
    clock.tick(60)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
            running = False
        # TODO B-4: Handle a left mouse button click (pygame.MOUSEBUTTONDOWN, button 1).
        #   For each sprite in all_sprites, check if the click position is inside its rect.
        #   If yes, kill the sprite and add 1 to score.
        # HINT:
        #       if event.type == pygame.MOUSEBUTTONDOWN and event.dict["button"] == 1:
        #           pos = event.dict["pos"]
        #           for sprite in list(all_sprites):   # list() avoids modifying group mid-loop
        #               if sprite.rect.collidepoint(pos):
        #                   sprite.kill()
        #                   score += 1


    # TODO B-3: Spawn a new Collectible every SPAWN_INTERVAL milliseconds.
    # HINT:
    #     now = pygame.time.get_ticks()
    #     if now - last_spawn >= SPAWN_INTERVAL:
    #         all_sprites.add(Collectible())
    #         last_spawn = now


    # update & draw part
    all_sprites.update()

    screen.fill(BACKGROUND)
    all_sprites.draw(screen)

    # TODO C-5: Render the string f"Score: {score}" and blit it at position (10, 10).
    # HINT:
    #   score_surf = font.render(f"Score: {score}", True, TEXT_COLOUR)
    #   screen.blit(score_surf, (10, 10))

    pygame.display.flip()
pygame.quit()
