/**
 * Copyright (c) 2021 Dominic Masters
 * 
 * This software is released under the MIT License.
 * https://opensource.org/licenses/MIT
 */

#include "entity.h"

entitystate_t ENTITY_STATE;

void entityStateInit() {
  // Reset the entities
  memset(ENTITY_STATE.entities, 0, sizeof(entity_t) * ENTITY_COUNT);

  // Prepare the spritebatch.
  ENTITY_STATE.spriteBatch = spriteBatchCreate(ENTITY_COUNT);

  // Load the texture
  ENTITY_STATE.texture = assetTextureLoad(ENTITY_ASSET_TEXTURE);

  // Divide the tileset
  ENTITY_STATE.tileset = tilesetCreate(
    ENTITY_STATE.texture->width/ENTITY_WIDTH,
    ENTITY_STATE.texture->height/ENTITY_HEIGHT,
    ENTITY_STATE.texture->width, ENTITY_STATE.texture->height,
    0,0,0,0
  );
}

void entityStateRender() {
  entityid_t i;
  entity_t *entity;

  // Flush the batch.
  spriteBatchFlush(ENTITY_STATE.spriteBatch);

  // Update and Render the entities.
  for(i = 0; i < ENTITY_COUNT; i++) {
    entity = ENTITY_STATE.entities + i;
    if(entity->type == ENTITY_TYPE_NULL) break;
    ENTITY_TYPES[entity->type].entityUpdate(i, entity);
    ENTITY_TYPES[entity->type].entityRender(i, entity);
  }

  // Draw the sprite batch.
  shaderUseTexture(GAME_STATE.shaderWorld, ENTITY_STATE.texture);
  shaderUsePosition(GAME_STATE.shaderWorld, 0, 0, 0, 0, 0, 0);
  spriteBatchDraw(ENTITY_STATE.spriteBatch, 0, -1);
}

void entityStateDispose() {
  entityid_t i;
  entity_t *entity;

  for(i = 0; i < ENTITY_COUNT; i++) {
    entity = ENTITY_STATE.entities + i;
    if(entity->type == ENTITY_TYPE_NULL) break;
    entityDispose(i);
  }

  spriteBatchDispose(ENTITY_STATE.spriteBatch);
}

void entityInit(entityid_t id, entitytypeid_t type) {
  entity_t *entity = ENTITY_STATE.entities + id;
  entity->type = type;

  // Reset values
  entity->gridX = entity->gridY = entity->gridZ = 0;
  entity->oldGridX = entity->oldGridY = entity->oldGridZ = 0;
  entity->positionX = entity->positionY = entity->positionZ = 0;

  // Init
  if(ENTITY_TYPES[type].entityInit == NULL) return;
  ENTITY_TYPES[type].entityInit(id, entity);
}

void entityDispose(entityid_t id) {
  entity_t *entity = ENTITY_STATE.entities + id;
  entity->type = ENTITY_TYPE_NULL;
  if(ENTITY_TYPES[entity->type].entityDispose == NULL) return;
  ENTITY_TYPES[entity->type].entityDispose(id, entity);
}