// 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_RGB || format == cTFPVRTC1_4_RGBA)
    {
	    // 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_RGB || format == cTFPVRTC1_4_RGBA)
    {
		// 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);
    }))
  ;

}
