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

#include <algorithm>

#include "flutter/fml/logging.h"

namespace impeller {

// TODO(b-luk): this should use a platform specific max texture size.
// https://github.com/flutter/flutter/issues/191820
static constexpr uint32_t kMaxGradientTextureSize = 1024;

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;
    // Avoid creating textures that are absurdly large due to stops that are
    // very close together.
    auto minimum_allowable_delta = 1.0 / (kMaxGradientTextureSize - 1.0);
    for (size_t i = 1; i < stops.size(); i++) {
      auto value = stops[i] - stops[i - 1];
      if (value <= minimum_allowable_delta) {
        minimum_delta = minimum_allowable_delta;
        break;
      }
      if (value < minimum_delta) {
        minimum_delta = value;
      }
    }
    texture_size = static_cast<uint32_t>(std::round(1.0 / minimum_delta)) + 1;
  }
  GradientData result;
  if (texture_size == colors.size() &&
      colors.size() <= kMaxGradientTextureSize) {
    result.colors = colors;
  } else {
    result.colors.reserve(texture_size);
    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.
    result.colors.push_back(previous_color);

    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)) {
        result.colors.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);

        result.colors.push_back(mixed_color);
      } else {
        // We've passed the next stop. Advance to the next stop interval.
        // Decrement `i` to re-evaluate the current texel against the new
        // interval. When there are overlapping or zero-delta stops, this branch
        // evaluates repeatedly until the overlap is passed.
        previous_color = next_color;
        previous_stop = next_stop;
        previous_color_index += 1;
        i--;
      }
    }
    // The last index is always equal to the last color, exactly.
    result.colors.push_back(colors.back());
  }
  return result;
}

}  // namespace impeller
