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

#include "common.h"

void entityCommonMoveUpdate(entityid_t id, entity_t *entity) {
  float x, y, z, delta;
  x = entity->gridX - entity->positionX;
  y = entity->gridY - entity->positionY;
  z = entity->gridZ - entity->positionZ;

  if(mathAbs(x) <= 0.05 && mathAbs(y) <= 0.05 && mathAbs(z) <= 0.05) {
    entity->positionX = entity->gridX;
    entity->positionY = entity->gridY;
    entity->positionZ = entity->gridZ;
    entity->state -= ENTITY_STATE_WALKING;
    return;
  }

  // TODO: Change this from easing curve to linear.
  delta = TIME_STATE.delta * ENTITY_COMMON_MOVE_SPEED;
  entity->positionX += x == 0 ? 0 : x > 0 ? delta : -delta;
  entity->positionY += y == 0 ? 0 : y > 0 ? delta : -delta;
  entity->positionZ += z == 0 ? 0 : z > 0 ? delta : -delta;
}

void entityCommonMove(entityid_t id, entity_t *entity, int32_t x, int32_t y, int32_t z) {
  int32_t newX, newY, newZ, chunkIndex, tileIndex;
  tileid_t tileId;

  // Update state.
  entity->state |= ENTITY_STATE_WALKING;

  // Determine the new coordinates.
  newX = entity->gridX + x;
  newY = entity->gridY + y;
  newZ = entity->gridZ + z;

  // Can we move there, tile check first then entity check.
  tilegetresult_t result = tileGet(newX, newY, newZ);
  chunkIndex = chunkGet(result.chunkX, result.chunkY, result.chunkZ);
  if(chunkIndex == -1) return;
  tileIndex = chunkGetTile(result.localX, result.localY, result.localZ);
  
  tileId = MAP_STATE.chunkList[chunkIndex]->tiles[tileIndex];
  if(tileId == TILE_NULL) return;

  // Update the old and new positions
  entity->oldGridX = entity->gridX;
  entity->oldGridY = entity->gridY;
  entity->oldGridZ = entity->gridZ;
  entity->gridX = newX;
  entity->gridY = newY;
  entity->gridZ = newZ;
}

void entityCommonRender(entityid_t id, entity_t *entity) {
  tilesetdiv_t div = tilesetGetDivision(ENTITY_STATE.tileset, 0, entity->direction);

  // Render sprite
  spriteBatchQuad(ENTITY_STATE.spriteBatch, -1,
    entity->positionX, entity->positionY, entity->positionZ + 0.01,
    1, 1,
    div.x0, div.y0, div.x1, div.y1
  );
}

void entityCommonTurn(entityid_t id, entity_t *entity, uint8_t dir) {
  if(entity->direction == dir) return;
  entity->direction = dir;
  entity->state = ENTITY_STATE_WALKING;
}