.module sys_collision
.include "./manager/entities.h.s"
.include "./manager/rounds.h.s"
.include "./manager/music.h.s"
.include "cpctelera.h.s"
.include "collision.h.s"
.include "ui.h.s"
.globl spawn_enemy1

.macro saveSetBorder _color
    push hl
    cpctm_setBorder_asm _color
    pop hl
.endm

sys_collision_control_init::
    call man_entity_collision_getArray
    ld (_ent_array_ptr), hl
ret

;;HL funciona como iterador
;;DE almacenamos el puntero
;;IX funciona como entidad 1
;;IY funciona como entidad 2

sys_collision_control_init_entities::
    call man_entity_first_entity
    ld (_ent_array_ptr), hl
ret

sys_collision_update::    
    _ent_array_ptr = . + 1  ld hl, #0x0000

    next_ix:
        ld e, (hl)
        inc hl
        ld d, (hl)
        inc hl
        ;;Comprobamos que el puntero no es null
        ld a, e
        or d
        ;;ret z ;;Fin
        jr z, exit
        ;;Almacenamos la siguiente posicion para la siguiente iteración
        push hl
        
        ld__ixl_e
        ld__ixh_d

        call sys_collision_check_player
        call sys_collision_check_enemy

        call sys_collision_check_valid_entity
        jr z, null

    next_iy:

        ld e, (hl)
        inc hl
        ld d, (hl)
        inc hl
    
        ;;Comprobamos que el "segundo iterador" no es null
        ld a, e
        or d
        jr z, null

        ld__iyl_e
        ld__iyh_d

        call sys_collision_check_valid_entity_iy
        jr z, null
        ;;CHECK COLLISION BETWEEN ENTITIES IX AND IY
        ;;DESTROY AF
        call check_entities_type_collision
        jr next_iy
    null:
        pop hl
        jr next_ix
    exit:
ret

;;IX entity 1
;;IY entity 2

check_entities_type_collision::

    ld a, e_type(ix)
    cp #0
    jr z, mainCharacter

    cp #1
    jr z, enemyCollision

    cp #3
    jr z, bulletCollision

    enemyCollision:

    ld b, e_type(iy)
    add a, b ;;Enemy
    cp #4
    jr z, bulletEnemy
    jp nz, skip

    bulletEnemy:
        ld a, e_cmps(ix)
        cp #e_cmps_deathanim
        jp z, skip
        
    ;;  ENEMY-BULLET
        call sys_collision_check
        jr nc, collision
    ret


    bulletCollision:

    ld b, e_type(iy)
    add a, b ;;Enemy
    cp #4
    jr z, bulletEnemy2
    jr nz, skip

    bulletEnemy2:
        ld a, e_cmps(iy)
        cp #e_cmps_deathanim
        jp z, skip
        
        call sys_collision_check
        jr nc, collision
    ret

    mainCharacter:
    ld b, e_type(iy)
    add a, b ;;Enemy/Bullet
    cp #1
    jr z, enemy

    ld a, e_type(iy)
    cp #e_type_food
    jr z, food_player
    jr nz, skip

    enemy:
        ld a, e_cmps(iy)
        cp #e_cmps_deathanim
        jp z, skip


        call sys_collision_check
        jr nc, collision_character
    ret

    food_player:
        call sys_collision_check
        jr nc, collision_food
    ret

    ;;Personaje principal muere
    collision_food:
        ld a, e_death(iy)
        cp #0
        jr z, skip

            push af
            ld l, #4 ; que sonido va a sonar
            ld h, #15 ; volumen 0-15
            ld e, #60 ; nota 0-143
            ld d, #0 ; speed (0 es original, 1 es la mas rapida)
            ld bc, #0xFFFF ;pitch
            ld a, #10 ;canal del medio
            push ix
            call cpct_akp_SFXPlay_asm
            pop ix
            pop af
        ld e_death(iy), #0
    ret

    collision_character:
        ld a, e_playerctr(ix)
        dec a
        jr nz, not_damaged
            call man_entity_damaged
            cpctm_setBorder_asm HW_RED
            ld a, #110 ;;Tiempo entre hit y hit 50 = 1 Segundo
            ld e_playerctr(ix), a
        not_damaged:
    jp skip

    collision:
        call man_entity_damaged
    skip:
ret

sys_collision_check_valid_entity::
    ld b, #e_cmps_todestroy
    ld a, e_cmps(ix)
    and b
    cp b
ret

sys_collision_check_valid_entity_iy::
    ld b, #e_cmps_todestroy
    ld a, e_cmps(iy)
    and b
    cp b
ret

sys_collision_check::
    ;;if (a<b)
    ;;a = e_x(ix)+e_w(ix) < e_x(iy)
    ;;a = e_x(ix)+e_w(ix) - e_x(iy) < 0

    ld a, e_x(ix)
    dec a
    add e_w(ix)
    sub e_x(iy)
    ret c

    ld a, e_y(ix)
    dec a
    add e_h(ix)
    sub e_y(iy)
    ret c

    ;;if (c<d)
    ;;a = e_x(iy)+e_w(iy) < e_x(ix)
    ;;a = e_x(iy)+e_w(iy) - e_x(ix) < 0

    ld a, e_x(iy)
    dec a
    add e_w(iy)
    sub e_x(ix)
    ret c

    ;;Colision en Y

    ld a, e_y(iy)
    dec a
    add e_h(iy)
    sub e_y(ix)
ret

sys_collision_check_player::
    ld a, e_type(ix)
    cp #e_type_mainchar
    jr nz, skip_ctr

    ld a, e_playerctr(ix)
    dec a
    jr z, skip_ctr
    
    ld e_playerctr(ix), a
    skip_ctr:
ret

sys_collision_check_enemy::
    ld a, e_type(ix)
    cp #e_type_enemy
    jr nz, skip_ctr_enemy

    ld a, e_enemy_ctr_retroceso(ix)
    dec a
    jr z, skip_ctr_enemy
    
    ld e_enemy_ctr_retroceso(ix), a
    ld a, e_enemy_ctr_retroceso(ix)
    cp #2
    jr nz, skip_ctr_enemy

    ld a, e_type_enemy_ai(ix)
    cp #e_type_enemy_ovni
    jr z, skip_ctr_enemy

    ld a, e_enemy_last_vel_x(ix)
    ld e_vx(ix), a
    ld a, e_enemy_last_vel_y(ix)
    ld e_vy(ix), a

    ld a, e_enemy_last_vel_x+1(ix)
    ld e_vx+1(ix), a
    ld a, e_enemy_last_vel_y+1(ix)
    ld e_vy+1(ix), a

    skip_ctr_enemy:
ret