// 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/entity/geometry/vertices_geometry.h"

#include <utility>

#include <utility>
#include "impeller/core/formats.h"

namespace impeller {

// Fan mode isn't natively supported. Unroll into triangle mode by
// manipulating the index array.
//
// In Triangle fan, the first vertex is shared across all triangles, and then
// each sliding window of two vertices plus that first vertex defines a
// triangle.
static std::vector<uint16_t> fromFanIndices(
    const std::vector<Point>& vertices,
    const std::vector<uint16_t>& indices) {
  std::vector<uint16_t> unrolled_indices;

  // Un-fan index buffer if provided.
  if (indices.size() > 0u) {
    if (indices.size() < 3u) {
      return {};
    }

    auto center_point = indices[0];
    for (auto i = 1u; i < indices.size() - 1; i++) {
      unrolled_indices.push_back(center_point);
      unrolled_indices.push_back(indices[i]);
      unrolled_indices.push_back(indices[i + 1]);
    }
  } else {
    if (vertices.size() < 3u) {
      return {};
    }

    // If indices were not provided, create an index buffer that unfans
    // triangles instead of re-writing points, colors, et cetera.
    for (auto i = 1u; i < vertices.size() - 1; i++) {
      unrolled_indices.push_back(0);
      unrolled_indices.push_back(i);
      unrolled_indices.push_back(i + 1);
    }
  }
  return unrolled_indices;
}

/////// Vertices Geometry ///////

VerticesGeometry::VerticesGeometry(std::vector<Point> vertices,
                                   std::vector<uint16_t> indices,
                                   std::vector<Point> texture_coordinates,
                                   std::vector<Color> colors,
                                   Rect bounds,
                                   VertexMode vertex_mode)
    : vertices_(std::move(vertices)),
      colors_(std::move(colors)),
      texture_coordinates_(std::move(texture_coordinates)),
      indices_(std::move(indices)),
      bounds_(bounds),
      vertex_mode_(vertex_mode) {
  NormalizeIndices();
}

PrimitiveType VerticesGeometry::GetPrimitiveType() const {
  switch (vertex_mode_) {
    case VerticesGeometry::VertexMode::kTriangleFan:
      // Unrolled into triangle mode.
      return PrimitiveType::kTriangle;
    case VerticesGeometry::VertexMode::kTriangleStrip:
      return PrimitiveType::kTriangleStrip;
    case VerticesGeometry::VertexMode::kTriangles:
      return PrimitiveType::kTriangle;
  }
}

void VerticesGeometry::NormalizeIndices() {
  // Convert triangle fan if present.
  if (vertex_mode_ == VerticesGeometry::VertexMode::kTriangleFan) {
    indices_ = fromFanIndices(vertices_, indices_);
    return;
  }
}

bool VerticesGeometry::HasVertexColors() const {
  return colors_.size() > 0;
}

bool VerticesGeometry::HasTextureCoordinates() const {
  return texture_coordinates_.size() > 0;
}

std::optional<Rect> VerticesGeometry::GetTextureCoordinateCoverge() const {
  if (!HasTextureCoordinates()) {
    return std::nullopt;
  }
  auto vertex_count = vertices_.size();
  if (vertex_count == 0) {
    return std::nullopt;
  }

  return Rect::MakePointBounds(texture_coordinates_.begin(),
                               texture_coordinates_.end());
}

GeometryResult VerticesGeometry::GetPositionBuffer(
    const ContentContext& renderer,
    const Entity& entity,
    RenderPass& pass) const {
  auto index_count = indices_.size();
  auto vertex_count = vertices_.size();

  size_t total_vtx_bytes = vertex_count * sizeof(float) * 2;
  size_t total_idx_bytes = index_count * sizeof(uint16_t);

  DeviceBufferDescriptor buffer_desc;
  buffer_desc.size = total_vtx_bytes + total_idx_bytes;
  buffer_desc.storage_mode = StorageMode::kHostVisible;

  auto buffer =
      renderer.GetContext()->GetResourceAllocator()->CreateBuffer(buffer_desc);

  if (!buffer->CopyHostBuffer(
          reinterpret_cast<const uint8_t*>(vertices_.data()),
          Range{0, total_vtx_bytes}, 0)) {
    return {};
  }
  if (index_count > 0 &&
      !buffer->CopyHostBuffer(
          reinterpret_cast<uint8_t*>(const_cast<uint16_t*>(indices_.data())),
          Range{0, total_idx_bytes}, total_vtx_bytes)) {
    return {};
  }

  return GeometryResult{
      .type = GetPrimitiveType(),
      .vertex_buffer =
          {
              .vertex_buffer = {.buffer = buffer,
                                .range = Range{0, total_vtx_bytes}},
              .index_buffer = {.buffer = buffer,
                               .range =
                                   Range{total_vtx_bytes, total_idx_bytes}},
              .vertex_count = index_count > 0 ? index_count : vertex_count,
              .index_type =
                  index_count > 0 ? IndexType::k16bit : IndexType::kNone,
          },
      .transform = pass.GetOrthographicTransform() * entity.GetTransform(),
      .prevent_overdraw = false,
  };
}

GeometryResult VerticesGeometry::GetPositionColorBuffer(
    const ContentContext& renderer,
    const Entity& entity,
    RenderPass& pass) {
  using VS = GeometryColorPipeline::VertexShader;

  auto index_count = indices_.size();
  auto vertex_count = vertices_.size();

  std::vector<VS::PerVertexData> vertex_data(vertex_count);
  {
    for (auto i = 0u; i < vertex_count; i++) {
      vertex_data[i] = {
          .position = vertices_[i],
          .color = colors_[i],
      };
    }
  }

  size_t total_vtx_bytes = vertex_data.size() * sizeof(VS::PerVertexData);
  size_t total_idx_bytes = index_count * sizeof(uint16_t);

  DeviceBufferDescriptor buffer_desc;
  buffer_desc.size = total_vtx_bytes + total_idx_bytes;
  buffer_desc.storage_mode = StorageMode::kHostVisible;

  auto buffer =
      renderer.GetContext()->GetResourceAllocator()->CreateBuffer(buffer_desc);

  if (!buffer->CopyHostBuffer(reinterpret_cast<uint8_t*>(vertex_data.data()),
                              Range{0, total_vtx_bytes}, 0)) {
    return {};
  }
  if (index_count > 0 &&
      !buffer->CopyHostBuffer(
          reinterpret_cast<uint8_t*>(const_cast<uint16_t*>(indices_.data())),
          Range{0, total_idx_bytes}, total_vtx_bytes)) {
    return {};
  }

  return GeometryResult{
      .type = GetPrimitiveType(),
      .vertex_buffer =
          {
              .vertex_buffer = {.buffer = buffer,
                                .range = Range{0, total_vtx_bytes}},
              .index_buffer = {.buffer = buffer,
                               .range =
                                   Range{total_vtx_bytes, total_idx_bytes}},
              .vertex_count = index_count > 0 ? index_count : vertex_count,
              .index_type =
                  index_count > 0 ? IndexType::k16bit : IndexType::kNone,
          },
      .transform = pass.GetOrthographicTransform() * entity.GetTransform(),
      .prevent_overdraw = false,
  };
}

GeometryResult VerticesGeometry::GetPositionUVBuffer(
    Rect texture_coverage,
    Matrix effect_transform,
    const ContentContext& renderer,
    const Entity& entity,
    RenderPass& pass) const {
  using VS = TexturePipeline::VertexShader;

  auto index_count = indices_.size();
  auto vertex_count = vertices_.size();
  auto uv_transform =
      texture_coverage.GetNormalizingTransform() * effect_transform;
  auto has_texture_coordinates = HasTextureCoordinates();
  std::vector<VS::PerVertexData> vertex_data(vertex_count);
  {
    for (auto i = 0u; i < vertex_count; i++) {
      auto vertex = vertices_[i];
      auto texture_coord =
          has_texture_coordinates ? texture_coordinates_[i] : vertices_[i];
      auto uv = uv_transform * texture_coord;
      // From experimentation we need to clamp these values to < 1.0 or else
      // there can be flickering.
      vertex_data[i] = {
          .position = vertex,
          .texture_coords =
              Point(std::clamp(uv.x, 0.0f, 1.0f - kEhCloseEnough),
                    std::clamp(uv.y, 0.0f, 1.0f - kEhCloseEnough)),
      };
    }
  }

  size_t total_vtx_bytes = vertex_data.size() * sizeof(VS::PerVertexData);
  size_t total_idx_bytes = index_count * sizeof(uint16_t);

  DeviceBufferDescriptor buffer_desc;
  buffer_desc.size = total_vtx_bytes + total_idx_bytes;
  buffer_desc.storage_mode = StorageMode::kHostVisible;

  auto buffer =
      renderer.GetContext()->GetResourceAllocator()->CreateBuffer(buffer_desc);

  if (!buffer->CopyHostBuffer(reinterpret_cast<uint8_t*>(vertex_data.data()),
                              Range{0, total_vtx_bytes}, 0)) {
    return {};
  }
  if (index_count > 0u &&
      !buffer->CopyHostBuffer(
          reinterpret_cast<uint8_t*>(const_cast<uint16_t*>(indices_.data())),
          Range{0, total_idx_bytes}, total_vtx_bytes)) {
    return {};
  }

  return GeometryResult{
      .type = GetPrimitiveType(),
      .vertex_buffer =
          {
              .vertex_buffer = {.buffer = buffer,
                                .range = Range{0, total_vtx_bytes}},
              .index_buffer = {.buffer = buffer,
                               .range =
                                   Range{total_vtx_bytes, total_idx_bytes}},
              .vertex_count = index_count > 0 ? index_count : vertex_count,
              .index_type =
                  index_count > 0 ? IndexType::k16bit : IndexType::kNone,
          },
      .transform = pass.GetOrthographicTransform() * entity.GetTransform(),
      .prevent_overdraw = false,
  };
}

GeometryVertexType VerticesGeometry::GetVertexType() const {
  if (HasVertexColors()) {
    return GeometryVertexType::kColor;
  }
  if (HasTextureCoordinates()) {
    return GeometryVertexType::kUV;
  }

  return GeometryVertexType::kPosition;
}

std::optional<Rect> VerticesGeometry::GetCoverage(
    const Matrix& transform) const {
  return bounds_.TransformBounds(transform);
}

}  // namespace impeller
