from pyxel import *
import random
from Titlescreen import TitleScreen

title_screen = TitleScreen()


#IMPORTANT: ANY CHANGES TO CERTAIN VARIABLES HAVE TO ALSO BE UPDATED IN THE RESET FUNCTION
#constants:
screenwidth = 1024
screenheight = 1024
player_speed = 5
jumpheight = 7


# Lava settings
lava_y = screenheight + 20         # starts off-screen at the bottom
lava_speed = 0         # <-- YOU control this
lava_frame = 0                # animation frame
lava_anim_timer = 0          # doesn't control animation speed: just set to 0
lava_animation_speed = 7    # controls animation speed: the smaller the number the faster the animation

# Player variables
player_x = (screenwidth/2)-8
player_y = 950 - 16
player_vx = 0
player_vy = 0
on_ground = False

# Game state
game_state = "titlescreen"   # can be: "playing", "game_over", "win", "menu"
current_level = 0
death_count = 0


debug = False  # set to True to see hitboxes
dev = False

boss = False            # currently in boss menu mode



moving = "still"


levels = [
    {   # LEVEL 0 (1)
    # 🧱 Platforms (x, y, width, height(just set to 16))
        "platforms": [
    (452, 950, 120, 16),
    (310, 880, 100, 16),
    (520, 820, 100, 16),
    (650, 750, 80, 16),
    (450, 690, 100, 16),
    (380, 620, 80, 16),
    (580, 560, 60, 16),
    (690, 480, 75, 16),
    (600, 440, 100, 16),
    (565, 370, 80, 16),
    (380, 300, 80, 16),
    (290, 230, 50, 16),
    (470, 230, 95, 16),
    (190, 180, 60, 16),
    (600, 155, 100, 16),
    (280, 120, 80, 16),
    (400, 90, 110, 16),
    ],
    
    # (x, y, trigger_zone_x, trigger_zone_y, trigger_width,trigger_height, active)
    #Trigger zone for spikes should normally be: spike_x - 20, spike_y - 20, 40 or 60(width), 40(height)
        "spikes": [
    (550, 804, 530, 784, 40, 40, False),
    (625, 139, 605, 119, 40, 40, False),
    ],
     
    # (x, y, width(just set to 16), height, trigger_zone_x, trigger_zone_y, trigger_width,trigger_height, active)
    #trigger zone for walls should normally be: x and y dependant on situation, 40(width), 40(height)
        "walls": [
    (244, 120, 16, 60, 250, 130, 30, 50, False),
    ],
    #goal_x, goal_y, goal_width, goal_height    
        "goal": (440, 58, 32, 32),
        "lava_speed": 0.2
    },
    
    {   # LEVEL 1 (2)
    # 🧱 Platforms (x, y, width, height(just set to 16))
        "platforms": [
    (452, 950, 120, 16),
    (620, 890, 110, 16),      
    (480, 830, 85, 16),      
    (280, 770, 130, 16),      
    (450, 710, 70, 16),       
    (600, 650, 95, 16),       
    (700, 590, 60, 16),       
    (500, 530, 140, 16),     
    (320, 470, 80, 16),       
    (180, 410, 100, 16),      
    (350, 350, 75, 16),      
    (520, 290, 110, 16),      
    (680, 230, 85, 16),       
    (425, 190, 65, 16),       
    (550, 110, 120, 16),      
    ],
    
    # (x, y, trigger_zone_x, trigger_zone_y, trigger_width,trigger_height, active)
    #Trigger zone for spikes should normally be: spike_x - 20, spike_y - 20, 40 or 60(width), 40 or 60(height)
        "spikes": [
    (510, 814, 500, 794, 60, 40, False),
    (560, 514, 540, 494, 60, 40, False),
    (465, 174, 445, 154, 60, 40, False),
    ],
     
    # (x, y, width(just set to 16), height, trigger_zone_x, trigger_zone_y, trigger_width,trigger_height, active)
    #trigger zone for walls should normally be: x and y dependant on situation, 40(width), 40(height)
        "walls": [
    
    ],
    #goal_x, goal_y, goal_width, goal_height    
        "goal": (630, 78, 32, 32),
        "lava_speed": 0.3
    },
    
    {   # LEVEL 2 (3)
    # 🧱 Platforms (x, y, width, height(just set to 16))
        "platforms": [
    (452, 950, 120, 16),
    (300, 880, 100, 16),
    (175, 820, 90, 16),
    (420, 760, 120, 16),
    (650, 700, 100, 16),
    (550, 640, 100, 16),
    (320, 580, 100, 16),
    (600, 520, 100, 16),
    (700, 460, 80, 16),
    (520, 400, 100, 16),
    (350, 340, 90, 16),
    (500, 290, 90, 16),
    (650, 230, 100, 16),
    (500, 170, 90, 16),
    (600, 90, 120, 16),
    ],
    
    # (x, y, trigger_zone_x, trigger_zone_y, trigger_width,trigger_height, active)
    #Trigger zone for spikes should normally be: spike_x - 20, spike_y - 20, 40 or 60(width), 40(height)
        "spikes": [
    (390, 564, 370, 544, 50, 40, False),
    (550, 624, 560, 530, 40, 20, False),
    (566, 624, 560, 530, 40, 20, False),
    (582, 624, 560, 530, 40, 20, False),
    (596, 624, 560, 530, 40, 20, False),
    (612, 624, 560, 530, 40, 20, False),
    (628, 624, 560, 530, 40, 20, False),
    (644, 624, 560, 530, 40, 20, False),
    (650, 684, 630, 664, 40, 40, False),
    (690, 214, 670, 194, 40, 40, False),
    
    ],
     
    # (x, y, width(just set to 16), height, trigger_zone_x, trigger_zone_y, trigger_width,trigger_height, active)
    #trigger zone for walls should normally be: x and y dependant on situation, 40(width), 40(height)
        "walls": [
    
    ],
    #goal_x, goal_y, goal_width, goal_height    
        "goal": (680, 58, 32, 32),
        "lava_speed": 0.4
    },
    
    

    {   # LEVEL 3 (4)
    # 🧱 Platforms (x, y, width, height(just set to 16))
        "platforms": [
    (452, 950, 120, 16),
    (320, 900, 100, 16),
    (220, 870, 60, 16),
    (330, 820, 90, 16),
    (500, 750, 100, 16),
    (650, 700, 80, 16),
    (400, 650, 150, 16),
    (600, 600, 50, 16),
    (420, 550, 100, 16),
    (275, 500, 85, 16),
    (160, 450, 80, 16),
    (370, 400, 90, 16),
    (550, 340, 140, 16),
    (250, 340, 75, 16),
    (650, 270, 105, 16),
    (180, 270, 70, 16),
    (550, 210, 35, 16),
    (230, 200, 100, 16),
    (350, 160, 70, 16),
    (270, 100, 100, 16),
    ],
    
    # (x, y, trigger_zone_x, trigger_zone_y, trigger_width,trigger_height, active)
    #Trigger zone for spikes should normally be: spike_x - 20, spike_y - 20, 40 or 60(width), 40(height)
        "spikes": [
    (360, 804, 340, 784, 60, 40, False),
    (376, 804, 340, 784, 60, 40, False),
    (600, 584, 580, 564, 60, 40, False),
    (575, 324, 555, 304, 60, 40, False),
    (335, 84, 315, 64, 60, 40, False),
    ],
     
    # (x, y, width(just set to 16), height, trigger_zone_x, trigger_zone_y, trigger_width,trigger_height, active)
    #trigger zone for walls should normally be: x and y dependant on situation, 40(width), 40(height)
        "walls": [
    (550, 260, 16, 80, 230, 150, 50, 50, False),
    (330, 105, 16, 96, 230, 150, 50, 50, False),
    ],
    #goal_x, goal_y, goal_width, goal_height    
        "goal": (280, 68, 32, 32),
        "lava_speed": 0.5
    },
    
    {  #Level 4 (5)
        # 🧱 Platforms (x, y, width, height(just set to 16))
        "platforms": [
    (452, 950, 120, 16),
    (380, 900, 80, 16),
    (500, 850, 120, 16),
    (300, 800, 120, 16),
    (500, 750, 100, 16),
    (600, 700, 60, 16),
    (400, 650, 150, 16),
    (600, 600, 50, 16),
    (450, 580, 100, 16),
    (320, 550, 100, 16),
    (375, 500, 100, 16),
    (560, 465, 100, 16),
    (160, 450, 80, 16),
    (370, 400, 90, 16),
    (550, 340, 140, 16),
    (250, 280, 120, 16),
    (510, 270, 105, 16),
    (250, 210, 35, 16),
    (350, 160, 70, 16),
    (550, 100, 100, 16),
    ],
    
    # (x, y, trigger_zone_x, trigger_zone_y, trigger_width,trigger_height, active)
    #Trigger zone for spikes should normally be: spike_x - 20, spike_y - 20, 40(width), 40(height)
        "spikes": [
    (530, 734, 510, 714, 40, 40, False),
    (460, 634, 440, 614, 40, 40, False),
    (580, 254, 570, 234, 40, 40, False),
    (380, 144, 360, 124, 40, 40, False)
    ],
    
    # (x, y, width(just set to 16), height, trigger_zone_x, trigger_zone_y, trigger_width,trigger_height, active)
    #trigger zone for walls should normally be: x and y dependant on situation, 40(width), 40(height)
        "walls": [
    (550, 586, 16, 64, 580, 600, 40, 5, False),
    (600, 520, 16, 80, 580, 600, 40, 5, False),
    (550, 516, 16, 64, 580, 600, 40, 5, False),
    (560, 369, 16, 96, 570, 410, 50, 40, False),
    (655, 369, 16, 96, 570, 410, 50, 40, False)
    ],
    #goal_x, goal_y, goal_width, goal_height    
        "goal": (615, 68, 32, 32),
        "lava_speed": 0.6
    },
    
    
    {  #Bosslevel
        # 🧱 Platforms (x, y, width, height(just set to 16))
        "platforms": [
        (452, 950, 120, 16),   # start
        (230, 160, 270, 16),
        (315, 115, 470, 16),
        (270, 60, 450, 16),
    ],

    "spikes": [
    
    #spike on beginner wall   
    (520, 844, 510, 824, 30, 35, False),    
    
    #lower platform    
    (484, 144, 448, 130, 16, 30, False),
    (468, 144, 432, 130, 16, 30, False), 
    (452, 144, 416, 130, 16, 30, False), 
    (436, 144, 400, 130, 16, 30, False), 
    (420, 144, 384, 130, 16, 30, False), 
    (404, 144, 368, 130, 16, 30, False), 
    (388, 144, 352, 130, 16, 30, False),
    (372, 144, 336, 130, 16, 30, False), 
    (356, 144, 320, 130, 16, 30, False),
    (340, 144, 304, 130, 16, 30, False), 
    (324, 144, 288, 130, 16, 30, False), 
    (308, 144, 272, 130, 16, 30, False), 
    #different trigger zone
    (292, 144, 272, 70, 40, 50, False),
    (276, 144, 272, 70, 40, 50, False), 
    (260, 144, 272, 70, 40, 50, False), 
    (244, 144, 272, 70, 40, 50, False), 
    (228, 144, 272, 70, 40, 50, False), 
    
    #higher platform
    (315, 99, 351, 85, 16, 30, False),
    (331, 99, 367, 85, 16, 30, False),
    (347, 99, 383, 85, 16, 30, False),
    (363, 99, 399, 85, 16, 30, False),
    (379, 99, 415, 85, 16, 30, False),
    (395, 99, 431, 85, 16, 30, False),
    (411, 99, 447, 85, 16, 30, False),
    (427, 99, 463, 85, 16, 30, False),
    (443, 99, 479, 85, 16, 30, False),
    (459, 99, 495, 85, 16, 30, False),
    (475, 99, 511, 85, 16, 30, False),
    (491, 99, 527, 85, 16, 30, False),
    (507, 99, 543, 85, 16, 30, False),
    (523, 99, 559, 85, 16, 30, False),
    (539, 99, 575, 85, 16, 30, False),
    (555, 99, 591, 85, 16, 30, False),
    (571, 99, 607, 85, 16, 30, False),
    (587, 99, 623, 85, 16, 30, False),
    (603, 99, 639, 85, 16, 30, False),
    (619, 99, 655, 85, 16, 30, False),
    (635, 99, 671, 85, 16, 30, False),
    (651, 99, 687, 85, 16, 30, False),
    (667, 99, 703, 85, 16, 30, False),
    (683, 99, 719, 85, 16, 30, False),
    #spikes in front of player
    (742, 99, 730, 85, 16, 30, False),
    (758, 99, 730, 85, 16, 30, False),
    (774, 99, 730, 85, 16, 30, False),
    
    
        
    ],

    "walls": [
        #starter walls
        (480, 900, 16, 40, 0, 0, 0, 0, True),
        (520, 860, 16, 60, 0, 0, 0, 0, True),
        (560, 820, 16, 60, 0, 0, 0, 0, True),

        # other walls
        #(x, y, width(just set to 16), height, trigger_zone_x, trigger_zone_y, trigger_width,trigger_height, active)
        (620, 760, 16, 80, 560, 800, 20, 20, False),
        (540, 700, 16, 80, 620, 740, 20, 20, False),
        (460, 640, 16, 80, 460, 610, 50, 30, False),
        (380, 580, 16, 80, 380, 550, 20, 30, False),
        (460, 520, 16, 80, 460, 610, 50, 30, False),
        (540, 460, 16, 80, 530, 440, 30, 30, False),
        (620, 410, 16, 80, 610, 390, 30, 30, False),
        (700, 340, 16, 100, 640, 340, 60, 30, False),
        (650, 280, 16, 60, 640, 340, 60, 30, False),
        (600, 200, 16, 80, 600, 180, 30, 30, False),
        

        
        
    ],

    "goal": (680, 28, 32, 32),
    "lava_speed": 0.8
    }
]





