import pygame
import random

pygame.init()

# Window settings
width = 700
height = 600
win = pygame.display.set_mode((width, height))
pygame.display.set_caption("Car Game")  # Updated title

# Colors
ASPHALT = (50, 50, 50)
WHITE = (255, 255, 255)
YELLOW = (255, 255, 0)
ROAD_EDGE = (180, 180, 180)
BLACK = (0, 0, 0)
BLUE = (0, 0, 255)

# Road and lanes
road_left = 100
road_right = 600
lane_count = 5
lane_width = (road_right - road_left) // lane_count
lanes = [road_left + i * lane_width + lane_width // 2 for i in range(lane_count)]  # center x of each lane

# Car settings (hitbox dimensions)
car_width = 70  # Player car hitbox width
car_height = 140  # Player car hitbox height
car_lane = 2  # Start in the middle lane
car_x = lanes[car_lane] - car_width // 2  # Current x position
car_target_x = car_x  # Target x position for smooth movement
car_y = height - car_height - 10
car_speed = 10  # Speed of smooth movement (pixels per frame)

# Obstacle settings (hitbox dimensions)
obstacle_width = 70  # Obstacle car hitbox width
obstacle_height = 120  # Obstacle car hitbox height
obstacles = [
    {"lane": random.randint(0, lane_count - 1), "y": -obstacle_height},
    {"lane": random.randint(0, lane_count - 1), "y": -obstacle_height - 200},  # Second car starts farther away
]
obstacle_speed = 5  # Initial speed
third_obstacle_added = False  # Flag for adding a third obstacle
fourth_obstacle_added = False  # Flag for adding a fourth obstacle

# Visual dimensions (for rendering only)
visual_car_width = 120  # Player car appears thicker
visual_obstacle_width = 170  # Obstacle car appears thinner

# Load car images with updated visual dimensions
player_car_img = pygame.image.load("car_player.png")  # Replace with the path to your player's car image
player_car_img = pygame.transform.scale(player_car_img, (visual_car_width, car_height))

obstacle_car_img = pygame.image.load("car_obstacle.png")  # Replace with the path to your obstacle car image
obstacle_car_img = pygame.transform.scale(obstacle_car_img, (visual_obstacle_width, obstacle_height))

clock = pygame.time.Clock()
font = pygame.font.Font(pygame.font.match_font('arial'), 36)  # Stylish font
title_font = pygame.font.Font(pygame.font.match_font('arial'), 72)

# Game variables
run = True
menu_active = True
score = 0
line_offset = 0  # Offset for moving dashed lines

def draw_highway():
    # Draw the asphalt background
    win.fill(ASPHALT)

    # Draw road edges (shoulders)
    pygame.draw.rect(win, ROAD_EDGE, (road_left - 20, 0, 20, height))  # Left shoulder
    pygame.draw.rect(win, ROAD_EDGE, (road_right, 0, 20, height))  # Right shoulder

    # Draw the road itself
    pygame.draw.rect(win, ASPHALT, (road_left, 0, road_right - road_left, height))  # Road area

    # Draw solid white lines for highway boundaries
    pygame.draw.line(win, WHITE, (road_left, 0), (road_left, height), 4)  # Left boundary
    pygame.draw.line(win, WHITE, (road_right, 0), (road_right, height), 4)  # Right boundary

    # Draw moving dashed yellow lane dividers
    global line_offset
    line_offset = (line_offset + 5) % 40  # Speed of lane line movement
    for i in range(1, lane_count):
        lane_x = road_left + i * lane_width
        for y in range(-line_offset, height, 40):
            pygame.draw.rect(win, YELLOW, (lane_x - 2, y, 4, 20))

def draw_game():
    draw_highway()
    visual_car_x = car_x - (visual_car_width - car_width) // 2  # Adjust visual car to match hitbox

    win.blit(player_car_img, (visual_car_x, car_y))  # Draw player's car

    # Draw obstacles
    for obstacle in obstacles:
        obstacle_x = lanes[obstacle["lane"]] - visual_obstacle_width // 2
        win.blit(obstacle_car_img, (obstacle_x, obstacle["y"]))

    # Display the score
    score_text = font.render(f"Score: {score}", True, WHITE)
    win.blit(score_text, (10, 10))

def main_menu():
    global menu_active, obstacles, score, third_obstacle_added, fourth_obstacle_added

    while menu_active:
        clock.tick(60)

        # Update the background gameplay
        for obstacle in obstacles:
            obstacle["y"] += obstacle_speed
            if obstacle["y"] > height:
                obstacle["y"] = -obstacle_height
                obstacle["lane"] = random.randint(0, lane_count - 1)

        # Draw the game in the background
        draw_game()

        # Draw menu overlay
        title_text = title_font.render("Car Game", True, WHITE)  # Game title
        play_text = font.render("Play", True, WHITE)

        # Play button dimensions and position
        play_button_rect = pygame.Rect(width // 2 - 100, 300, 200, 50)  # (x, y, width, height)

        # Draw title and button
        win.blit(title_text, (width // 2 - title_text.get_width() // 2, 100))
        pygame.draw.rect(win, BLUE, play_button_rect)  # Draw button rectangle
        win.blit(play_text, (play_button_rect.x + play_button_rect.width // 2 - play_text.get_width() // 2,
                             play_button_rect.y + play_button_rect.height // 2 - play_text.get_height() // 2))
        pygame.display.update()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if play_button_rect.collidepoint(event.pos):  # Check if mouse click is inside the button
                    score = 0  # Reset score when game starts
                    obstacles = [
                        {"lane": random.randint(0, lane_count - 1), "y": -obstacle_height},
                        {"lane": random.randint(0, lane_count - 1), "y": -obstacle_height - 200},
                    ]
                    third_obstacle_added = False
                    fourth_obstacle_added = False
                    menu_active = False  # Exit the menu and start the game

# Main loop
main_menu()  # Display the main menu
while run:
    clock.tick(60)

    # Increase obstacle speed as score increases
    obstacle_speed = 5 + (score // 10)

    # Add a third obstacle when the score reaches 10
    if score >= 10 and not third_obstacle_added:
        obstacles.append({"lane": random.randint(0, lane_count - 1), "y": -obstacle_height - 400})
        third_obstacle_added = True

    # Add a fourth obstacle when the score reaches 20
    if score >= 20 and not fourth_obstacle_added:
        obstacles.append({"lane": random.randint(0, lane_count - 1), "y": -obstacle_height - 600})
        fourth_obstacle_added = True

    draw_game()
    pygame.display.update()

    # Update obstacles
    for obstacle in obstacles:
        obstacle["y"] += obstacle_speed
        if obstacle["y"] > height:
            obstacle["y"] = -obstacle_height
            obstacle["lane"] = random.randint(0, lane_count - 1)
            score += 1  # Increase score when an obstacle resets

    # Smoothly move the car towards the target x position
    if car_x < car_target_x:
        car_x += min(car_speed, car_target_x - car_x)
    elif car_x > car_target_x:
        car_x -= min(car_speed, car_x - car_target_x)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        elif event.type == pygame.KEYDOWN:  # Detect key press
            if event.key == pygame.K_LEFT and car_lane > 0:
                car_lane -= 1
                car_target_x = lanes[car_lane] - car_width // 2
            elif event.key == pygame.K_RIGHT and car_lane < lane_count - 1:
                car_lane += 1
                car_target_x = lanes[car_lane] - car_width // 2

    # Check for collisions
    car_rect = pygame.Rect(car_x, car_y, car_width, car_height)
    for obstacle in obstacles:
        obstacle_x = lanes[obstacle["lane"]] - obstacle_width // 2
        
        # Adjust obstacle hitbox to be smaller (20% of original size)
        obstacle_hitbox_width = obstacle_width * 0.2
        obstacle_hitbox_height = obstacle_height * 0.2
        obstacle_hitbox_x = obstacle_x + (obstacle_width - obstacle_hitbox_width) // 2
        obstacle_hitbox_y = obstacle["y"] + (obstacle_height - obstacle_hitbox_height) // 2

        obstacle_rect = pygame.Rect(
            obstacle_hitbox_x, obstacle_hitbox_y, obstacle_hitbox_width, obstacle_hitbox_height
        )

        if car_rect.colliderect(obstacle_rect):
            run = False  # End the game on collision i have made 4 car_obstacles going from 1 4 make 4 diffrent car models show up