import pyxel
import random

# ============================================================
#  ARIEL – DSCHUNGEL ABENTEUER  |  KOMPLETT (Tutorial + Intro + Spiel)
# ============================================================


# ============================================================
#  TUTORIAL-SZENE  (neu – erscheint VOR dem Intro)
# ============================================================
class ArielDschungelTutorial:
    def __init__(self, on_done):
        self.on_done = on_done
        self.f = 0
        self.page = 0          # Seite 0 oder 1
        self.blink = 0
        # Kleine Demo-Animation
        self.demo_y = 90.0
        self.demo_jumping = False
        self.demo_jump_v = 0.0
        self.demo_ducking = False
        self.demo_timer = 0
        self.demo_phase = 0    # 0=laufen, 1=springen, 2=ducken, 3=portal

    def update(self):
        self.f += 1
        self.blink = (self.f // 18) % 2

        # Demo-Animation automatisch durchspielen
        self.demo_timer += 1
        phases = [60, 60, 60, 80]
        if self.demo_phase < len(phases) and self.demo_timer > phases[self.demo_phase]:
            self.demo_phase = (self.demo_phase + 1) % len(phases)
            self.demo_timer = 0
            self.demo_ducking = False

        if self.demo_phase == 1 and self.demo_timer == 5:
            self.demo_jumping = True
            self.demo_jump_v  = 6.0
        if self.demo_phase == 2 and self.demo_timer > 10:
            self.demo_ducking = True

        if self.demo_jumping:
            self.demo_y -= self.demo_jump_v
            self.demo_jump_v -= 0.4
            if self.demo_y >= 90:
                self.demo_y = 90.0
                self.demo_jumping = False
                self.demo_jump_v  = 0.0

        # Weiter mit ENTER, SPACE oder Pfeiltaste rechts
        if pyxel.btnp(pyxel.KEY_RETURN) or pyxel.btnp(pyxel.KEY_SPACE) \
                or pyxel.btnp(pyxel.KEY_RIGHT):
            if self.page == 0:
                self.page = 1
                self.f = 0
            else:
                self.on_done()

    # ---------- Hilfsfunktion: Ariel mini ----------
    def _draw_ariel(self, x, y, ducking=False, special=False):
        x, y = int(x), int(y)
        if ducking:
            pyxel.rect(x-3, y+4, 14, 4, 8)
            pyxel.rect(x,   y+4, 8,  6, 15)
            pyxel.pset(x+2, y+5, 0); pyxel.pset(x+5, y+5, 0)
            pyxel.rect(x+3, y+9, 2, 1, 14)
            pyxel.rect(x,   y+10, 8, 3, 12)
        else:
            pyxel.rect(x-3, y-6, 14, 6,  8)
            pyxel.rect(x-3, y,   3,  12, 8)
            pyxel.rect(x+8, y,   3,  12, 8)
            pyxel.rect(x,   y,   8,  10, 15)
            pyxel.pset(x+2, y+2, 0)
            pyxel.pset(x+5, y+2, 0)
            pyxel.rect(x+3, y+7, 2, 1, 14)
            pyxel.rect(x, y+10, 8, 5, 12)

    # ---------- Kaktus (Hindernis Typ 0) ----------
    def _draw_cactus(self, x, y):
        pyxel.rect(x+2, y-2, 2, 12, 3)
        pyxel.rect(x,   y+2, 6, 8,  3)
        pyxel.pset(x+1, y+1, 0); pyxel.pset(x+4, y, 0)
        pyxel.rectb(x, y+2, 6, 8, 0)

    # ---------- Liane (Hindernis Typ 1 – Ducken) ----------
    def _draw_log(self, x, y):
        pyxel.rect(x, y, 14, 6, 2)
        pyxel.rect(x, y, 14, 1, 1)
        pyxel.rectb(x, y, 14, 6, 0)

    # ---------- Stern ----------
    def _draw_star(self, x, y):
        pyxel.pset(x+3, y,   10); pyxel.pset(x+3, y+1, 10)
        pyxel.rect(x,   y+2, 7, 1, 10)
        pyxel.rect(x+1, y+3, 5, 1, 10)
        pyxel.pset(x,   y+4, 10); pyxel.pset(x+2, y+4, 10)
        pyxel.pset(x+4, y+4, 10); pyxel.pset(x+6, y+4, 10)

    # ---------- Portal ----------
    def _draw_portal(self, x, y):
        pr = 7
        pyxel.circ(x, y, pr,     11)
        pyxel.circ(x, y, pr - 3, 3)
        pyxel.circ(x, y, pr - 5, 0)
        pyxel.pset(x, y, 7)

    def draw(self):
        pyxel.cls(0)
        f = self.f

        # ── Hintergrund: Dschungel-Streifen ──────────────────
        pyxel.rect(0, 0, 160, 120, 3)
        pyxel.rect(0, 95, 160, 25, 13)
        for gx in range(0, 160, 2):
            pyxel.pset(gx, 94 - ((gx*3 + f//4) % 3), 11)

        # Bäume links + rechts als Rahmen
        for tx, ty in [(0, 30), (148, 25)]:
            pyxel.rect(tx, ty, 4, 100, 4)
            pyxel.circ(tx+2, ty, 12, 3)
            pyxel.circ(tx+2, ty-4, 7, 11)

        # ── Rahmen ───────────────────────────────────────────
        pyxel.rectb(8,  4,  144, 112, 10)
        pyxel.rectb(9,  5,  142, 110, 14)
        pyxel.rectb(10, 6,  140, 108, 11)

        # ── Seite 0: Steuerung & Ziel ─────────────────────────
        if self.page == 0:
            # Titel
            pyxel.rect(14, 9, 132, 11, 0)
            pyxel.text(16, 11, "ARIEL  IM  DSCHUNGELCAMP", 10)

            pyxel.text(14, 24, "ZIEL:", 14)
            pyxel.text(14, 31, "Komm als Dschungelkoenigin", 7)
            pyxel.text(14, 38, "ans Ziel - weiche Hindernissen", 7)
            pyxel.text(14, 45, "aus und loese Raetsel!", 7)

            # Trennlinie
            pyxel.line(14, 53, 146, 53, 11)

            pyxel.text(14, 56, "STEUERUNG:", 14)

            # SPACE → Springen
            pyxel.rect(14, 63, 44, 8, 13)
            pyxel.rectb(14, 63, 44, 8, 7)
            pyxel.text(15, 65, "LEERTASTE", 0)
            pyxel.text(60, 65, "=  SPRINGEN", 7)

            # DOWN → Ducken
            pyxel.rect(14, 74, 44, 8, 1)
            pyxel.rectb(14, 74, 44, 8, 7)
            pyxel.text(15, 76, "PFEIL UNTEN", 0)
            pyxel.text(60, 76, "=  DUCKEN", 7)

            # X → Superpower
            pyxel.rect(14, 85, 44, 8, 9)
            pyxel.rectb(14, 85, 44, 8, 7)
            pyxel.text(22, 87, "TASTE  X", 0)
            pyxel.text(60, 87, "=  SUPERPOWER", 7)

            pyxel.text(60, 95, "(wenn Leiste voll!)", 5)

            # Weiter-Hinweis
            if self.blink:
                pyxel.text(22, 106, "ENTER / SPACE  ->  Weiter", 10)

        # ── Seite 1: Hindernisse, Tipps, Demo ─────────────────
        else:
            pyxel.rect(14, 9, 132, 11, 0)
            pyxel.text(20, 11, "HINDERNISSE  &  TIPPS", 14)

            # --- Kaktus ---
            self._draw_cactus(14, 24)
            pyxel.rectb(12, 22, 12, 14, 8)
            pyxel.text(28, 24, "Kaktus / Hindernis:", 7)
            pyxel.text(28, 31, "SPRINGEN um drueber", 10)
            pyxel.text(28, 38, "hinwegzukommen!", 10)

            # --- Ast/Liane ---
            self._draw_log(14, 52)
            pyxel.rectb(12, 50, 18, 10, 8)
            pyxel.text(34, 52, "Ast / fliegendes Hindernis:", 7)
            pyxel.text(34, 59, "DUCKEN um drunter durch!", 10)

            # --- Stern ---
            self._draw_star(14, 67)
            pyxel.text(24, 69, "Stern sammeln  ->  +25 Punkte", 10)
            pyxel.text(24, 76, "und ladet Superpower auf!", 14)

            # --- Portal ---
            self._draw_portal(18, 88)
            pyxel.text(28, 84, "Portal = Raetsel!", 9)
            pyxel.text(28, 91, "Mathe loesen (Ziffern tippen)", 7)
            pyxel.text(28, 98, "oder Buchstaben-Folge merken.", 7)

            # --- Demo-Animation am Boden ---
            demo_x = 75
            # Demo-Ariel
            if self.demo_phase == 2 and self.demo_ducking:
                self._draw_ariel(demo_x, int(self.demo_y), ducking=True)
            else:
                self._draw_ariel(demo_x, int(self.demo_y))

            # Demo-Hindernis je nach Phase
            if self.demo_phase == 1:
                self._draw_cactus(demo_x + 35, 88)
                pyxel.text(demo_x - 18, 82, "-> SPRINGEN!", 10)
            elif self.demo_phase == 2:
                self._draw_log(demo_x + 30, 83)
                pyxel.text(demo_x - 18, 82, "-> DUCKEN!", 9)
            elif self.demo_phase == 3:
                self._draw_portal(demo_x + 40, 90)
                pyxel.text(demo_x - 18, 82, "-> RAETSEL!", 11)

            # Weiter-Hinweis
            if self.blink:
                pyxel.text(14, 107, "ENTER / SPACE  ->  Spiel starten!", 10)


# ============================================================
#  INTRO-SZENE
# ============================================================
class ArielDschungelIntro:
    def __init__(self, on_done):
        self.on_done = on_done
        self._setup()

    def _setup(self):
        self.f = 0
        self.done = False
        self.phase = 0
        self.phase_timer = 0

        self.world_offset = 0.0

        self.ariel_x = -20.0
        self.ariel_y = 90.0
        self.ariel_target = 55.0
        self.ariel_vx = 0.0
        self.ariel_vy = 0.0
        self.ariel_pushed = False
        self.push_done = False

        self.gil_x = 200.0
        self.gil_y = 90.0
        self.gil_arm_up = False

        self.bubble_visible = False
        self.lie_text = ["Aligreta ist", "haesslich!"]
        self.lie_cross_visible = False

        self.banner_y = -30.0
        self.banner_bounce = 0

        self.welcome_y = 200.0

        self.bg_ropes = []
        for i in range(12):
            self.bg_ropes.append([i * 80 + random.randint(0, 40),
                                   random.randint(0, 15),
                                   random.randint(20, 40)])
        self.bg_flowers = []
        for i in range(30):
            self.bg_flowers.append([i * 18 + random.randint(-5, 5),
                                     random.randint(93, 99),
                                     random.choice([8, 9, 10, 14])])
        self.trees = []
        for i in range(20):
            self.trees.append([i * 30,
                                random.randint(20, 50),
                                random.choice([2, 3, 4, 11])])

        self.animals = []
        for _ in range(4):
            self.animals.append({"type": "bird",
                "x": random.randint(0, 800), "y": random.randint(12, 45),
                "frame": random.randint(0, 10), "dir": random.choice([-1, 1]),
                "speed": random.uniform(0.5, 1.0)})
        for _ in range(3):
            self.animals.append({"type": "butterfly",
                "x": random.randint(0, 500), "y": random.randint(40, 70),
                "frame": random.randint(0, 8), "dir": random.choice([-1, 1]),
                "speed": random.uniform(0.3, 0.6)})
        for _ in range(3):
            self.animals.append({"type": "monkey",
                "x": random.randint(50, 700), "y": random.randint(25, 45),
                "frame": random.randint(0, 20), "dir": random.choice([-1, 1]),
                "speed": random.uniform(0.3, 0.6)})

        self.glitter = [[random.randint(5, 155),
                          random.randint(60, 85),
                          random.randint(0, 30)] for _ in range(12)]
        self.particles = []

    def _set_phase(self, p):
        self.phase = p
        self.phase_timer = 0

    def update(self):
        self.f += 1
        self.phase_timer += 1

        if pyxel.btnp(pyxel.KEY_RETURN) or pyxel.btnp(pyxel.KEY_SPACE):
            self.done = True
            self.on_done()
            return

        self.world_offset += 0.35
        self._update_animals()
        for g in self.glitter:
            g[2] += 1

        if self.phase == 0:
            if self.ariel_x < self.ariel_target:
                self.ariel_x += 1.8
            else:
                self.ariel_x = self.ariel_target
                if self.phase_timer > 30:
                    self._set_phase(1)

        elif self.phase == 1:
            target = 98.0
            if self.gil_x > target:
                self.gil_x -= 1.5
            else:
                self.gil_x = target
                if self.phase_timer > 40:
                    self._set_phase(2)

        elif self.phase == 2:
            self.bubble_visible = True
            if self.phase_timer > 90:
                self.lie_cross_visible = True
            if self.phase_timer > 130:
                if not self.particles:
                    for _ in range(18):
                        self.particles.append({
                            "x": float(int(self.gil_x) - 20),
                            "y": 70.0,
                            "vx": random.uniform(-2.5, 2.5),
                            "vy": random.uniform(-3.0, 0.5),
                            "c": random.choice([8, 9, 10, 14, 7]),
                            "life": random.randint(15, 35)
                        })
                self._set_phase(3)

        elif self.phase == 3:
            if self.banner_y < 35:
                self.banner_y += 4
            else:
                self.banner_y = 35
                self.banner_bounce = max(0, self.banner_bounce - 1)

            for p in self.particles:
                p["x"] += p["vx"]
                p["y"] += p["vy"]
                p["vy"] += 0.15
                p["life"] -= 1
            self.particles = [p for p in self.particles if p["life"] > 0]

            if self.phase_timer == 40:
                self.gil_arm_up = True
                self.ariel_vy = -3.5
                self.ariel_vx = -2.8
                self.ariel_pushed = True

            if self.ariel_pushed:
                self.ariel_x += self.ariel_vx
                self.ariel_y += self.ariel_vy
                self.ariel_vy += 0.4
                if self.ariel_y >= 90:
                    self.ariel_y = 90.0
                    self.ariel_vy = 0.0
                    self.ariel_vx = 0.0
                    self.ariel_pushed = False
                    self.push_done = True

            if self.push_done and self.phase_timer > 90:
                self._set_phase(4)

        elif self.phase == 4:
            if self.ariel_x < 60:
                self.ariel_x += 1.2
            self.gil_x += 1.0
            self.gil_arm_up = False
            if self.phase_timer > 70:
                self._set_phase(5)

        elif self.phase == 5:
            if self.welcome_y > 75:
                self.welcome_y -= 4
            else:
                self.welcome_y = 75
            if self.phase_timer > 80:
                self._set_phase(6)

    def _update_animals(self):
        f = self.f
        for a in self.animals:
            a["frame"] += 1
            t = a["type"]
            if t in ("bird", "butterfly"):
                a["x"] += a["dir"] * a["speed"]
                sx = a["x"] - self.world_offset
                if sx < -20 or sx > 180:
                    a["dir"] *= -1
                if t == "butterfly":
                    a["y"] += pyxel.sin(f * 5 + a["x"] * 0.1) * 0.4
                    a["y"] = max(35, min(78, a["y"]))
            elif t == "monkey":
                a["x"] += a["dir"] * a["speed"] * 0.5
                sx = a["x"] - self.world_offset
                if sx < -10 or sx > 175:
                    a["dir"] *= -1

    def _draw_monkey(self, x, y, frame):
        bob = 1 if (frame // 8) % 2 == 0 else 0
        y = int(y) + bob; x = int(x)
        pyxel.pset(x+7, y+3, 4); pyxel.pset(x+8, y+2, 4)
        pyxel.pset(x+9, y+1, 4); pyxel.pset(x+9, y,   9)
        pyxel.rect(x+1, y,   6, 5, 4)
        pyxel.rect(x+2, y+1, 4, 3, 9)
        pyxel.rect(x+1, y-4, 5, 4, 4)
        pyxel.pset(x+2, y-3, 0); pyxel.pset(x+4, y-3, 0)
        pyxel.pset(x+3, y-2, 9)
        pyxel.pset(x,   y-3, 4); pyxel.pset(x+6, y-3, 4)
        arm = (frame // 5) % 2
        pyxel.pset(x,   y+1 if arm == 0 else y+2, 4)
        pyxel.pset(x+7, y+2 if arm == 0 else y+1, 4)
        pyxel.pset(x+2, y+5, 4); pyxel.pset(x+4, y+5, 4)

    def _draw_bird(self, x, y, frame):
        x, y = int(x), int(y)
        wing = (frame // 4) % 2
        pyxel.rect(x+1, y+1, 4, 3, 7)
        pyxel.rect(x+3, y-1, 3, 3, 7)
        pyxel.pset(x+5, y-1, 0); pyxel.pset(x+6, y, 9)
        pyxel.pset(x,   y+2, 13); pyxel.pset(x-1, y+3, 13)
        if wing == 0:
            pyxel.rect(x+1, y,   4, 1, 12); pyxel.pset(x, y-1, 12)
        else:
            pyxel.rect(x+1, y+3, 4, 1, 12); pyxel.pset(x, y+4, 12)

    def _draw_butterfly(self, x, y, frame):
        x, y = int(x), int(y)
        wing = (frame // 3) % 2
        c1, c2 = 14, 9
        pyxel.pset(x+2, y, 0); pyxel.pset(x+2, y+1, 0); pyxel.pset(x+2, y+2, 0)
        if wing == 0:
            pyxel.pset(x,   y,   c1); pyxel.pset(x+1, y,   c1)
            pyxel.pset(x,   y+1, c1); pyxel.pset(x+1, y+1, c2)
            pyxel.pset(x+3, y,   c1); pyxel.pset(x+4, y,   c1)
            pyxel.pset(x+3, y+1, c2); pyxel.pset(x+4, y+1, c1)
        else:
            pyxel.pset(x+1, y, c1); pyxel.pset(x+1, y+1, c2)
            pyxel.pset(x+3, y, c1); pyxel.pset(x+3, y+1, c2)

    def draw_ariel(self, x, y, special=False):
        x, y = int(x), int(y)
        pyxel.rect(x-3, y-6, 14, 6,  8)
        pyxel.rect(x-3, y,   3,  12, 8)
        pyxel.rect(x+8, y,   3,  12, 8)
        pyxel.rect(x,   y,   8,  10, 15)
        pyxel.pset(x+2, y+2, 0)
        pyxel.pset(x+5, y+2, 0)
        pyxel.rect(x+3, y+7, 2, 1, 14)
        c = self.f % 16 if special else 12
        pyxel.rect(x, y+10, 8, 5, c)

    def draw_gil(self, x, y, arm_up=False, walking=False):
        x, y = int(x), int(y)
        f = self.f
        pyxel.rect(x,   y-4, 8,  4,  4)
        pyxel.pset(x-1, y-3, 4)
        pyxel.pset(x+8, y-3, 4)
        pyxel.rect(x,   y,   8,  10, 15)
        pyxel.pset(x+2, y-1, 0); pyxel.pset(x+3, y-2, 0)
        pyxel.pset(x+5, y-2, 0); pyxel.pset(x+6, y-1, 0)
        pyxel.pset(x+2, y+2, 0); pyxel.pset(x+5, y+2, 0)
        pyxel.pset(x+2, y+6, 0); pyxel.pset(x+3, y+7, 0)
        pyxel.pset(x+4, y+7, 0); pyxel.pset(x+5, y+6, 0)
        pyxel.rect(x, y+10, 8, 5, 1)
        if arm_up:
            pyxel.rect(x+8, y,   3,  8,  9)
            pyxel.pset(x+10, y-1, 9)
            pyxel.rect(x-3, y+2,  3,  8,  9)
        else:
            arm_swing = (f // 6) % 2 if walking else 0
            pyxel.rect(x-3, y+2 + arm_swing,     3, 8, 9)
            pyxel.rect(x+8, y+2 + (1-arm_swing),  3, 8, 9)
        pyxel.rect(x,   y+15, 4, 2, 0)
        pyxel.rect(x+4, y+15, 4, 2, 0)

    def draw_speech_bubble(self, x, y, lines, show_cross):
        bx, by = x - 48, y - 40
        bw, bh = 58, 26
        pyxel.rect(bx+2, by+2, bw, bh, 1)
        pyxel.rect(bx,   by,   bw, bh, 7)
        pyxel.rectb(bx,  by,   bw, bh, 0)
        pyxel.pset(bx+bw-8, by+bh,   0)
        pyxel.pset(bx+bw-7, by+bh+1, 0)
        pyxel.pset(bx+bw-8, by+bh+1, 7)
        pyxel.pset(bx+bw-6, by+bh+2, 0)
        pyxel.pset(bx+bw-7, by+bh+2, 7)
        pyxel.pset(bx+bw-8, by+bh+2, 7)
        for i, line in enumerate(lines):
            pyxel.text(bx+4, by+5 + i*9, line, 0)
        if show_cross:
            pyxel.rect(bx,  by,  bw, bh, 8)
            pyxel.rectb(bx, by,  bw, bh, 0)
            for i in range(bh - 2):
                lx1 = bx + 2 + int(i * (bw-4) / (bh-2))
                lx2 = bx + bw - 3 - int(i * (bw-4) / (bh-2))
                ly  = by + 1 + i
                if 0 <= lx1 < 160: pyxel.pset(lx1, ly, 7)
                if 0 <= lx2 < 160: pyxel.pset(lx2, ly, 7)
            pyxel.text(bx+8, by+9, "GELOGEN!", 7)

    def draw_glitter(self, x, y, t):
        phase = (t // 4) % 4
        c = [10, 7, 14, 9][phase]
        pyxel.pset(x,   y-1, c); pyxel.pset(x-1, y, c)
        pyxel.pset(x,   y,   7); pyxel.pset(x+1, y, c)
        pyxel.pset(x,   y+1, c)

    def draw(self):
        f = self.f
        pyxel.cls(3)

        for i in range(12):
            bx = (i * 45 - int(self.world_offset * 0.15)) % 200 - 20
            by = 40 + (i % 3) * 8
            pyxel.rect(bx+2, by, 3, 100-by, 4)
            pyxel.circ(bx+3, by, 13, 4)
            pyxel.circ(bx+3, by, 10, 3)
            pyxel.pset(bx+5, by+4, 9); pyxel.pset(bx+1, by+6, 9)

        for rope in self.bg_ropes:
            rx = int((rope[0] - self.world_offset * 0.3) % 300 - 30)
            ry_top = rope[1]; rl = rope[2]
            sway = int(pyxel.sin(f * 1 + rope[0] * 0.03) * 2)
            for ry in range(ry_top, ry_top + rl):
                px = rx + sway
                if 0 <= px < 160: pyxel.pset(px, ry, 4)
                if ry % 5 == 0:
                    if 0 <= px-1 < 160: pyxel.pset(px-1, ry, 3)
                    if 0 <= px+1 < 160: pyxel.pset(px+1, ry, 3)

        for fl in self.bg_flowers:
            fx = int((fl[0] - self.world_offset * 0.6) % 220 - 10)
            if 0 <= fx < 160:
                pyxel.pset(fx, fl[1], 11); pyxel.pset(fx, fl[1]-1, 11)
                pyxel.pset(fx-1, fl[1]-2, fl[2]); pyxel.pset(fx+1, fl[1]-2, fl[2])
                pyxel.pset(fx,   fl[1]-3, fl[2]); pyxel.pset(fx,   fl[1]-2, 7)

        for t in self.trees:
            tx = int((t[0] - self.world_offset * 0.4) % 200 - 20)
            ty = t[1]; tc = t[2]
            if -15 <= tx <= 165:
                pyxel.rect(tx, ty, 4, 120-ty, 4)
                for rty in range(ty, 100, 4): pyxel.pset(tx+1, rty, 9)
                pyxel.circ(tx+2, ty, 10, 3)
                pyxel.circ(tx+4, ty-3, 6, tc)
                for li in range(-8, 8, 3):
                    for lj in range(-8, 8, 3):
                        if li*li + lj*lj < 60:
                            lx2, ly2 = tx+2+li, ty+lj
                            if 0 <= lx2 < 160 and 0 <= ly2 < 100:
                                if (li + lj) % 5 == 0: pyxel.pset(lx2, ly2, 11)

        pyxel.rect(0, 100, 160, 20, 13)
        for gx in range(0, 160, 2):
            gh = ((gx * 3 + f // 4) % 3)
            pyxel.pset(gx, 99-gh, 11)
        for gx in range(0, 160, 7):
            wgx = (gx + int(self.world_offset)) % 160
            if wgx % 14 < 5: pyxel.rect(gx, 103, 5, 2, 4)

        for a in self.animals:
            ax = int(a["x"] - self.world_offset)
            ay = int(a["y"])
            if -15 <= ax <= 165:
                t = a["type"]
                fr = a["frame"]
                if t == "monkey":      self._draw_monkey(ax, ay, fr)
                elif t == "bird":      self._draw_bird(ax, ay, fr)
                elif t == "butterfly": self._draw_butterfly(ax, ay, fr)

        if self.phase < 4:
            self.draw_ariel(self.ariel_x, self.ariel_y)

        walking_gil = (self.phase == 1 and self.gil_x > 100)
        if self.gil_x < 175:
            self.draw_gil(int(self.gil_x), int(self.gil_y),
                          arm_up=self.gil_arm_up, walking=walking_gil)

        if self.phase >= 4:
            self.draw_ariel(self.ariel_x, self.ariel_y)

        if self.phase == 0 and self.ariel_x < self.ariel_target:
            for d in range(3):
                dx = int(self.ariel_x) - d * 4 - 5
                if 0 <= dx < 160:
                    pyxel.pset(dx, 97 + d % 2, 13)

        if self.phase >= 1 and self.gil_x < 155:
            gx = int(self.gil_x)
            pyxel.rect(gx - 2, int(self.gil_y) - 18, 16, 7, 0)
            pyxel.text(gx - 1, int(self.gil_y) - 17, "GIL", 8)
        if self.ariel_x > 0:
            ax = int(self.ariel_x)
            pyxel.rect(ax - 5, int(self.ariel_y) - 16, 26, 7, 0)
            pyxel.text(ax - 4, int(self.ariel_y) - 15, "ARIEL", 14)

        if self.bubble_visible and self.phase in (2, 3) and self.gil_x < 155:
            self.draw_speech_bubble(int(self.gil_x), int(self.gil_y),
                                    self.lie_text, self.lie_cross_visible)

        for p in self.particles:
            if 0 <= int(p["x"]) < 160 and 0 <= int(p["y"]) < 120:
                pyxel.pset(int(p["x"]), int(p["y"]), p["c"])

        if self.phase >= 3:
            by2 = int(self.banner_y)
            pyxel.rect(7,  by2+2, 148, 18, 1)
            pyxel.rect(5,  by2,   148, 18, 8)
            pyxel.rectb(5, by2,   148, 18, 7)
            pyxel.rectb(6, by2+1, 146, 16, 0)
            pyxel.text(14, by2+6, "GIL LUEGT! Das stimmt nicht!", 7)
            pyxel.text(6,  by2+6, "!", 14)
            pyxel.text(148,by2+6, "!", 14)

        if self.phase >= 5:
            wy = int(self.welcome_y)
            for g in self.glitter:
                if 0 <= g[0] < 160 and wy - 10 <= g[1] <= wy + 30:
                    self.draw_glitter(g[0], g[1], g[2])
            pyxel.rect(3,  wy,    154, 22, 0)
            pyxel.rectb(3, wy,    154, 22, 10)
            pyxel.rectb(4, wy+1,  152, 20, 11)
            text  = "Willkommen im"
            text2 = "Dschungelcamp!"
            colors1 = [10, 14, 9, 8, 10, 14, 9, 8, 10, 14, 9, 8, 10]
            colors2 = [9,  8, 10, 14, 9, 8, 10, 14, 9, 8, 10, 14, 9, 8]
            for i, ch in enumerate(text):
                pyxel.text(8 + i * 4, wy + 4, ch, colors1[i % len(colors1)])
            for i, ch in enumerate(text2):
                pyxel.text(8 + i * 4, wy + 13, ch, colors2[i % len(colors2)])

        if self.phase >= 6:
            if (f // 18) % 2 == 0:
                pyxel.rect(18, 108, 124, 9, 0)
                pyxel.text(20, 110, "ENTER zum Starten", 13)

        pyxel.rect(0,   0, 5, 14, 4)
        pyxel.rect(155, 0, 5, 14, 4)
        for li in range(0, 10, 2):
            pyxel.pset(5 + li // 3, li, 3)
            pyxel.pset(154 - li // 3, li, 3)


# ============================================================
#  SPIELSZENE
# ============================================================
class ArielDschungelRun:
    def __init__(self, on_restart_intro=None):
        self.on_restart_intro = on_restart_intro
        self.reset_game()

    def reset_game(self):
        self.spieler_x = 40
        self.spieler_y = 90
        self.is_jumping = False
        self.jump_velocity = 0
        self.is_ducking = False

        self.score = 0
        self.lives = 3
        self.heart_states = [0, 0, 0]

        self.world_offset = 0
        self.game_over = False
        self.jungle_level = 1

        self.camp_names = ["Gill", "Samira", "Umut", "Mirja", "Hardy",
                           "Simone", "Hubert", "Nicole", "Steffen", "Eva"]
        self.gill_lies   = ["Spring!", "Ducken!"]
        self.other_hints = ["Spring!", "Ducken!"]

        self.special_power = 0
        self.is_special_active = False
        self.special_timer = 0

        self.stars = []; self.obstacles = []; self.vines = []
        self.hints = []; self.portals = []; self.trees = []; self.deco = []

        self.animals = []
        for i in range(5):
            self.animals.append({"type": "monkey", "x": random.randint(50, 800),
                "y": random.randint(25, 45), "frame": random.randint(0, 20),
                "dir": random.choice([-1, 1]), "speed": random.uniform(0.3, 0.7)})
        for i in range(6):
            self.animals.append({"type": "bird", "x": random.randint(0, 900),
                "y": random.randint(12, 50), "frame": random.randint(0, 10),
                "dir": random.choice([-1, 1]), "speed": random.uniform(0.5, 1.2)})
        for i in range(3):
            self.animals.append({"type": "snake", "x": random.randint(100, 700),
                "y": 96, "frame": random.randint(0, 16), "dir": 1,
                "speed": random.uniform(0.2, 0.5)})
        for i in range(4):
            self.animals.append({"type": "butterfly", "x": random.randint(0, 600),
                "y": random.randint(40, 75), "frame": random.randint(0, 8),
                "dir": random.choice([-1, 1]), "speed": random.uniform(0.3, 0.6)})

        self.bg_ropes = []
        for i in range(12):
            self.bg_ropes.append([i * 80 + random.randint(0, 40),
                                   random.randint(0, 15), random.randint(20, 40)])
        self.bg_flowers = []
        for i in range(30):
            self.bg_flowers.append([i * 18 + random.randint(-5, 5),
                                     random.randint(93, 99),
                                     random.choice([8, 9, 10, 14])])
        self.bg_coconuts = []
        for i in range(20):
            tx = i * 30; ty = random.randint(20, 50); tc = random.choice([2, 3, 4, 11])
            self.trees.append([tx, ty, tc])
            if random.random() < 0.5:
                self.bg_coconuts.append([tx + random.randint(-3, 3),
                                          ty + random.randint(5, 10)])

        self.active_quiz      = False
        self.quiz_type        = "math"
        self.quiz_solution    = ""
        self.quiz_display     = ""
        self.quiz_input       = ""
        self.memory_timer     = 0

    def lose_life(self):
        if self.lives > 0:
            self.lives -= 1
            self.heart_states[self.lives] = 1
            if self.lives <= 0:
                self.game_over = True

    def spawn_objects(self):
        spawn_interval = max(8, (45 - self.jungle_level * 4))
        if pyxel.frame_count % spawn_interval == 0:
            spawn_x = self.world_offset + 180

            # Mindestabstand zum letzten Hindernis sicherstellen (ausweichbar!)
            last_obs_x = max((o[0] for o in self.obstacles), default=0)
            too_close = (spawn_x - last_obs_x) < 55

            r = random.random()
            if r < 0.06:
                height = random.choice([55, 62, 68, 74])
                self.stars.append([spawn_x, height])
            elif r < 0.28:
                if not too_close:
                    t1 = random.choice([0, 1])
                    self.obstacles.append([spawn_x, 90, t1])
                    # Doppel-Hindernis nur ab Level 5, immer VERSCHIEDENE Typen
                    # und mit Abstand 28px damit man zwischen ihnen reagieren kann
                    if self.jungle_level >= 5 and random.random() < 0.25:
                        t2 = 1 - t1  # anderer Typ → immer ausweichbar
                        self.obstacles.append([spawn_x + 28, 90, t2])
            elif r < 0.38:
                self.vines.append([spawn_x, random.randint(10, 30)])
            elif r < 0.65:
                name = random.choice(self.camp_names)
                msg  = random.choice(self.gill_lies) if name == "Gill" \
                       else random.choice(self.other_hints)
                self.hints.append([spawn_x, 45, name, msg, False])
            elif r < 0.82:   # Portale seltener (war 0.95)
                self.portals.append([spawn_x, 80])
            if random.random() < 0.4:
                self.deco.append([spawn_x, 98, random.choice([8, 10, 14, 15])])

        if pyxel.frame_count % 200 == 0:
            t = random.choice(["bird", "monkey", "butterfly"])
            self.animals.append({"type": t, "x": self.world_offset + 200,
                "y": random.randint(15, 55) if t != "monkey" else random.randint(25, 45),
                "frame": 0, "dir": random.choice([-1, 1]),
                "speed": random.uniform(0.3, 1.0)})

    def update(self):
        if self.game_over:
            if pyxel.btnp(pyxel.KEY_R): self.reset_game()
            return

        if self.active_quiz:
            self.update_quiz()
            return

        if pyxel.btnp(pyxel.KEY_X) and self.special_power >= 100:
            self.is_special_active = True
            self.special_power = 0
            self.special_timer = 150

        if self.is_special_active:
            self.special_timer -= 1
            if self.special_timer <= 0: self.is_special_active = False

        current_speed = 1.5 + (self.jungle_level * 0.5)
        move_speed = current_speed * 2 if self.is_special_active else current_speed

        self.world_offset += move_speed
        self.score += 1
        self.spawn_objects()

        if self.score > self.jungle_level * 1000:
            self.jungle_level += 1

        if self.score > 0 and self.score % 10000 == 0:
            if self.lives < 3:
                self.heart_states[self.lives] = 0
                self.lives += 1
            self.score += 1

        if pyxel.btnp(pyxel.KEY_SPACE) and not self.is_jumping:
            self.is_jumping = True
            self.jump_velocity = 6

        if self.is_jumping:
            self.spieler_y -= self.jump_velocity
            self.jump_velocity -= 0.4
            if self.spieler_y >= 90:
                self.spieler_y = 90
                self.is_jumping = False

        self.is_ducking = pyxel.btn(pyxel.KEY_DOWN)
        self.check_collisions()
        self._update_animals()

        self.stars     = [s for s in self.stars     if s[0] > self.world_offset - 20]
        self.obstacles = [o for o in self.obstacles  if o[0] > self.world_offset - 20]
        self.hints     = [h for h in self.hints      if h[0] > self.world_offset - 20]
        self.deco      = [d for d in self.deco       if d[0] > self.world_offset - 20]

    def _update_animals(self):
        f = pyxel.frame_count
        for a in self.animals:
            a["frame"] += 1
            t = a["type"]
            if t in ("bird", "butterfly"):
                a["x"] += a["dir"] * a["speed"]
                sx = a["x"] - self.world_offset
                if sx < -20 or sx > 180: a["dir"] *= -1
                if t == "butterfly":
                    a["y"] += pyxel.sin(f * 5 + a["x"] * 0.1) * 0.4
                    a["y"] = max(35, min(78, a["y"]))
            elif t == "monkey":
                a["x"] += a["dir"] * a["speed"] * 0.5
                sx = a["x"] - self.world_offset
                if sx < -10 or sx > 175: a["dir"] *= -1
            elif t == "snake":
                a["x"] += a["dir"] * a["speed"] * 0.4
                sx = a["x"] - self.world_offset
                if sx < -15 or sx > 175: a["dir"] *= -1

    def update_quiz(self):
        if self.quiz_type == "math":
            for i in range(10):
                if pyxel.btnp(getattr(pyxel, f"KEY_{i}")):
                    self.quiz_input += str(i)
                    sol = self.quiz_solution
                    inp = self.quiz_input

                    if len(inp) > len(sol):
                        self.fail_quiz()
                    elif not sol.startswith(inp):
                        self.fail_quiz()
                    elif len(inp) == len(sol):
                        self.score += 40
                        self.active_quiz = False
                        self.quiz_input = ""
                    break

        elif self.quiz_type == "memory":
            if self.memory_timer > 0:
                self.memory_timer -= 1
            else:
                chars = ["A", "B", "C", "D"]
                for char in chars:
                    if pyxel.btnp(getattr(pyxel, f"KEY_{char}")):
                        if char == self.quiz_solution[0]:
                            self.quiz_solution = self.quiz_solution[1:]
                            if len(self.quiz_solution) == 0:
                                self.score += 40
                                self.active_quiz = False
                        else:
                            self.fail_quiz()

    def fail_quiz(self):
        self.lose_life()
        self.active_quiz = False
        self.quiz_input = ""

    def check_collisions(self):
        abs_x = self.world_offset + self.spieler_x

        for s in self.stars[:]:
            if abs(abs_x - s[0]) < 8 and abs(self.spieler_y - s[1]) < 8:
                self.score += 25
                if not self.is_special_active:
                    self.special_power = min(100, self.special_power + 25)
                self.stars.remove(s)

        if not self.is_special_active:
            for o in self.obstacles[:]:
                if abs(abs_x - o[0]) < 8:
                    if (o[2] == 0 and not self.is_jumping) or \
                       (o[2] == 1 and not self.is_ducking):
                        self.lose_life()
                        self.obstacles.remove(o)

            for h in self.hints:
                if abs(abs_x - h[0]) < 5 and not h[4]:
                    is_gill = (h[2] == "Gill")
                    action_correct = \
                        (h[3] in ["Spring!"] and self.is_jumping) or \
                        (h[3] in ["Ducken!"] and self.is_ducking)
                    if (is_gill and action_correct) or (not is_gill and not action_correct):
                        self.lose_life()
                        h[4] = True

        for v in self.vines[:]:
            if abs(abs_x - v[0]) < 10 and self.is_jumping:
                self.score += 15
                self.jump_velocity = 4
                self.world_offset += 30
                self.vines.remove(v)

        for p in self.portals[:]:
            if abs(abs_x - p[0]) < 8:
                self.active_quiz = True
                self.quiz_input  = ""
                if random.random() < 0.5 or self.jungle_level <= 2:
                    self.quiz_type = "math"
                    n1 = random.randint(1, 5 + self.jungle_level)
                    n2 = random.randint(1, 5 + self.jungle_level)
                    self.quiz_display  = f"{n1} + {n2}"
                    self.quiz_solution = str(n1 + n2)
                else:
                    self.quiz_type = "memory"
                    chars = ["A", "B", "C", "D"]
                    length = min(5, 2 + self.jungle_level)
                    sol = "".join(random.choice(chars) for _ in range(length))
                    self.quiz_solution = sol
                    self.quiz_display  = sol
                    self.memory_timer  = max(40, 90 - (self.jungle_level * 5))
                self.portals.remove(p)

    def draw_heart(self, x, y, broken):
        if not broken:
            pyxel.pset(x+1, y, 8); pyxel.pset(x+2, y, 8)
            pyxel.pset(x+4, y, 8); pyxel.pset(x+5, y, 8)
            pyxel.rect(x,   y+1, 7, 1, 8)
            pyxel.rect(x,   y+2, 7, 1, 8)
            pyxel.rect(x+1, y+3, 5, 1, 8)
            pyxel.rect(x+2, y+4, 3, 1, 8)
            pyxel.pset(x+3, y+5, 8)
            pyxel.pset(x+1, y+1, 14)
        else:
            pyxel.pset(x+1, y, 8); pyxel.pset(x+2, y, 8)
            pyxel.pset(x+4, y, 8); pyxel.pset(x+5, y, 8)
            pyxel.pset(x,   y+1, 8); pyxel.pset(x+1, y+1, 8)
            pyxel.pset(x+3, y+1, 8); pyxel.pset(x+4, y+1, 8)
            pyxel.pset(x+5, y+1, 8); pyxel.pset(x+6, y+1, 8)
            pyxel.pset(x,   y+2, 8); pyxel.pset(x+2, y+2, 8)
            pyxel.pset(x+3, y+2, 8); pyxel.pset(x+4, y+2, 8)
            pyxel.pset(x+6, y+2, 8)
            pyxel.pset(x+1, y+3, 8); pyxel.pset(x+3, y+3, 8); pyxel.pset(x+5, y+3, 8)
            pyxel.pset(x+2, y+4, 8); pyxel.pset(x+4, y+4, 8)
            pyxel.pset(x+3, y+5, 8)

    def draw_star(self, x, y, color):
        pyxel.pset(x+3, y,   color); pyxel.pset(x+3, y+1, color)
        pyxel.rect(x,   y+2, 7, 1, color)
        pyxel.rect(x+1, y+3, 5, 1, color)
        pyxel.pset(x,   y+4, color); pyxel.pset(x+2, y+4, color)
        pyxel.pset(x+4, y+4, color); pyxel.pset(x+6, y+4, color)
        pyxel.pset(x+1, y+5, color); pyxel.pset(x+5, y+5, color)

    def _draw_monkey(self, x, y, frame):
        bob = 1 if (frame // 8) % 2 == 0 else 0
        y = int(y) + bob; x = int(x)
        pyxel.pset(x+7, y+3, 4); pyxel.pset(x+8, y+2, 4)
        pyxel.pset(x+9, y+1, 4); pyxel.pset(x+9, y,   9)
        pyxel.rect(x+1, y,   6, 5, 4)
        pyxel.rect(x+2, y+1, 4, 3, 9)
        pyxel.rect(x+1, y-4, 5, 4, 4)
        pyxel.pset(x+2, y-3, 0); pyxel.pset(x+4, y-3, 0)
        pyxel.pset(x+3, y-2, 9)
        pyxel.pset(x,   y-3, 4); pyxel.pset(x+6, y-3, 4)
        arm = (frame // 5) % 2
        pyxel.pset(x,   y+1 if arm == 0 else y+2, 4)
        pyxel.pset(x+7, y+2 if arm == 0 else y+1, 4)
        pyxel.pset(x+2, y+5, 4); pyxel.pset(x+4, y+5, 4)
        pyxel.pset(x+2, y+6, 4); pyxel.pset(x+4, y+6, 4)

    def _draw_bird(self, x, y, frame):
        x, y = int(x), int(y)
        wing = (frame // 4) % 2
        pyxel.rect(x+1, y+1, 4, 3, 7)
        pyxel.rect(x+3, y-1, 3, 3, 7)
        pyxel.pset(x+5, y-1, 0); pyxel.pset(x+6, y, 9)
        pyxel.pset(x,   y+2, 13); pyxel.pset(x-1, y+3, 13)
        if wing == 0:
            pyxel.rect(x+1, y,   4, 1, 12); pyxel.pset(x, y-1, 12)
        else:
            pyxel.rect(x+1, y+3, 4, 1, 12); pyxel.pset(x, y+4, 12)

    def _draw_snake(self, x, y, frame):
        x, y = int(x), int(y)
        wave = (frame // 3) % 6
        offsets = [0, 1, 0, -1, 0, 1]
        for i in range(7):
            px = x + i * 2
            py = y + offsets[(wave + i) % 6]
            c = 11 if i % 2 == 0 else 3
            pyxel.pset(px, py, c); pyxel.pset(px, py+1, c)
        pyxel.rect(x+14, y-1, 4, 3, 3)
        pyxel.pset(x+17, y-1, 7)
        if (frame // 6) % 2 == 0:
            pyxel.pset(x+18, y,   8)
            pyxel.pset(x+19, y-1, 8); pyxel.pset(x+19, y+1, 8)

    def _draw_butterfly(self, x, y, frame):
        x, y = int(x), int(y)
        wing = (frame // 3) % 2
        c1, c2 = 14, 9
        pyxel.pset(x+2, y, 0); pyxel.pset(x+2, y+1, 0); pyxel.pset(x+2, y+2, 0)
        if wing == 0:
            pyxel.pset(x,   y,   c1); pyxel.pset(x+1, y,   c1)
            pyxel.pset(x,   y+1, c1); pyxel.pset(x+1, y+1, c2)
            pyxel.pset(x+3, y,   c1); pyxel.pset(x+4, y,   c1)
            pyxel.pset(x+3, y+1, c2); pyxel.pset(x+4, y+1, c1)
        else:
            pyxel.pset(x+1, y, c1); pyxel.pset(x+1, y+1, c2)
            pyxel.pset(x+3, y, c1); pyxel.pset(x+3, y+1, c2)

    def draw(self):
        bg = 3 if self.jungle_level < 3 else (11 if self.jungle_level < 6 else 0)
        pyxel.cls(bg)
        f = pyxel.frame_count

        for i in range(12):
            bx = (i * 45 - int(self.world_offset * 0.15)) % 200 - 20
            by = 40 + (i % 3) * 8
            pyxel.rect(bx+2, by, 3, 100-by, 4)
            pyxel.circ(bx+3, by, 13, 4 if self.jungle_level < 4 else 0)
            pyxel.circ(bx+3, by, 10, 3 if self.jungle_level < 4 else 11)
            pyxel.pset(bx+5, by+4, 9); pyxel.pset(bx+1, by+6, 9)

        for rope in self.bg_ropes:
            rx = int((rope[0] - self.world_offset * 0.3) % 300 - 30)
            ry_top = rope[1]; rl = rope[2]
            sway = int(pyxel.sin(f * 1 + rope[0] * 0.03) * 2)
            for ry in range(ry_top, ry_top + rl):
                px = rx + sway
                if 0 <= px < 160: pyxel.pset(px, ry, 4)
                if ry % 5 == 0:
                    if 0 <= px-1 < 160: pyxel.pset(px-1, ry, 3)
                    if 0 <= px+1 < 160: pyxel.pset(px+1, ry, 3)

        for fl in self.bg_flowers:
            fx = int((fl[0] - self.world_offset * 0.6) % 220 - 10)
            if 0 <= fx < 160:
                pyxel.pset(fx, fl[1], 11); pyxel.pset(fx, fl[1]-1, 11)
                pyxel.pset(fx-1, fl[1]-2, fl[2]); pyxel.pset(fx+1, fl[1]-2, fl[2])
                pyxel.pset(fx,   fl[1]-3, fl[2]); pyxel.pset(fx,   fl[1]-2, 7)

        for t in self.trees:
            tx = int((t[0] - self.world_offset * 0.4) % 200 - 20)
            ty = t[1]; tc = t[2]
            if -15 <= tx <= 165:
                pyxel.rect(tx, ty, 4, 120-ty, 4)
                for rty in range(ty, 100, 4): pyxel.pset(tx+1, rty, 9)
                pyxel.circ(tx+2, ty, 10, 3 if self.jungle_level < 4 else 11)
                pyxel.circ(tx+4, ty-3, 6, tc)
                for li in range(-8, 8, 3):
                    for lj in range(-8, 8, 3):
                        if li*li + lj*lj < 60:
                            lx, ly2 = tx+2+li, ty+lj
                            if 0 <= lx < 160 and 0 <= ly2 < 100:
                                if (li + lj) % 5 == 0: pyxel.pset(lx, ly2, 11)

        pyxel.rect(0, 100, 160, 20, 13)
        for gx in range(0, 160, 2):
            gh = ((gx * 3 + f // 4) % 3)
            pyxel.pset(gx, 99-gh, 11)
        for gx in range(0, 160, 7):
            world_gx = (gx + int(self.world_offset)) % 160
            if world_gx % 14 < 5: pyxel.rect(gx, 103, 5, 2, 4)

        for a in self.animals:
            ax = int(a["x"] - self.world_offset)
            ay = int(a["y"])
            if -15 <= ax <= 165:
                t = a["type"]
                fr = a["frame"]
                if t == "monkey":      self._draw_monkey(ax, ay, fr)
                elif t == "bird":      self._draw_bird(ax, ay, fr)
                elif t == "snake":     self._draw_snake(ax, ay, fr)
                elif t == "butterfly": self._draw_butterfly(ax, ay, fr)

        if self.game_over:
            pyxel.rect(5, 20, 150, 80, 0)
            pyxel.rectb(5, 20, 150, 80, 8)
            pyxel.text(10, 35, "Du wirst leider nicht die", 8)
            pyxel.text(10, 43, "diesjaehrige Dschungelkoenigin!", 8)
            pyxel.text(10, 58, f"Dein Score: {self.score}", 7)
            pyxel.text(10, 72, "R = Neustart", 10)
            return

        for s in self.stars:
            sx = int(s[0] - self.world_offset)
            sy = int(s[1])
            if -10 <= sx <= 160:
                self.draw_star(sx - 3, sy - 3, 10)
                pyxel.text(sx - 4, sy + 5, "+25", 7)

        for o in self.obstacles:
            ox = int(o[0] - self.world_offset)
            if o[2] == 0:
                pyxel.rect(ox+2, 88, 2, 12, 3)
                pyxel.rect(ox,   92, 6, 8,  3)
                pyxel.pset(ox+1, 87, 0); pyxel.pset(ox+4, 86, 0)
                pyxel.pset(ox+3, 85, 0); pyxel.pset(ox-1, 91, 0)
                pyxel.pset(ox+7, 90, 0)
                pyxel.rectb(ox, 92, 6, 8, 0)
                pyxel.pset(ox+2, 87, 0)
            else:
                pyxel.rect(ox, 78, 14, 6, 2)
                pyxel.rect(ox, 78, 14, 1, 1)
                pyxel.rectb(ox, 78, 14, 6, 0)
                for mx in range(ox, ox+14, 3):
                    pyxel.pset(mx, 80, 1)
                for mx in range(ox, ox+14, 2):
                    pyxel.pset(mx,   77, 2)
                    pyxel.pset(mx+1, 76, 1)

        for v in self.vines:
            vx = int(v[0] - self.world_offset)
            vlen = 60 + v[1]
            sway = int(pyxel.sin(f * 3 + v[0] * 0.1) * 2)
            for vy in range(0, vlen):
                px = vx + int(sway * vy / vlen)
                if 0 <= px < 160:
                    c = 4 if vy % 3 != 0 else 9
                    pyxel.pset(px, vy, c)
                if vy % 6 == 0:
                    if 0 <= px-1 < 160: pyxel.pset(px-1, vy, 3)
                    if 0 <= px+1 < 160: pyxel.pset(px+1, vy, 3)
            pyxel.circ(vx + sway, vlen, 3, 9)

        for h in self.hints:
            color = 8 if h[2] == "Gill" else (10 if h[2] == "Samira" else 7)
            hx = int(h[0] - self.world_offset)
            if -5 <= hx <= 155:
                pyxel.rect(hx-2, h[1]-2, 38, 24, 0)
                pyxel.rectb(hx-2, h[1]-2, 38, 24, color)
                pyxel.text(hx, h[1],   f"{h[2]}:", color)
                pyxel.text(hx, h[1]+8, h[3], 7)
                if h[2] == "Gill":
                    pyxel.text(hx, h[1]+16, "LUEGT!", 8)
                pyxel.rect(hx+28, h[1]+4, 4, 8, color)

        for p in self.portals:
            px = int(p[0] - self.world_offset)
            if -10 <= px <= 160:
                pr = 7 + int(pyxel.sin(f * 3) * 1)
                pyxel.circ(px, int(p[1]), pr,     11)
                pyxel.circ(px, int(p[1]), pr - 3, 3)
                pyxel.circ(px, int(p[1]), pr - 5, 0)
                pyxel.pset(px, int(p[1]), 7)
                pyxel.text(px - 6, int(p[1]) + pr + 2, "PORTAL", 7)

        self.draw_ariel(self.spieler_x, self.spieler_y + (5 if self.is_ducking else 0))

        pyxel.rect(0, 0, 160, 12, 0)
        pyxel.text(2, 3, f"SCORE:{self.score}", 7)
        pyxel.text(72, 3, f"LVL:{self.jungle_level}", 10)
        for i in range(3):
            self.draw_heart(110 + i * 9, 2, self.heart_states[i])
        pyxel.rect(140, 3, 15, 4, 13)
        bar_w = self.special_power // 7
        pyxel.rect(140, 3, bar_w, 4, 10 if self.special_power < 100 else 11)

        if self.active_quiz:
            pyxel.rect(12, 25, 136, 72, 0)
            pyxel.rectb(12, 25, 136, 72, 11)
            pyxel.rectb(13, 26, 134, 70, 14)

            if self.quiz_type == "math":
                sol   = self.quiz_solution
                inp   = self.quiz_input
                digits = len(sol)

                pyxel.text(22, 32, "** MATHE-AUFGABE **", 10)
                pyxel.text(22, 45, f"Was ist: {self.quiz_display} ?", 7)

                total_w = digits * 12
                slot_x  = 80 - total_w // 2
                for d in range(digits):
                    sx = slot_x + d * 12
                    pyxel.rectb(sx, 57, 10, 10, 13)
                    if d < len(inp):
                        pyxel.text(sx + 3, 60, inp[d], 10)
                    else:
                        pyxel.text(sx + 3, 60, "_", 5)

                hint = "Ziffer druecken" if digits == 1 else f"{digits} Ziffern nacheinander"
                pyxel.text(20, 72, hint, 13)
                if len(inp) > 0:
                    pyxel.text(20, 82, f"Eingabe: {inp}", 14)

            elif self.quiz_type == "memory":
                pyxel.text(22, 30, "** MERK DIR DIE FOLGE **", 14)
                if self.memory_timer > 0:
                    for ci, ch in enumerate(self.quiz_display):
                        cc = [10, 8, 14, 9][["A","B","C","D"].index(ch)]
                        pyxel.text(28 + ci * 12, 50, ch, cc)
                    pyxel.text(22, 68, f"Zeit: {self.memory_timer}", 13)
                else:
                    pyxel.text(22, 46, "JETZT ABTIPPEN! (A/B/C/D)", 7)
                    pyxel.text(22, 58, f"Noch: {len(self.quiz_solution)} Zeichen", 13)
                    pyxel.text(22, 68, "Falsch = Leben verloren!", 8)

    def draw_ariel(self, x, y):
        pyxel.rect(x-3, y-2,  14, 6,  8)
        pyxel.rect(x-3, y,    3,  12, 8)
        pyxel.rect(x+8, y,    3,  12, 8)
        pyxel.rect(x,   y,    8,  10, 15)
        pyxel.pset(x+2, y+2, 0)
        pyxel.pset(x+5, y+2, 0)
        pyxel.rect(x+3, y+7, 2, 1, 14)
        c = pyxel.frame_count % 16 if self.is_special_active else 12
        pyxel.rect(x, y+10, 8, 5, c)


# ============================================================
#  HAUPT-APP
# ============================================================
class ArielDschungelApp:
    def __init__(self):
        pyxel.init(160, 120, title="Ariel - Dschungel Camp")
        self.state   = "tutorial"
        self.tutorial = ArielDschungelTutorial(on_done=self.start_intro)
        self.intro   = None
        self.game    = None
        pyxel.run(self.update, self.draw)

    def start_intro(self):
        self.intro = ArielDschungelIntro(on_done=self.start_game)
        self.state = "intro"

    def start_game(self):
        self.game  = ArielDschungelRun()
        self.state = "game"

    def update(self):
        if self.state == "tutorial":
            self.tutorial.update()
        elif self.state == "intro":
            self.intro.update()
        elif self.state == "game":
            self.game.update()

    def draw(self):
        if self.state == "tutorial":
            self.tutorial.draw()
        elif self.state == "intro":
            self.intro.draw()
        elif self.state == "game":
            self.game.draw()


ArielDschungelApp()