lava_death_messages = [
    "CONGRATULATIONS. YOU ARE NOW VAPOR.",
    "THAT LAVA WAS NOT DECORATIVE.",
    "YOU REALLY THOUGHT LAVA WAS SAFE?",
    "YOU MELTED. CONGRATS.",
    "SKILL ISSUE DETECTED.",
    "10/10 PERFORMANCE. FROM THE LAVA.",
    "CONFIDENCE WAS HIGH. SKILL WAS NOT.",
    "YOU GOT OUTPLAYED BY A LIQUID.",
    "YOU GOT DEFEATED BY THE ENVIRONMENT.",
    "YOU MADE IT LOOK EASY. FOR THE LAVA."
]

spike_death_messages = [
    "YOU REALLY RAN INTO THAT.",
    "SPIKES: 1 YOU: 0",
    "MAYBE DON'T HUG SHARP THINGS?",
    "THAT LOOKED PAINFUL.",
    "SHARP OBJECTS ARE... SHARP",
    "SKILL ISSUE DETECTED.",
    "10/10 PERFORMANCE. FROM THE SPIKES.",
    "REFLEXES? NEVER HEARD OF THEM.",
    "CONFIDENCE WAS HIGH. SKILL WAS NOT.",
    "YOU MADE IT LOOK EASY. FOR THE SPIKES.",
    "IT WAS LITERALLY STANDING STILL!"
]


