.include "entity_manager.h.s"


_num_entities:: .db 0
_last_elem_ptr:: .dw _entity_array
_entity_array::
    .ds max_entities*sizeof_e

_player_lives:: .db 3
_player_invuln_sec:: .db 10000 ; nº ciclos para volver a tener colisiones

entity_manager_getEntityArray:
    ld      ix, #_entity_array
    ld      a, (_num_entities)
    ret


;;=========================================================================
;; Crea una nueva entidad
;; Input:
;;      HL : Puntero a la zona de memoria donde se encuentran los datos de la nueva entidad
;; Destroy:
;;      AF, BC, HL, DE
;; Return:
;;      
;;=========================================================================
entity_manager_create::
    ld      de, (_last_elem_ptr)
    ld      bc, #sizeof_e
    ldir

    ;; Incrementamos el número de entidades
    ld      a, (_num_entities)
    inc     a

    ;; Comprobar el num max de entidades
    cp  #max_entities
    ret z ; salimos si ha alcanzado el num max de entidades

    ld      (_num_entities), a

    ;; Incrementamos el puntero al último elemento
    ld      hl, (_last_elem_ptr) ;; Cargamos en hl el valor contenido por _last_elem_ptr
    ld      bc, #sizeof_e
    add     hl, bc
    ld      (_last_elem_ptr), hl

    ret 


;;===========================================================
;; Marca las entidades como invalidas
;; Input:
;;      IX : Puntero a la zona de memoria donde se encuentra la entidad a destruir
;; Destroy:
;;      
;; Return:
;;      
;;===========================================================
entity_manager_destroy_entity::

    ld e_cmp(ix), #e_cmp_invalid
    ; Decrementar num entidades
    ;ld a, (_num_entities)
    ;dec a
    ;ld (_num_entities),a

    ; Decrementar last element

    ret


;;===========================================================
;; Actualiza vector entidades y mueve los asteroides que están 
;; arriba de la pantalla delante
;; Input:
;;      IX : Puntero al vector de entidades
;;       A : numero de entidades
;; Destroy:
;;      AF, B, DE, IX
;; Return:
;;      
;;===========================================================
entity_manager_update::
    
    ; Pasa el primer elemento (player)
    ld      de, #sizeof_e
    add     ix, de

    ; Carga nª entidades
    ld b, a

    ; Recorrer el vector ordenando los asteroides
    _loop_update:
        ; Comprueba num entidades
        dec b
        ret z


        ; Es invalido?
        ld a, e_cmp(ix)
        and #e_cmp_invalid
        jr  z, _next_e

        ; Haz cosas
        ; Intercambiar por el último
        

        _next_e:
            ;ld      de, #sizeof_e
            add     ix, de
            jr      _loop_update


;;=========================================================================
;; Ejecuta la funcion dada para todas las entidades con los bits indicados
;; Input:
;;      HL : Puntero a la función a ejecutar
;;       B : Máscara de bits
;; Destroy:
;;      AF, C, DE
;; Return:
;;      
;;=========================================================================
entity_manager_forall_matching::
    call    entity_manager_getEntityArray
    ld c, a

    ; Recorrer vector
    _loop:
        ld a, e_cmp(ix)
        and b       ; comprobamos si es valida la máscara de bits
        jr z, _cond_parada  ; si no valida vamos al siguiente
        
        ; Llamar a la fn
        push bc
        push hl
        call JP_HL
        pop hl
        pop bc
    

    _cond_parada:
        ; Comprobar si quedan entidades
        dec c
        ret z ; sale si no hay más elem

        ; Aumentamos iterador
        ld      de, #sizeof_e
        add     ix, de
        
        jr      _loop

; Funcion para hacer call de una funcion en registro hl
JP_HL:
        jp (hl)