// basis_wrappers.cpp - Simple C-style wrappers to the C++ transcoder for WebGL use.
#include "basisu_transcoder.h"
#include <emscripten/bind.h>
#include <algorithm>

using namespace emscripten;
using namespace basist;

static basist::etc1_global_selector_codebook *g_pGlobal_codebook;

void basis_init()
{
  basisu_transcoder_init();

  if (!g_pGlobal_codebook)
    g_pGlobal_codebook = new basist::etc1_global_selector_codebook(g_global_selector_cb_size, g_global_selector_cb);
}

#define MAGIC 0xDEADBEE1

struct basis_file
{
  int m_magic = 0;
	basisu_transcoder m_transcoder;
  std::vector<uint8_t> m_file;

  basis_file(const emscripten::val& jsBuffer)
    : m_file([&]() {
        size_t byteLength = jsBuffer["byteLength"].as<size_t>();
        return std::vector<uint8_t>(byteLength);
      }()),
      m_transcoder(g_pGlobal_codebook)
  {
    unsigned int length = jsBuffer["length"].as<unsigned int>();
    emscripten::val memory = emscripten::val::module_property("HEAP8")["buffer"];
    emscripten::val memoryView = jsBuffer["constructor"].new_(memory, reinterpret_cast<uintptr_t>(m_file.data()), length);
    memoryView.call<void>("set", jsBuffer);

    if (!m_transcoder.validate_header(m_file.data(), m_file.size())) {
      m_file.clear();
    }

    // Initialized after validation
    m_magic = MAGIC;
  }

  void close() {
    assert(m_magic == MAGIC);
    m_file.clear();
  }

  uint32_t getHasAlpha() {
    assert(m_magic == MAGIC);
    if (m_magic != MAGIC)
      return 0;

    basisu_image_level_info li;
    if (!m_transcoder.get_image_level_info(m_file.data(), m_file.size(), li, 0, 0))
      return 0;

    return li.m_alpha_flag;
  }

  uint32_t getNumImages() {
    assert(m_magic == MAGIC);
    if (m_magic != MAGIC)
      return 0;

    return m_transcoder.get_total_images(m_file.data(), m_file.size());
  }

  uint32_t getNumLevels(uint32_t image_index) {
    assert(m_magic == MAGIC);
    if (m_magic != MAGIC)
      return 0;

    basisu_image_info ii;
    if (!m_transcoder.get_image_info(m_file.data(), m_file.size(), ii, image_index))
      return 0;

    return ii.m_total_levels;
  }

  uint32_t getImageWidth(uint32_t image_index, uint32_t level_index) {
    assert(m_magic == MAGIC);
    if (m_magic != MAGIC)
      return 0;

    uint32_t orig_width, orig_height, total_blocks;
    if (!m_transcoder.get_image_level_desc(m_file.data(), m_file.size(), image_index, level_index, orig_width, orig_height, total_blocks))
      return 0;

    return orig_width;
  }

  uint32_t getImageHeight(uint32_t image_index, uint32_t level_index) {
    assert(m_magic == MAGIC);
    if (m_magic != MAGIC)
      return 0;

    uint32_t orig_width, orig_height, total_blocks;
    if (!m_transcoder.get_image_level_desc(m_file.data(), m_file.size(), image_index, level_index, orig_width, orig_height, total_blocks))
      return 0;

    return orig_height;
  }

  uint32_t getImageTranscodedSizeInBytes(uint32_t image_index, uint32_t level_index, uint32_t format) {
    assert(m_magic == MAGIC);
    if (m_magic != MAGIC)
      return 0;

    if (format >= cTFTotalTextureFormats)
      return 0;

    uint32_t bytes_per_block = basis_get_bytes_per_block(static_cast<transcoder_texture_format>(format));

    uint32_t orig_width, orig_height, total_blocks;
    if (!m_transcoder.get_image_level_desc(m_file.data(), m_file.size(), image_index, level_index, orig_width, orig_height, total_blocks))
      return 0;

    if (format == cTFPVRTC1_4_OPAQUE_ONLY)
    {
	    // For PVRTC1, Basis only writes (or requires) total_blocks * bytes_per_block. But GL requires extra padding for very small textures: 
        // https://www.khronos.org/registry/OpenGL/extensions/IMG/IMG_texture_compression_pvrtc.txt
        const uint32_t width = (orig_width + 3) & ~3;
        const uint32_t height = (orig_height + 3) & ~3;
        const uint32_t size_in_bytes = (std::max(8U, width) * std::max(8U, height) * 4 + 7) / 8;
        return size_in_bytes;
    }

    return total_blocks * bytes_per_block;
  }