death_message = "You died!"


completed_levels = [False] * len(levels)


def all_levels_completed():
    return all(completed_levels[:-1])  # exclude last (boss) level




def load_level(level_index):
    global platforms, spikes, walls
    global goal_x, goal_y, goal_w, goal_h
    global lava_speed   

    level = levels[level_index]

    platforms = list(level["platforms"])
    spikes = [tuple(s) for s in level["spikes"]]
    walls = [tuple(w) for w in level["walls"]]

    goal_x, goal_y, goal_w, goal_h = level["goal"]

    lava_speed = level["lava_speed"]  


def reset(start_level):
    global player_x, player_y, player_vx, player_vy, on_ground
    global lava_y, lava_frame, lava_anim_timer, game_state, moving

    player_x = (screenwidth / 2) - 8
    player_y = 950 - 16
    player_vx = 0
    player_vy = 0
    on_ground = False

    lava_y = screenheight + 20
    
    if start_level == True:
        game_state = "playing"
        load_level(current_level)
    
    moving = "still"


def update():
    
    global current_level, game_state, moving, death_message, death_count  
    global player_x, player_y, player_vx, player_vy, on_ground
    global boss, boss_unlocked
    global dev, debug
    
    
    
    
    if game_state == "titlescreen":
        title_screen.update()
        if btnp(KEY_RETURN):
            game_state = "menu"
        return
        



    # Go back to menu anytime
    if btnp(KEY_M):
        game_state = "menu"
        return
    
    
    if btnp(KEY_D) and dev == True:
        debug = not debug

        if not all(completed_levels):
            # Unlock all
            for i in range(len(completed_levels)):
                completed_levels[i] = True
            
        else:
            # Reset progress
            for i in range(len(completed_levels)):
                completed_levels[i] = False
            
    
    
    if game_state == "menu":

        # Reset ALL progress (ENTER + R ONLY in menu)
        if btnp(KEY_R) and btn(KEY_RETURN):
            for i in range(len(completed_levels)):
                completed_levels[i] = False
            current_level = 0
            death_count = 0
            boss = False
            return

        # Level selection with lock check
        if btnp(KEY_1):
            if 0 == 0 or completed_levels[0-1]:
                current_level = 0
                reset(True)

        elif btnp(KEY_2) and len(levels) > 1:
            if completed_levels[0]:
                current_level = 1
                reset(True)

        elif btnp(KEY_3) and len(levels) > 2:
            if completed_levels[1]:
                current_level = 2
                reset(True)

        elif btnp(KEY_4) and len(levels) > 3:
            if completed_levels[2]:
                current_level = 3
                reset(True)

        elif btnp(KEY_5) and len(levels) > 4:
            if completed_levels[3]:
                current_level = 4
                reset(True)
                
        # --- SECRET BOSS ACTIVATION ---
        if (btn(KEY_LEFT) and btn(KEY_RIGHT) and btn(KEY_SPACE)):
            if all_levels_completed():
                boss = True
                reset(False)  # reset player but DON'T start level
                play(3,6)
                
            
                
                
                
        # --- BOSS MENU MODE ---
        if boss == True:
            global player_x, player_y, player_vx, player_vy, on_ground

            # movement (same as game)
            player_vx = 0
            if btn(KEY_LEFT):
                player_vx = -player_speed
            if btn(KEY_RIGHT):
                player_vx = player_speed

            if btn(KEY_SPACE) and on_ground:
                player_vy = -jumpheight
                on_ground = False

            # apply movement
            
            if player_x >= screenwidth - 16:
                player_x = screenwidth - 16
            if player_x <= 0:
                player_x = 0
            
            
            player_x += player_vx
            player_y += player_vy

            # gravity
            if not on_ground:
                player_vy += 0.3

            # ground (menu floor)
            if player_y >= 950 - 16:
                player_y = 950 - 16
                player_vy = 0
                on_ground = True

            # --- PORTAL COLLISION --- 
            portal_x, portal_y = 760, 918  #IF YOU CHANGE HERE THEN ALSO IN DRAW FUNCTION

            if (player_x + 16 > portal_x and
            player_x < portal_x + 32 and
            player_y + 16 > portal_y and
            player_y < portal_y + 32):

                current_level = len(levels) - 1  # boss level
                boss = False
                reset(True)
        
        return
    
    
    
    
    
    
    
    # Reset
    if btnp(KEY_R) and current_level <= len(levels)-1:
        reset(True)
        return

    # Stop movement if game ended
    if game_state != "playing":
        return
    

    # Horizontal movement
    player_vx = 0
    moving = "still"
    if btn(KEY_LEFT):
        player_vx = -player_speed
        moving = "left"
    if btn(KEY_RIGHT):
        player_vx = player_speed
        moving = "right"

    # Jump
    if btn(KEY_SPACE) and on_ground == True and player_vy <= 0:
        player_vy = -jumpheight
        on_ground = False
        play(2,3)

    # Apply movement
   # --- Move horizontally ---
    if player_x >= screenwidth - 16:
        player_x = screenwidth - 16
    if player_x <= 0:
        player_x = 0
        
    player_x += player_vx

    for px, py, pw, ph in platforms:
        if (player_y + 16 > py and 
        player_y < py + ph):
            # Moving right
            if (player_vx > 0 and 
            player_x + 16 > px and 
            player_x < px):
                player_x = px - 16
            # Moving left
            elif (player_vx < 0 and 
            player_x < px + pw and 
            player_x + 16 > px + pw):
                player_x = px + pw
                
                
        # --- Wall collision (horizontal) ---
    for wx, wy, ww, wh, tx, ty, tw, th, active in walls:
        if not active:
            continue

        if (player_y + 16 > wy and player_y < wy + wh):
            # Moving right
            if player_vx > 0 and player_x + 16 > wx and player_x < wx:
                player_x = wx - 16
            # Moving left
            elif player_vx < 0 and player_x < wx + ww and player_x + 16 > wx + ww:
                player_x = wx + ww
                

    # --- Move vertically ---
    player_y += player_vy
    on_ground = False  # reset before checking

    for px, py, pw, ph in platforms:
        # Landing
        if (player_x + 16 > px and 
            player_x - 5 <= px + pw and
            player_y + 16 >= py and 
            player_y + 16 - player_vy <= py and 
            player_vy > 0):

                player_y = py - 16
                player_vy = 0
                on_ground = True

        # Ceiling
        elif (player_x + 16 > px and      
            player_x - 5 <= px + pw and    
            player_y <= py + ph and 
            player_y - player_vy >= py + ph and 
            player_vy < 0):

                player_y = py + ph
                player_vy = 0
    # Ground collision
    if player_y >= screenheight-16:
        player_y = screenheight-16
        player_vy = 0
        on_ground = True
            
            
            
            
        # --- Wall collision (vertical) ---
    for wx, wy, ww, wh, tx, ty, tw, th, active in walls:
        if not active:
            continue

        # Landing on wall
        if (player_x + 16 > wx and player_x < wx + ww and
            player_y + 16 >= wy and player_y + 16 - player_vy <= wy and player_vy > 0):

            player_y = wy - 16
            player_vy = 0
            on_ground = True

        # Hitting underside of wall
        elif (player_x + 16 > wx and player_x < wx + ww and
            player_y <= wy + wh and player_y - player_vy >= wy + wh and player_vy < 0):

            player_y = wy + wh
            player_vy = 0

    
    # --- Apply gravity (after collision) ---
    if not on_ground:
        player_vy += 0.3
        if player_vy > 16:
            player_vy = 16
        if player_vy < -16:
            player_vy = -16
    
    
    global lava_y, lava_frame, lava_anim_timer

    # --- Lava movement ---
    lava_y -= lava_speed

    # --- Lava animation ---
    lava_anim_timer += 1
    if lava_anim_timer >= lava_animation_speed:
        lava_anim_timer = 0
        lava_frame = (lava_frame + 1) % 3

    # --- Lava collision ---
    if player_y + 16 > lava_y:
        global death_message
        death_message = random.choice(lava_death_messages)
        death_count += 1
        game_state = "game_over"
        play(3,0)
        return
    
    
    
         # --- Activate spikes ---
    for i in range(len(spikes)):
        sx, sy, tx, ty, tw, th, active = spikes[i]

        if not active == True:
            if (player_x + 16 > tx and
                player_x < tx + tw and
                player_y + 16 > ty and
                player_y < ty + th):

                spikes[i] = (sx, sy, tx, ty, tw, th, True)
            
          #Activate Walls  
    for i in range(len(walls)):
        wx, wy, ww, wh, tx, ty, tw, th, active = walls[i]

        if not active == True:
            if (player_x + 16 > tx and
                player_x < tx + tw and
                player_y + 16 > ty and
                player_y < ty + th):

                walls[i] = (wx, wy, ww, wh, tx, ty, tw, th, True)
            
            
            
            
        # --- Spike collision ---
    for sx, sy, tx, ty, tw, th, active in spikes:
        if not active == True:
            continue

        if (player_x + 16 > sx and
            player_x < sx + 16 and
            player_y + 16 > sy and
            player_y < sy + 16):

            death_message = random.choice(spike_death_messages)
            death_count += 1
            game_state = "game_over"
            play(3,1)
            return
    
                
       # --- Check goal collision ---
    if (player_x + 16 > goal_x and
        player_x < goal_x + goal_w and
        player_y + 16 > goal_y and
        player_y < goal_y + goal_h):
            

        # --- IF PLAYER IS CURRENTLY IN BOSS LEVEL ---
        if current_level == len(levels) - 1:
            game_state = "boss_win"
            play(3,5)
            return
        
        
        completed_levels[current_level] = True
        # normal level complete
        if current_level < len(levels) - 2:
            play(3,2)   # ✅ level-up sound

        # --- OTHERWISE GO TO NEXT LEVEL ---
        current_level += 1

        # --- IF NEXT LEVEL IS BOSS → NORMAL GAME WIN SCREEN ---
        if current_level == len(levels) - 1:
            game_state = "win"
            play(3,4)
            return

        reset(True)
        return
    
    
    
    

