// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "impeller/scene/importer/vertices_builder.h"

#include <cstring>
#include <limits>
#include <memory>
#include <type_traits>

#include "flutter/fml/logging.h"
#include "impeller/scene/importer/conversions.h"
#include "impeller/scene/importer/scene_flatbuffers.h"

namespace impeller {
namespace scene {
namespace importer {

//------------------------------------------------------------------------------
/// VerticesBuilder
///

std::unique_ptr<VerticesBuilder> VerticesBuilder::MakeUnskinned() {
  return std::make_unique<UnskinnedVerticesBuilder>();
}

std::unique_ptr<VerticesBuilder> VerticesBuilder::MakeSkinned() {
  return std::make_unique<SkinnedVerticesBuilder>();
}

VerticesBuilder::VerticesBuilder() = default;

VerticesBuilder::~VerticesBuilder() = default;

/// @brief  Reads a numeric component from `source` and returns a 32bit float.
///         If `normalized` is `true`, signed SourceTypes convert to a range of
///         -1 to 1, and unsigned SourceTypes convert to a range of 0 to 1.
template <typename SourceType>
static Scalar ToScalar(const void* source, size_t index, bool normalized) {
  const SourceType* s = reinterpret_cast<const SourceType*>(source) + index;
  Scalar result = static_cast<Scalar>(*s);
  if (normalized) {
    constexpr SourceType divisor = std::is_integral_v<SourceType>
                                       ? std::numeric_limits<SourceType>::max()
                                       : 1;
    result = static_cast<Scalar>(*s) / static_cast<Scalar>(divisor);
  }
  return result;
}

/// @brief  A ComponentWriter which simply converts all of an attribute's
///         components to normalized scalar form.
static void PassthroughAttributeWriter(
    Scalar* destination,
    const void* source,
    const VerticesBuilder::ComponentProperties& component,
    const VerticesBuilder::AttributeProperties& attribute) {
  FML_DCHECK(attribute.size_bytes ==
             attribute.component_count * sizeof(Scalar));
  for (size_t component_i = 0; component_i < attribute.component_count;
       component_i++) {
    *(destination + component_i) =
        component.convert_proc(source, component_i, true);
  }
}

/// @brief  A ComponentWriter which converts four vertex indices to scalars.
static void JointsAttributeWriter(
    Scalar* destination,
    const void* source,
    const VerticesBuilder::ComponentProperties& component,
    const VerticesBuilder::AttributeProperties& attribute) {
  FML_DCHECK(attribute.component_count == 4);
  for (int i = 0; i < 4; i++) {
    *(destination + i) = component.convert_proc(source, i, false);
  }
}

std::map<VerticesBuilder::AttributeType, VerticesBuilder::AttributeProperties>
    VerticesBuilder::kAttributeTypes = {
        {VerticesBuilder::AttributeType::kPosition,
         {.offset_bytes = offsetof(UnskinnedVerticesBuilder::Vertex, position),
          .size_bytes = sizeof(UnskinnedVerticesBuilder::Vertex::position),
          .component_count = 3,
          .write_proc = PassthroughAttributeWriter}},
        {VerticesBuilder::AttributeType::kNormal,
         {.offset_bytes = offsetof(UnskinnedVerticesBuilder::Vertex, normal),
          .size_bytes = sizeof(UnskinnedVerticesBuilder::Vertex::normal),
          .component_count = 3,
          .write_proc = PassthroughAttributeWriter}},
        {VerticesBuilder::AttributeType::kTangent,
         {.offset_bytes = offsetof(UnskinnedVerticesBuilder::Vertex, tangent),
          .size_bytes = sizeof(UnskinnedVerticesBuilder::Vertex::tangent),
          .component_count = 4,
          .write_proc = PassthroughAttributeWriter}},
        {VerticesBuilder::AttributeType::kTextureCoords,
         {.offset_bytes =
              offsetof(UnskinnedVerticesBuilder::Vertex, texture_coords),
          .size_bytes =
              sizeof(UnskinnedVerticesBuilder::Vertex::texture_coords),
          .component_count = 2,
          .write_proc = PassthroughAttributeWriter}},
        {VerticesBuilder::AttributeType::kColor,
         {.offset_bytes = offsetof(UnskinnedVerticesBuilder::Vertex, color),
          .size_bytes = sizeof(UnskinnedVerticesBuilder::Vertex::color),
          .component_count = 4,
          .write_proc = PassthroughAttributeWriter}},
        {VerticesBuilder::AttributeType::kJoints,
         {.offset_bytes = offsetof(SkinnedVerticesBuilder::Vertex, joints),
          .size_bytes = sizeof(SkinnedVerticesBuilder::Vertex::joints),
          .component_count = 4,
          .write_proc = JointsAttributeWriter}},
        {VerticesBuilder::AttributeType::kWeights,
         {.offset_bytes = offsetof(SkinnedVerticesBuilder::Vertex, weights),
          .size_bytes = sizeof(SkinnedVerticesBuilder::Vertex::weights),
          .component_count = 4,
          .write_proc = JointsAttributeWriter}}};

static std::map<VerticesBuilder::ComponentType,
                VerticesBuilder::ComponentProperties>
    kComponentTypes = {
        {VerticesBuilder::ComponentType::kSignedByte,
         {.size_bytes = sizeof(int8_t), .convert_proc = ToScalar<int8_t>}},
        {VerticesBuilder::ComponentType::kUnsignedByte,
         {.size_bytes = sizeof(int8_t), .convert_proc = ToScalar<uint8_t>}},
        {VerticesBuilder::ComponentType::kSignedShort,
         {.size_bytes = sizeof(int16_t), .convert_proc = ToScalar<int16_t>}},
        {VerticesBuilder::ComponentType::kUnsignedShort,
         {.size_bytes = sizeof(int16_t), .convert_proc = ToScalar<uint16_t>}},
        {VerticesBuilder::ComponentType::kSignedInt,
         {.size_bytes = sizeof(int32_t), .convert_proc = ToScalar<int32_t>}},
        {VerticesBuilder::ComponentType::kUnsignedInt,
         {.size_bytes = sizeof(int32_t), .convert_proc = ToScalar<uint32_t>}},
        {VerticesBuilder::ComponentType::kFloat,
         {.size_bytes = sizeof(float), .convert_proc = ToScalar<float>}},
};

void VerticesBuilder::WriteAttribute(void* destination,
                                     size_t destination_stride_bytes,
                                     AttributeType attribute,
                                     ComponentType component_type,
                                     const void* source,
                                     size_t attribute_stride_bytes,
                                     size_t attribute_count) {
  const ComponentProperties& component_props = kComponentTypes[component_type];
  const AttributeProperties& attribute_props = kAttributeTypes[attribute];
  for (size_t i = 0; i < attribute_count; i++) {
    const uint8_t* src =
        reinterpret_cast<const uint8_t*>(source) + attribute_stride_bytes * i;
    uint8_t* dst = reinterpret_cast<uint8_t*>(destination) +
                   i * destination_stride_bytes + attribute_props.offset_bytes;

    attribute_props.write_proc(reinterpret_cast<Scalar*>(dst), src,
                               component_props, attribute_props);
  }
}

//------------------------------------------------------------------------------
/// UnskinnedVerticesBuilder
///

UnskinnedVerticesBuilder::UnskinnedVerticesBuilder() = default;

UnskinnedVerticesBuilder::~UnskinnedVerticesBuilder() = default;

void UnskinnedVerticesBuilder::WriteFBVertices(
    fb::MeshPrimitiveT& primitive) const {
  auto vertex_buffer = fb::UnskinnedVertexBufferT();
  vertex_buffer.vertices.resize(0);
  for (auto& v : vertices_) {
    vertex_buffer.vertices.push_back(fb::Vertex(
        ToFBVec3(v.position), ToFBVec3(v.normal), ToFBVec4(v.tangent),
        ToFBVec2(v.texture_coords), ToFBColor(v.color)));
  }
  primitive.vertices.Set(std::move(vertex_buffer));
}

void UnskinnedVerticesBuilder::SetAttributeFromBuffer(
    AttributeType attribute,
    ComponentType component_type,
    const void* buffer_start,
    size_t attribute_stride_bytes,
    size_t attribute_count) {
  if (attribute_count > vertices_.size()) {
    vertices_.resize(attribute_count, Vertex());
  }
  WriteAttribute(vertices_.data(),        // destination
                 sizeof(Vertex),          // destination_stride_bytes
                 attribute,               // attribute
                 component_type,          // component_type
                 buffer_start,            // source
                 attribute_stride_bytes,  // attribute_stride_bytes
                 attribute_count);        // attribute_count
}

//------------------------------------------------------------------------------
/// SkinnedVerticesBuilder
///

SkinnedVerticesBuilder::SkinnedVerticesBuilder() = default;

SkinnedVerticesBuilder::~SkinnedVerticesBuilder() = default;

void SkinnedVerticesBuilder::WriteFBVertices(
    fb::MeshPrimitiveT& primitive) const {
  auto vertex_buffer = fb::SkinnedVertexBufferT();
  vertex_buffer.vertices.resize(0);
  for (auto& v : vertices_) {
    auto unskinned_attributes = fb::Vertex(
        ToFBVec3(v.vertex.position), ToFBVec3(v.vertex.normal),
        ToFBVec4(v.vertex.tangent), ToFBVec2(v.vertex.texture_coords),
        ToFBColor(v.vertex.color));
    vertex_buffer.vertices.push_back(fb::SkinnedVertex(
        unskinned_attributes, ToFBVec4(v.joints), ToFBVec4(v.weights)));
  }
  primitive.vertices.Set(std::move(vertex_buffer));
}

void SkinnedVerticesBuilder::SetAttributeFromBuffer(
    AttributeType attribute,
    ComponentType component_type,
    const void* buffer_start,
    size_t attribute_stride_bytes,
    size_t attribute_count) {
  if (attribute_count > vertices_.size()) {
    vertices_.resize(attribute_count, Vertex());
  }
  WriteAttribute(vertices_.data(),        // destination
                 sizeof(Vertex),          // destination_stride_bytes
                 attribute,               // attribute
                 component_type,          // component_type
                 buffer_start,            // source
                 attribute_stride_bytes,  // attribute_stride_bytes
                 attribute_count);        // attribute_count
}

}  // namespace importer
}  // namespace scene
}  // namespace impeller