  uint32_t startTranscoding() {
    assert(m_magic == MAGIC);
    if (m_magic != MAGIC)
      return 0;

    return m_transcoder.start_transcoding(m_file.data(), m_file.size());
  }

  uint32_t transcodeImage(const emscripten::val& dst, uint32_t image_index, uint32_t level_index, uint32_t format, uint32_t pvrtc_wrap_addressing, uint32_t get_alpha_for_opaque_formats) {
    assert(m_magic == MAGIC);
    if (m_magic != MAGIC)
      return 0;

    if (format >= cTFTotalTextureFormats)
      return 0;

    uint32_t bytes_per_block = basis_get_bytes_per_block(static_cast<transcoder_texture_format>(format));

    uint32_t orig_width, orig_height, total_blocks;
    if (!m_transcoder.get_image_level_desc(m_file.data(), m_file.size(), image_index, level_index, orig_width, orig_height, total_blocks))
      return 0;

    uint32_t required_size = total_blocks * bytes_per_block;

    if (format == cTFPVRTC1_4_OPAQUE_ONLY)
    {
		// For PVRTC1, Basis only writes (or requires) total_blocks * bytes_per_block. But GL requires extra padding for very small textures: 
		// https://www.khronos.org/registry/OpenGL/extensions/IMG/IMG_texture_compression_pvrtc.txt
		// The transcoder will clear the extra bytes followed the used blocks to 0.
        const uint32_t width = (orig_width + 3) & ~3;
        const uint32_t height = (orig_height + 3) & ~3;
        required_size = (std::max(8U, width) * std::max(8U, height) * 4 + 7) / 8;
        assert(required_size >= total_blocks * bytes_per_block);
    }

    std::vector<uint8_t> dst_data(required_size);

    uint32_t status = m_transcoder.transcode_image_level(
      m_file.data(), m_file.size(), image_index, level_index,
      dst_data.data(), dst_data.size() / bytes_per_block,
      static_cast<basist::transcoder_texture_format>(format),
      (
        (pvrtc_wrap_addressing ? basisu_transcoder::cDecodeFlagsPVRTCWrapAddressing : 0) |
        (get_alpha_for_opaque_formats ? basisu_transcoder::cDecodeFlagsTranscodeAlphaDataToOpaqueFormats : 0)
      ));

    emscripten::val memory = emscripten::val::module_property("HEAP8")["buffer"];
    emscripten::val memoryView = emscripten::val::global("Uint8Array").new_(memory, reinterpret_cast<uintptr_t>(dst_data.data()), dst_data.size());

    dst.call<void>("set", memoryView);
    return status;
  }
};

EMSCRIPTEN_BINDINGS(basis_transcoder) {

  function("initializeBasis", &basis_init);

  class_<basis_file>("BasisFile")
    .constructor<const emscripten::val&>()
    .function("close", optional_override([](basis_file& self) {
      return self.close();
    }))
    .function("getHasAlpha", optional_override([](basis_file& self) {
      return self.getHasAlpha();
    }))
    .function("getNumImages", optional_override([](basis_file& self) {
      return self.getNumImages();
    }))
    .function("getNumLevels", optional_override([](basis_file& self, uint32_t imageIndex) {
      return self.getNumLevels(imageIndex);
    }))
    .function("getImageWidth", optional_override([](basis_file& self, uint32_t imageIndex, uint32_t levelIndex) {
      return self.getImageWidth(imageIndex, levelIndex);
    }))
    .function("getImageHeight", optional_override([](basis_file& self, uint32_t imageIndex, uint32_t levelIndex) {
      return self.getImageHeight(imageIndex, levelIndex);
    }))
    .function("getImageTranscodedSizeInBytes", optional_override([](basis_file& self, uint32_t imageIndex, uint32_t levelIndex, uint32_t format) {
      return self.getImageTranscodedSizeInBytes(imageIndex, levelIndex, format);
    }))
    .function("startTranscoding", optional_override([](basis_file& self) {
      return self.startTranscoding();
    }))
    .function("transcodeImage", optional_override([](basis_file& self, const emscripten::val& dst, uint32_t imageIndex, uint32_t levelIndex, uint32_t format, uint32_t pvrtcWrapAddressing, uint32_t getAlphaForOpaqueFormats) {
      return self.transcodeImage(dst, imageIndex, levelIndex, format, pvrtcWrapAddressing, getAlphaForOpaqueFormats);
    }))
  ;

}
