import pyxel, random #import dependencies

pyxel.init(13*16, 9*16)
#pyxel.init(39*16, 27*16) #dev mode, sees whole map
pyxel.load("res2.pyxres") #load res file

floor = [ [0 for i in range(39)] for i in range(27)] #define 39*27 table
player_cell_x = 6 #player start x pos
player_cell_y = 4 #player start y pos
orientation = "S"
level = 0
rooms = [] #init a list of room centers (used for corridors building)
mobs = []
dither_timer = 0
dither_amount = 0
life = 3

def generation(): #generation of the dungeon (Lev part)
    global floor, level, rooms #use the global floor table + level var
    
    floor = [[0 for i in range(39)] for i in range(27)] #define 39*27 table
    
    def spawn():
        global player_cell_x, player_cell_y
        # ----------SPAWN----------
        x = player_cell_x - 1 #spawn room x pos
        y = player_cell_y - 1 #spawn room y pos
        for h in range(3): #height 3
            for w in range(3): #width 3
                floor[y+h][x+w] = 10 #set to floor tile
        rooms.append((x+1, y+1))  #save center position
    spawn() # run func

    def random_room(): #make ONE random room 
        width = random.randint(3, 10) #random width
        height = random.randint(3, 10) #random height

        x = random.randint(0, 39 - width) #random x pos
        y = random.randint(0, 27 - height) #random y pos

        for h in range(height): # room will be HEIGHT tall 
            for w in range(width): # room will be WIDTH wide
                floor[y+h][x+w] = 10 #set to floor tile

        rooms.append((x + w//2, y + h//2)) # add room's centers to list of centers
    
    for _ in range(3+level): #make X random rooms
        random_room() #call rand room func
    
    def end(): #pre-built room templates
        global player_cell_x, player_cell_y #use global player coords
        x = random.randint(0, 34)
        y = random.randint(0,22)
        for h in range(5):
            for w in range (5):
                floor[y+h][x+w] = 10
                if h==2 and w==2:
                    floor[y+h][x+w] = 199
        rooms.append((x+2, y+2))
    end()
    
    def corridors(): #connect them with corridors
        for i in range(1, len(rooms)): #
            x1, y1 = rooms[i-1]
            x2, y2 = rooms[i]
            for x in range(min(x1, x2), max(x1, x2) + 1):
                floor[y1][x] = 10
            for y in range(min(y1, y2), max(y1, y2) + 1):
                floor[y][x2] = 10
    corridors()
    
    floor[rooms[-1][1]][rooms[-1][0]]=199 
    
    def walls():
        for line in range(27):
            for tile in range(39):
                if floor[line][tile] == 10:
                    walls = [0, 0, 0, 0]
                    #top
                    try:
                        if floor[line-1][tile] == 0:
                            walls[0] = 1
                    except IndexError: 
                        walls[0] = 1
                    #right
                    try:
                        if floor[line][tile+1] == 0:
                            walls[1] = 1
                    except IndexError: 
                        walls[1] = 1
                    #bottom
                    try:
                        if floor[line+1][tile] == 0:
                            walls[2] = 1
                    except IndexError: 
                        walls[2] = 1
                    #left
                    try:
                        if floor[line][tile-1] == 0:
                            walls[3] = 1
                    except IndexError: 
                        walls[3] = 1
                        
                    match walls:
                        case [0,0,0,0]: 
                            floor[line][tile] = 100
                        case [1,0,0,0]: 
                            floor[line][tile] = 101
                        case [1,1,0,0]: 
                            floor[line][tile] = 102
                        case [0,1,0,0]: 
                            floor[line][tile] = 103
                        case [0,1,1,0]: 
                            floor[line][tile] = 104
                        case [0,0,1,0]: 
                            floor[line][tile] = 105
                        case [0,0,1,1]:
                            floor[line][tile] = 106
                        case [0,0,0,1]: 
                            floor[line][tile] = 107
                        case [1,0,0,1]: 
                            floor[line][tile] = 108
                        case [1,0,1,0]:
                            floor[line][tile] = 109
                        case [0,1,0,1]:
                            floor[line][tile] = 110
                
    level+=1
    walls()
generation()


def generation_mobs():
    global floor, mobs #use the global floor table + level var
    
    mobs = [[0 for i in range(39)] for i in range(27)] #define 39*27 table
    
    for line in range(len(mobs)):
        for cell in range(len(mobs[line])):
            if floor[line][cell]//100 == 1:
                chance = random.randint(1,100)
                if chance > 92:
                    mobs[line][cell] = 11
generation_mobs()
print(mobs)


def dither_in(time):
    global dither_timer, dither_amount
    print(dither_amount, dither_timer, time)
    if dither_timer < time:
        dither_timer+=1
        dither_amount=dither_timer/time
    dither_amount = 1

def dither_out(time):
    global life
    if life<3:
        life+=1
    global dither_timer, dither_amount
    if dither_timer != 0:
        dither_timer-=1
        dither_amount=dither_timer/time
    dither_amount = 0

def mob_movement(player_x, player_y):
    global mobs, life
    temp = [[0 for i in range(39)] for i in range(27)]
    for line in range(len(mobs)):
        for cell in range(len(mobs[line])):
            if mobs[line][cell] != 0:
                if line>=player_y+5 or line<=player_y-5 or cell<=player_x-7 or cell>=player_x+7:
                    temp[line][cell]=11
                else:
                    if line < player_y and floor[line+1][cell]!=0 and temp[line+1][cell]==0:
                        temp[line+1][cell]=11
                    elif line > player_y and floor[line-1][cell]!=0 and temp[line-1][cell]==0 :
                        temp[line-1][cell]=11
                    elif cell < player_x and floor[line][cell+1]!=0 and temp[line][cell+1]==0:
                        temp[line][cell+1]=11
                    elif cell > player_x and floor[line][cell-1]!=0 and temp[line][cell-1]==0:
                        temp[line][cell-1]=11
                    else:
                        temp[line][cell]=11

    mobs = temp
    

def player_movement(player_x, player_y, orientation):
    global floor, mobs, life
    if pyxel.btnp(pyxel.KEY_W) or pyxel.btnp(pyxel.KEY_Z):
        if floor[player_y-1][player_x]//100 == 1 and mobs[player_y-1][player_x]==0:
            mob_movement(player_x, player_y)
            player_y -=1
            if player_y < 0:
                player_y = 0
        orientation = "N"
    elif pyxel.btnp(pyxel.KEY_A) or pyxel.btnp(pyxel.KEY_Q):
        if floor[player_y][player_x-1]//100 == 1 and mobs[player_y][player_x-1]==0:
            mob_movement(player_x, player_y)
            player_x -=1
            if player_x < 0:
                player_x = 0
        orientation = "W"
    elif pyxel.btnp(pyxel.KEY_S):
        if floor[player_y+1][player_x]//100 == 1 and mobs[player_y+1][player_x]==0:
            mob_movement(player_x, player_y)
            player_y +=1
            if player_y > 26:
                player_y = 26
        orientation = "S"
    elif pyxel.btnp(pyxel.KEY_D) :
        if floor[player_y][player_x+1]//100 == 1 and mobs[player_y][player_x+1]==0:
            mob_movement(player_x, player_y)
            player_x +=1
            if player_x > 38:
                player_x = 38
        orientation = "E"
        
    if mobs[player_y][player_x]==11:
        life-=1
        mobs[player_y][player_x]=0

           
    return player_x, player_y, orientation
    
def attack(orientation, player_x, player_y):
    global mobs
    if pyxel.btnp(pyxel.KEY_SPACE):
        match orientation:
            case "N":
                if mobs[player_y-1][player_x]:
                    mobs[player_y-1][player_x]=0
            case "S":
                if mobs[player_y+1][player_x]:
                    mobs[player_y+1][player_x]=0
            case "E":
                if mobs[player_y][player_x+1]:
                    mobs[player_y][player_x+1]=0
            case "W":
                if mobs[player_y][player_x-1]:
                    mobs[player_y][player_x-1]=0
        mob_movement(player_x, player_y)
        
def update_and_draw_health(life, level):
    x=13*16-10
    y=3
    if life==1:
        pyxel.blt(x, y, 0, 35, 67, 9, 9, 2)
    if life==2:
        pyxel.blt(x, y, 0, 35, 67, 9, 9, 2)
        pyxel.blt(x-13, y, 0, 35, 67, 9, 9, 2)
    if life==3:
        pyxel.blt(x, y, 0, 35, 67, 9, 9, 2)
        pyxel.blt(x-13, y, 0, 35, 67, 9, 9, 2)
        pyxel.blt(x-26, y, 0, 35, 67, 9, 9, 2)
    if life<1:
        life-=1000
        pyxel.blt(0, 0, 2, 0, 32, 13*16, 9*16, 2)

    

def update():
    global player_cell_x, player_cell_y, orientation, rooms, dither_timer, life
    player_cell_x, player_cell_y, orientation = player_movement(player_cell_x, player_cell_y, orientation)
    attack(orientation, player_cell_x, player_cell_y)
    if player_cell_x == rooms[-1][0]:
        if player_cell_y == rooms[-1][1]:
            dither_in(60)
            generation()
            generation_mobs()
            dither_out(60)
   
def draw():
    global floor, monstre, orientation, dither_timer, mobs
    
    pyxel.cls(0)
    
    cell_x = (-player_cell_x+6) * 16
    cell_y = (-player_cell_y+4) * 16
    
    if dither_amount != 0:
        pyxel.dither(dither_amount)
    
    
    for line in range(len(floor)):
        for cell in range(len(floor[line])):
            if floor[line][cell]//100 == 1:
                tile = floor[line][cell] - 100
                pyxel.blt(cell_x, cell_y, 1, 0, tile*16, 16, 16)
                if tile == 99: 
                    pyxel.blt(cell_x, cell_y, 1, 32, 0, 16, 16)
            else:
                pyxel.rect(cell_x, cell_y, 16, 16, 0)
            cell_x += 16
        cell_y += 16
        cell_x = (-player_cell_x+6) * 16
        
    cell_x = (-player_cell_x+6) * 16
    cell_y = (-player_cell_y+4) * 16
    
    for line in range(len(mobs)): #dessine les mobs
        for cell in range(len(mobs[line])):
            if mobs[line][cell]//10 == 1:
                pyxel.blt(cell_x, cell_y, 0, 16, 16-16, 16, 16, 2)
            cell_x += 16 
        cell_y += 16
        cell_x = (-player_cell_x+6) * 16
        
        
    if orientation == "N":
        pyxel.blt(6*16, 4*16, 0, 0, 48, 16, 16, 2)
    elif orientation == "W":
        pyxel.blt(6*16, 4*16, 0, 0, 32, 16, 16, 2)
    elif orientation == "S":
        pyxel.blt(6*16, 4*16, 0, 0, 0, 16, 16, 2)
    elif orientation == "E":
        pyxel.blt(6*16, 4*16, 0, 0, 16, 16, 16, 2)
    
    update_and_draw_health(life, level)
    
pyxel.run(update, draw)