;;-----------------------------LICENSE NOTICE------------------------------------
;;  This file is part of Viking Hangover
;;  Copyright (C) 2021 Ahmed Begga / Érika Moreno / Adriana Morejón (@ComputosGame)
;;
;;  This program is free software: you can redistribute it and/or modify
;;  it under the terms of the GNU Lesser General Public License as published by
;;  the Free Software Foundation, either version 3 of the License, or
;;  (at your option) any later version.
;;
;;  This program is distributed in the hope that it will be useful,
;;  but WITHOUT ANY WARRANTY; without even the implied warranty of
;;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;  GNU Lesser General Public License for more details.
;;
;;  You should have received a copy of the GNU Lesser General Public License
;;  along with this program.  If not, see <http://www.gnu.org/licenses/>.
;;-------------------------------------------------------------------------------

.include "cpctelera.h.s"
.include "entity.h.s"
.include "sys/render.h.s"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;  VARIABLES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_currentPos::
.ds 2
_space_Free::
.ds 2
_ptr_entities_array::
   .ds entity_array_bytes_size 
   .db #0
_ptr_next_entity::
   .ds 2
_function_for_all::
   .ds 2
_signature::
   .ds 1
_signature2::
   .ds 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Description:                                           ;;                                                          
;;      Create the array of  entities                    ;;
;;Required:                                              ;;
;;     -                                                 ;;  
;; Return:                                               ;;                                                  
;;     -                                                 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
man_entity_init::
   ld bc, #entity_array_bytes_size
   ld a, #0
   ld de, #_ptr_entities_array
   call cpct_memset_asm

   ld hl, #_ptr_entities_array
   ld (_ptr_next_entity), hl
   ld hl, #entity_array_bytes_size
   ld (#_space_Free), hl

   ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Description:                                            ;;                                                          
;;      Returns the a new entity and increases the pointer;;
;;      to the following free space                       ;;
;;Required:                                               ;;
;;     -                                                  ;;  
;; Return:                                                ;;                                                  
;;     HL ->Pointer to th first entity created            ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
man_entity_create::
   ld bc, (_ptr_next_entity) 
   ld a, #e_cmp_default
   ld (bc), a

   ld hl, #entity_size
   add hl, bc
   ld (_ptr_next_entity), hl 
   ld l, c
   ld h, b
   push hl

   ld bc, #entity_size
   ld hl, (_space_Free)
   add hl, bc
   ld (#_space_Free), hl
   pop hl
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Description:                                           ;;                                                          
;;      Destroy an entity from the array                 ;;
;;Required:                                              ;;
;;     IX -> Pointer on the beginning of the array       ;;  
;; Return:                                               ;;                                                  
;;     -                                                 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
man_entity_destroy::
   ;;actualizamos nuestro puntero a la siguiente entidad
   ld bc, #entity_size
   ld hl, (#_space_Free)
   add hl, bc
   ld (#_space_Free), hl

   call sys_render_delete
   ;;Restamos para cargarnos la entidad
   ld bc, #-entity_size
   ld (_currentPos), ix
   ld hl, (#_currentPos)
   ld d, h
   ld e, l
   ld hl, (#_ptr_next_entity)

   add hl, bc
   ld (_ptr_next_entity), hl
   ld bc, #entity_size
   call cpct_memcpy_asm
   call actualiza
   
ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Description:                                           ;;                                                          
;;      Marks an entity to destroy                       ;;
;;Required:                                              ;;
;;     IX -> Pointer on the beginning of the array       ;;  
;; Return:                                               ;;                                                  
;;     -                                                 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
man_entity_set4_destroy::
   ld b, #e_cmp_dead
   ld a, e_type(ix)
   or b
   ld e_type(ix), a
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Description:                                           ;;                                                          
;;      Call to destroy every entity set4dead            ;;
;;Required:                                              ;;
;;     IX -> Pointer on the beginning of the array       ;;  
;; Return:                                               ;;                                                  
;;     -                                                 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
man_entity_destroy_dead::
   ld a, #e_cmp_dead
   ld hl, #man_entity_destroy
   call man_entity_forall
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Description:                                           ;;                                                          
;;      Apply a function for all the entities in the array;;
;;Required:                                              ;;
;;     HL -> Function that we want to apply              ;;  
;;     a  -> _signature                                   ;;                                                  
;; Return:                                               ;;                                                  
;;     -                                                 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
man_entity_forall::
   ld ix, #_ptr_entities_array
   ld (_signature), a
   ld (_function_for_all), hl
   forall_loop:
      ld a, e_type(ix)
      or a
      ret z

      ld a, (#_signature)
      ld b, e_type(ix)
      and b
      jr z, next_iter

      ld bc, #next_iter
      ld hl, (#_function_for_all)
      push bc
      jp (hl)

      next_iter:
         ld bc, #entity_size
         add ix, bc
         jr forall_loop
ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Description:                                           ;;                                                          
;;      Apply a function for all the entities in the array;;
;;      with a concrete restriction                      ;;
;;Required:                                              ;;
;;     HL -> Function that we want to apply              ;;  
;;     a  -> _signature                                  ;;                                                  
;;     b  -> _signature2                                 ;;                                                  
;; Return:                                               ;;                                                  
;;     -                                                 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
man_entity_forall_match::
   ld ix, #_ptr_entities_array
   ld (_signature), a
   ld a, b
   ld (_signature2), a
   ld (_function_for_all), hl
   forall_matchFirst_loop:
      ld a, e_type(ix)
      ld iy, #_ptr_entities_array
      or a
      ret z

      ld a, (#_signature)
      ld b, e_type(ix)
      and b
      jr z, next_iter_first

      forall_matchSecond_loop:
            ld a, e_type(iy)      
            or a
            jr z, next_iter_first

            ld a, (#_signature2)
            ld b, e_type(iy)      
            and b
            jr z, next_iter_sec 

            ld bc, #next_iter_sec
            ld hl, (#_function_for_all)
            push bc
            jp (hl)

            next_iter_sec:
            ld bc, #entity_size
            add iy, bc
            jr forall_matchSecond_loop
            next_iter_first:
            ld bc, #entity_size
            add ix, bc
            jr forall_matchFirst_loop
ret

actualiza:
   ld bc, #entity_size
   ld a, #0
   ld de, (#_ptr_next_entity)
   call cpct_memset_asm
   ;;Restamos nuevamente
   ld ix, (#_currentPos)
   ld bc, #-entity_size 
   ;;Actualizamos la nueva posicion de ix
   add ix, bc
ret   