def draw():
    global lava_frames, lava_frame, lava_anim_timer
    cls(0) 
    
    
    if game_state == "titlescreen":
        title_screen.draw()
        return
    
    # 🧱 Draw platforms
    for px, py, pw, ph in platforms:
        for i in range(0, pw, 16):
            blt(px + i, py, 0, 0, 32, 16, 16, 0)
            
            
            
        # --- Draw spikes ---
    for sx, sy, tx, ty, tw, th, active in spikes:
        if active == True:
            blt(sx, sy, 0, 0, 64, 16, 16, 0)


    # --- Draw walls ---
    for wx, wy, ww, wh, tx, ty, tw, th, active in walls:
        if active == True:
            for y in range(wy, wy + wh, 16):
                blt(wx, y, 0, 0, 48, 16, 16, 0)   
    
    
    
    lava_frames = [
    (0, 192),
    (16, 192),
    (32, 192)
    ]

    u, v = lava_frames[lava_frame]

    # Fill all space below lava_y
    y = int(lava_y)
    while y < screenheight:
        for x in range(0, screenwidth, 16):
            blt(x, y, 0, u, v, 16, 16, 0)
        y += 16
        
    
    
    # Draw map
    bltm(0,0,0,0,0,screenwidth,screenheight,0)

    
                
    # Draw goal 
    # blt(x, y, img_bank, u, v, w, h, [colkey])
    blt(goal_x, goal_y, 0, 16, 32, goal_w, goal_h, 0)

    #draw player
    if moving == "still":
        blt(player_x,player_y,0,0,16,16,16,0)
    if moving == "right":
        blt(player_x,player_y,0,16,16,16,16,0)
    if moving == "left":
        blt(player_x,player_y,0,32,16,16,16,0)
    
    
    # --- UI text ---
    if game_state == "game_over":
        cls(0)
        bltm(0, 0, 0, 0, 0, screenwidth, screenheight, 0)

        # --- TEXT CONTENT ---
        line1 = "GAME OVER"
        line2 = death_message
        line3 = "PRESS R TO RESTART"
        line4 = str(death_count)

        # --- WIDTH CALC (longest line) ---
        max_width = max(
            len(line1) * 4,
            len(line2) * 4,
            len(line3) * 4,
            len(line4) * 4
        )

        # --- BOX SETTINGS ---
        box_height = 80
        padding = 10

        box_x = (screenwidth - max_width) // 2
        box_y = screenheight // 2 - box_height // 2

        border_thickness = 3

        # border
        for i in range(border_thickness):
            rect(
                box_x - padding - i,
                box_y - padding - i,
                max_width + padding * 2 + i * 2,
                box_height + padding * 2 + i * 2,
                5
            )

        # fill
        rect(box_x - padding + border_thickness,
            box_y - padding + border_thickness,
            max_width + padding * 2 - border_thickness * 2,
            box_height + padding * 2 - border_thickness * 2,
            12)

        # --- DRAW TEXT (centered inside box) ---
        text(box_x + (max_width - len(line1)*4)//2,
            box_y + 5, line1, 8)

        text(box_x + (max_width - len(line2)*4)//2,
            box_y + 25, line2, 7)

        text(box_x + (max_width - len(line3)*4)//2,
            box_y + 40, line3, 7)

        # skull icon (centered)
        blt(box_x + max_width//2 - 12,
            box_y + 55, 0, 0, 240, 16, 16, 0)

        text(box_x + max_width//2 + 8,
            box_y + 59, line4, 8)


    elif game_state == "win":
        cls(0)
        border_thickness = 3

        # --- TEXT CONTENT ---
        line1 = "YOU WIN!"
        line2 = "PRESS M TO RETURN TO MENU."

        # --- WIDTH CALC ---
        max_width = max(
            len(line1) * 4,
            len(line2) * 4
        )

        # --- BOX SETTINGS ---
        box_height = 50
        padding = 10

        box_x = (screenwidth - max_width) // 2
        box_y = screenheight // 2 - box_height // 2

        for i in range(border_thickness):
            rect(
                box_x - padding - i,
                box_y - padding - i,
                max_width + padding * 2 + i * 2,
                box_height + padding * 2 + i * 2,
                5
            )

        # fill
        rect(box_x - padding + border_thickness,
            box_y - padding + border_thickness,
            max_width + padding * 2 - border_thickness * 2,
            box_height + padding * 2 - border_thickness * 2,
            12)
            
            
        # --- DRAW TEXT ---
        text(box_x + (max_width - len(line1)*4)//2,
         box_y + 10, line1, 11)

        text(box_x + (max_width - len(line2)*4)//2,
            box_y + 30, line2, 7)
            
            
    elif game_state == "boss_win":
        cls(0)
        border_thickness = 3

        line1 = "BOSS LEVEL DEFEATED!"
        line2 = "THAT WAS INSANE!"
        line3 = "CONGRATS!"
        line4 = "PRESS M TO RETURN TO MENU"

        max_width = max(
            len(line1) * 4,
            len(line2) * 4,
            len(line3) * 4,
            len(line4) * 4
        )

        box_height = 90
        padding = 10

        box_x = (screenwidth - max_width) // 2
        box_y = screenheight // 2 - box_height // 2

        # border
        for i in range(border_thickness):
            rect(
                box_x - padding - i,
                box_y - padding - i,
                max_width + padding * 2 + i * 2,
                box_height + padding * 2 + i * 2,
                8
            )

        # fill
        rect(
            box_x - padding + border_thickness,
            box_y - padding + border_thickness,
            max_width + padding * 2 - border_thickness * 2,
            box_height + padding * 2 - border_thickness * 2,
            1
        )

        text(box_x + (max_width - len(line1)*4)//2,
            box_y + 10, line1, 11)

        text(box_x + (max_width - len(line2)*4)//2,
            box_y + 30, line2, 7)

        text(box_x + (max_width - len(line3)*4)//2,
            box_y + 50, line3, 7)
        
        text(box_x + (max_width - len(line4)*4)//2,
            box_y + 70, line4, 7)
        
        
     # --- MENU SCREEN ---
    if game_state == "menu":
        cls(0)
        
        
        lava_anim_timer += 1
        if lava_anim_timer >= lava_animation_speed:
            lava_anim_timer = 0
            lava_frame = (lava_frame + 1) % 3
        
        
        lava_frames = [
        (0, 192),
        (16, 192),
        (32, 192)
        ]

        u, v = lava_frames[lava_frame]

        # Fill all space below lava_y
        y = 950
        while y < screenheight:
            for x in range(0, screenwidth, 16):
                blt(x, y, 0, u, v, 16, 16, 0)
            y += 16
        
        bltm(0,0,0,0,0,screenwidth,screenheight,0)
        
        
        
        if boss == True:
        # draw portal
            portal_x, portal_y = 760, 918 #IF YOU CHANGE HERE ALSO IN UPDATE FOR COLLISION DETECTION
            blt(portal_x, portal_y, 0, 16, 32, 32, 32, 0)# pick a portal sprite
            text(770, 910, "???", 8)

            # draw player
            blt(player_x, player_y, 0, 0, 16, 16, 16, 0)
        
        

        blt(360, 350, 0, 0, 224, 16, 16, 0) #C
        blt(376, 350, 0, 16, 224, 16, 16, 0) #I
        blt(392, 350, 0, 32, 224, 16, 16, 0) #I
        blt(408, 350, 0, 48, 224, 16, 16, 0) #M
        blt(424, 350, 0, 64, 224, 16, 16, 0) #B
        blt(456, 350, 0, 80, 224, 16, 16, 0) #O
        blt(472, 350, 0, 96, 224, 16, 16, 0) #R
        blt(504, 350, 0, 64, 224, 16, 16, 0) #B
        blt(520, 350, 0, 112, 224, 16, 16, 0) #U
        blt(536, 350, 0, 96, 224, 16, 16, 0) #R
        blt(552, 350, 0, 128, 224, 16, 16, 0) #N
    
        
        blt(450, 390, 0, 0, 240, 16, 16, 0) #SKULL
        text(475, 395, f"{death_count}", 8)
        if death_count >= 55:
            text(416, 415, "HOW DID YOU MANAGE THAT!!", 7)

        # Draw level icons
        start_x = 416
        y = 426

        for i in range(len(levels) - 1):
            x = start_x + i * 20

            unlocked = (i == 0) or completed_levels[i-1]

            if unlocked:
                u = i * 16
                v = 96
                blt(x, y, 0, u, v, 16, 16, 0)
            else:
                blt(x, y, 0, 0, 80, 16, 16, 0)

        text(386, 516, "CONTROLS:", 10)
        text(386, 526, "NUMBERS = SELECT LEVEL", 7)
        text(386, 536, "ARROW KEYS = MOVE", 7)
        text(386, 546, "SPACE = JUMP", 7)
        text(386, 556, "R = RESTART", 7)
        text(386, 566, "ENTER + R = RESET PROGRESS", 7)
        text(386, 576, "M = BACK TO MENU", 7)
        
        if current_level == len(levels) - 1:
            text(386, 586, "SPACE +  BOTH ARROW KEYS = ???", 9)
        
        return
        
        
        # --- DEBUG: Draw trigger zones ---
    if debug == True:
        # Spike trigger zones
        for sx, sy, tx, ty, tw, th, active in spikes:
            rect(tx, ty, tw, th, 8)

        # Wall trigger zones
        for wx, wy, ww, wh, tx, ty, tw, th, active in walls:
            rect(tx, ty, tw, th, 9)
            

        

# Start game
init(screenwidth, screenheight, fps = 60)
load("Files.pyxres")
current_level = 0
load_level(current_level)
reset(False)
run(update, draw)