// 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 <algorithm>

#include "flutter/fml/logging.h"
#include "impeller/geometry/gradient.h"

namespace impeller {

static void AppendColor(const Color& color, GradientData* data) {
  auto converted = color.ToR8G8B8A8();
  data->color_bytes.push_back(converted[0]);
  data->color_bytes.push_back(converted[1]);
  data->color_bytes.push_back(converted[2]);
  data->color_bytes.push_back(converted[3]);
}

GradientData CreateGradientBuffer(const std::vector<Color>& colors,
                                  const std::vector<Scalar>& stops) {
  FML_DCHECK(stops.size() == colors.size());

  uint32_t texture_size;
  if (stops.size() == 2) {
    texture_size = colors.size();
  } else {
    auto minimum_delta = 1.0;
    for (size_t i = 1; i < stops.size(); i++) {
      auto value = stops[i] - stops[i - 1];
      // Smaller than kEhCloseEnough
      if (value < 0.0001) {
        continue;
      }
      if (value < minimum_delta) {
        minimum_delta = value;
      }
    }
    // Avoid creating textures that are absurdly large due to stops that are
    // very close together.
    // TODO(jonahwilliams): this should use a platform specific max texture
    // size.
    texture_size = std::min(
        static_cast<uint32_t>(std::round(1.0 / minimum_delta)) + 1, 1024u);
  }
  GradientData data = {
      .color_bytes = {},
      .texture_size = texture_size,
  };
  data.color_bytes.reserve(texture_size * 4);

  if (texture_size == colors.size() && colors.size() <= 1024) {
    for (auto i = 0u; i < colors.size(); i++) {
      AppendColor(colors[i], &data);
    }
  } else {
    Color previous_color = colors[0];
    auto previous_stop = 0.0;
    auto previous_color_index = 0;

    // The first index is always equal to the first color, exactly.
    AppendColor(previous_color, &data);

    for (auto i = 1u; i < texture_size - 1; i++) {
      auto scaled_i = i / (texture_size - 1.0);
      Color next_color = colors[previous_color_index + 1];
      auto next_stop = stops[previous_color_index + 1];
      // We're almost exactly equal to the next stop.
      if (ScalarNearlyEqual(scaled_i, next_stop)) {
        AppendColor(next_color, &data);

        previous_color = next_color;
        previous_stop = next_stop;
        previous_color_index += 1;
      } else if (scaled_i < next_stop) {
        // We're still between the current stop and the next stop.
        auto t = (scaled_i - previous_stop) / (next_stop - previous_stop);
        auto mixed_color = Color::lerp(previous_color, next_color, t);

        AppendColor(mixed_color, &data);
      } else {
        // We've slightly overshot the previous stop.
        previous_color = next_color;
        previous_stop = next_stop;
        previous_color_index += 1;
        next_color = colors[previous_color_index + 1];
        auto next_stop = stops[previous_color_index + 1];

        auto t = (scaled_i - previous_stop) / (next_stop - previous_stop);
        auto mixed_color = Color::lerp(previous_color, next_color, t);

        AppendColor(mixed_color, &data);
      }
    }
    // The last index is always equal to the last color, exactly.
    AppendColor(colors.back(), &data);
  }
  return data;
}

std::optional<std::vector<Color>> CreateGradientColors(
    const std::vector<Color>& colors,
    const std::vector<Scalar>& stops) {
  FML_DCHECK(stops.size() == colors.size());

  if (stops.size() == 2) {
    // Use original buffer.
    return std::nullopt;
  }

  auto minimum_delta = 1.0;
  for (size_t i = 1; i < stops.size(); i++) {
    auto value = stops[i] - stops[i - 1];
    // Smaller than kEhCloseEnough
    if (value < 0.0001) {
      continue;
    }
    if (value < minimum_delta) {
      minimum_delta = value;
    }
  }
  // Avoid creating buffers that are absurdly large due to stops that are
  // very close together.
  uint32_t color_count = std::min(
      static_cast<uint32_t>(std::round(1.0 / minimum_delta)) + 1, 1024u);

  if (color_count == colors.size()) {
    // Use original buffer.
    return std::nullopt;
  }

  std::vector<Color> data;
  data.reserve(color_count);

  Color previous_color = colors[0];
  auto previous_stop = 0.0;
  auto previous_color_index = 0;

  // The first index is always equal to the first color, exactly.
  data.push_back(colors[0]);

  for (auto i = 1u; i < color_count - 1; i++) {
    auto scaled_i = i / (color_count - 1.0);
    Color next_color = colors[previous_color_index + 1];
    auto next_stop = stops[previous_color_index + 1];
    // We're almost exactly equal to the next stop.
    if (ScalarNearlyEqual(scaled_i, next_stop)) {
      data.push_back(next_color);

      previous_color = next_color;
      previous_stop = next_stop;
      previous_color_index += 1;
    } else if (scaled_i < next_stop) {
      // We're still between the current stop and the next stop.
      auto t = (scaled_i - previous_stop) / (next_stop - previous_stop);
      auto mixed_color = Color::lerp(previous_color, next_color, t);

      data.push_back(mixed_color);
    } else {
      // We've slightly overshot the previous stop.
      previous_color = next_color;
      previous_stop = next_stop;
      previous_color_index += 1;
      next_color = colors[previous_color_index + 1];
      auto next_stop = stops[previous_color_index + 1];

      auto t = (scaled_i - previous_stop) / (next_stop - previous_stop);
      auto mixed_color = Color::lerp(previous_color, next_color, t);
      data.push_back(mixed_color);
    }
  }
  // The last index is always equal to the last color, exactly.
  data.push_back(colors.back());
  return data;
}

}  // namespace impeller
