from multiprocessing import Process
import time
import random
import pygame
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.core.window import Window

# --------------------------------------------------
# KONFIG
# --------------------------------------------------
SCREEN_W = 800
SCREEN_H = 600

PLAYER_W = 110
PLAYER_H = 65

# Seitliche Bewegung (Schnee)
MAX_SIDE_SPEED = 800
SIDE_ACCEL = 4500
SIDE_FRICTION = 2600

# Vorwärtsbewegung (Gas)
BASE_OBSTACLE_SPEED = 600
MAX_FORWARD_SPEED = 1600
FORWARD_ACCEL = 500
FORWARD_FRICTION = 300

TREE_MIN_W = 60
TREE_MAX_W = 120
TREE_MIN_H = 120
TREE_MAX_H = 200

ROCK_MIN = 20
ROCK_MAX = 50

SPAWN_INTERVAL = 0.9
FONT_SIZE = 22


# --------------------------------------------------
# PYGAME SPIEL
# --------------------------------------------------
def run_pygame():
    global SCREEN_W, SCREEN_H

    pygame.init()
    screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
    SCREEN_W, SCREEN_H = screen.get_size()
    pygame.display.set_caption("Motocross Schnee")

    clock = pygame.time.Clock()
    font = pygame.font.SysFont(None, FONT_SIZE)

    PLAYER_Y = SCREEN_H // 2 - 80
    player_x = SCREEN_W // 2

    # Bewegung
    side_vel = 0
    forward_speed = BASE_OBSTACLE_SPEED

    def load(path, size=None):
        try:
            img = pygame.image.load(path).convert_alpha()
            if size:
                img = pygame.transform.scale(img, size)
            return img
        except:
            return None

    bike_center = load("Kawasaki_Kx_500.png", (PLAYER_W, PLAYER_H))
    bike_left   = load("Kx500_links.png", (PLAYER_W, PLAYER_H))
    bike_right  = load("Kx500_rechts.png", (PLAYER_W, PLAYER_H))

    bg_img   = load("schnee.jpg", (SCREEN_W, SCREEN_H))
    tree_img = load("baum.png")
    rock_img = load("stein.png")

    current_bike = bike_center
    obstacles = []

    last_spawn = 0
    score = 0
    gas_time = 0
    last_time = time.time()
    running = True

    # --------------------------------------------------
    # HINDERNISSE
    # --------------------------------------------------
    def spawn():
        if random.choice([True, False]):  # BAUM
            w = random.randint(TREE_MIN_W, TREE_MAX_W)
            h = random.randint(TREE_MIN_H, TREE_MAX_H)
            x = random.randint(0, SCREEN_W - w)
            y = SCREEN_H + h

            hitbox_w = int(w * 0.18)
            hitbox_h = int(h * 0.12)
            hitbox_x = x + (w - hitbox_w) // 2
            hitbox_y = y + int(h * 0.78)

            obstacles.append({
                "type": "tree",
                "draw": pygame.Rect(x, y, w, h),
                "hit": pygame.Rect(hitbox_x, hitbox_y, hitbox_w, hitbox_h)
            })
        else:  # STEIN
            s = random.randint(ROCK_MIN, ROCK_MAX)
            x = random.randint(0, SCREEN_W - s)
            y = SCREEN_H + s
            obstacles.append({
                "type": "rock",
                "rect": pygame.Rect(x, y, s, s)
            })

    # --------------------------------------------------
    # GAME LOOP
    # --------------------------------------------------
    while running:
        now = time.time()
        dt = now - last_time
        last_time = now

        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                running = False
            if e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:
                running = False

        keys = pygame.key.get_pressed()

        # Seitliche Bewegung (Schnee)
        if keys[pygame.K_LEFT]:
            side_vel -= SIDE_ACCEL * dt
            current_bike = bike_left or bike_center
        elif keys[pygame.K_RIGHT]:
            side_vel += SIDE_ACCEL * dt
            current_bike = bike_right or bike_center
        else:
            if side_vel > 0:
                side_vel -= SIDE_FRICTION * dt
                if side_vel < 0:
                    side_vel = 0
            elif side_vel < 0:
                side_vel += SIDE_FRICTION * dt
                if side_vel > 0:
                    side_vel = 0
            current_bike = bike_center

        side_vel = max(-MAX_SIDE_SPEED, min(MAX_SIDE_SPEED, side_vel))
        player_x += side_vel * dt
        player_x = max(0, min(SCREEN_W - PLAYER_W, player_x))

        # Vorwärtsbeschleunigung (W)
        if keys[pygame.K_w]:
            gas_time += dt
            forward_speed += FORWARD_ACCEL * dt
        else:
            gas_time = 0
            forward_speed -= FORWARD_FRICTION * dt

        forward_speed = max(BASE_OBSTACLE_SPEED,
                            min(MAX_FORWARD_SPEED, forward_speed))

        multiplier = 1.0 if gas_time < 3 else 1.0 + 0.1 * int(gas_time - 3)
        score += 5 * dt * multiplier

        # SPAWN – DOPPELT SO VIELE OBJEKTE
        last_spawn += dt
        if last_spawn >= SPAWN_INTERVAL:
            last_spawn = 0
            spawn()
            spawn()   # 👈 zweites Hindernis

        # Hindernisse bewegen
        for o in obstacles[:]:
            if o["type"] == "tree":
                o["draw"].y -= int(forward_speed * dt)
                o["hit"].y -= int(forward_speed * dt)
                if o["draw"].bottom < 0:
                    obstacles.remove(o)
            else:
                o["rect"].y -= int(forward_speed * dt)
                if o["rect"].bottom < 0:
                    obstacles.remove(o)

        # Kollision
        player_rect = pygame.Rect(int(player_x), PLAYER_Y, PLAYER_W, PLAYER_H)
        for o in obstacles:
            if o["type"] == "tree":
                if o["hit"].colliderect(player_rect):
                    running = False
            else:
                if o["rect"].colliderect(player_rect):
                    running = False

        # Zeichnen
        screen.blit(bg_img, (0, 0))
        screen.blit(current_bike, (player_x, PLAYER_Y))

        for o in obstacles:
            if o["type"] == "tree":
                screen.blit(pygame.transform.scale(tree_img, o["draw"].size), o["draw"])
            else:
                screen.blit(pygame.transform.scale(rock_img, o["rect"].size), o["rect"])

        screen.blit(font.render(f"Punkte: {int(score)}", True, (0, 0, 0)), (20, 20))
        screen.blit(font.render(f"Multiplier: {multiplier:.1f}", True, (0, 0, 0)), (20, 45))
        screen.blit(font.render(f"Speed: {int(forward_speed)}", True, (0, 0, 0)), (20, 70))

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

    pygame.quit()


# --------------------------------------------------
# KIVY MENU
# --------------------------------------------------
class MainMenu(BoxLayout):
    def start_game(self):
        Process(target=run_pygame).start()


class MenuApp(App):
    def build(self):
        Builder.load_file("menu.kv")
        Window.size = (480, 360)
        return MainMenu()


if __name__ == "__main__":
    MenuApp().run()
