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

#include "TilesetAsset.hpp"

using namespace Dawn;

TilesetAsset::TilesetAsset(AssetManager *assMan, std::string name) :
  Asset(assMan, name),
  loader(name + ".tileset"),
  tileset()
{
}

void TilesetAsset::updateSync() {

}

void TilesetAsset::updateAsync() {
  assertTrue(this->state == 0x00, "TilesetAsset::updateAsync: Initial state should be 0x00");

  this->state = 0x01;
  this->loader.open();
  uint8_t *buffer = (uint8_t*)memoryAllocate(this->loader.getSize());
  this->loader.read(buffer, this->loader.getSize());
  this->loader.close();
  this->state = 0x02;

  char *strCurrent = (char *)buffer;
  char *strNext, *strSubCurrent;

  // Read cols and rows
  strNext = strchr(strCurrent, '|');
  *strNext = '\0';
  this->tileset.columns = atoi(strCurrent);
  this->state = 0x03;
  assertTrue(this->tileset.columns > 0, "TilesetAsset::updateAsync: Count of columns needs to be greater than 0");

  strCurrent = strNext+1;
  strNext = strchr(strCurrent, '|');
  *strNext = '\0';
  this->tileset.rows = atoi(strCurrent);
  this->state = 0x04;
  assertTrue(this->tileset.rows > 0, "TilesetAsset::updateAsync: Count of rows needs to be greater than 0");

  strCurrent = strNext+1;
  strNext = strchr(strCurrent, '|');
  *strNext = '\0';
  this->tileset.divX = atoi(strCurrent);
  this->state = 0x05;
  assertTrue(this->tileset.divX > 0, "TilesetAsset::updateAsync: divX needs to be greater than 0");

  strCurrent = strNext+1;
  strNext = strchr(strCurrent, '|');
  *strNext = '\0';
  this->tileset.divY = atoi(strCurrent);
  this->state = 0x06;
  assertTrue(this->tileset.divY > 0, "TilesetAsset::updateAsync: divY needs to be greater than 0");

  // Begin reading tiles.
  int32_t done = 0;
  int32_t count = this->tileset.columns * this->tileset.rows;
  while(done < count) {
    struct Tile tile;

    strCurrent = strNext+1;
    strNext = strchr(strCurrent, '|');

    // Parse ux0
    strSubCurrent = strchr(strCurrent, ',');
    *strSubCurrent = '\0';
    tile.uv0.x  = atof(strCurrent);

    // Parse ux1
    strCurrent = strSubCurrent+1;
    strSubCurrent = strchr(strCurrent, ',');
    *strSubCurrent = '\0';
    tile.uv1.x = atof(strCurrent);

    // Parse uy0
    strCurrent = strSubCurrent+1;
    strSubCurrent = strchr(strCurrent, ',');
    *strSubCurrent = '\0';
    tile.uv0.y = atof(strCurrent);

    // Parse uy1
    strCurrent = strSubCurrent+1;
    *strNext = '\0';
    tile.uv1.y = atof(strCurrent);

    // Next.
    this->tileset.tiles.push_back(tile);
    done++;
  }

  this->state = 0x07;
  this->loaded = true;
  
  memoryFree(buffer);
}