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

#include <algorithm>
#include <cmath>
#include <functional>
#include <sstream>
#include <type_traits>

#include "impeller/base/strings.h"
#include "impeller/geometry/constants.h"
#include "impeller/geometry/scalar.h"
#include "impeller/geometry/vector.h"

namespace impeller {

#define _IMPELLER_ASSERT_BLEND_MODE(blend_mode)                            \
  auto enum_##blend_mode = static_cast<std::underlying_type_t<BlendMode>>( \
      BlendMode::k##blend_mode);                                           \
  if (i != enum_##blend_mode) {                                            \
    return false;                                                          \
  }                                                                        \
  ++i;

static constexpr inline bool ValidateBlendModes() {
  std::underlying_type_t<BlendMode> i = 0;
  // Ensure the order of the blend modes match.
  IMPELLER_FOR_EACH_BLEND_MODE(_IMPELLER_ASSERT_BLEND_MODE)
  // Ensure the total number of blend modes match.
  if (i - 1 !=
      static_cast<std::underlying_type_t<BlendMode>>(BlendMode::kLast)) {
    return false;
  }
  return true;
}
static_assert(ValidateBlendModes(),
              "IMPELLER_FOR_EACH_BLEND_MODE must match impeller::BlendMode.");

#define _IMPELLER_BLEND_MODE_NAME_LIST(blend_mode) #blend_mode,

static constexpr const char* kBlendModeNames[] = {
    IMPELLER_FOR_EACH_BLEND_MODE(_IMPELLER_BLEND_MODE_NAME_LIST)};

const char* BlendModeToString(BlendMode blend_mode) {
  return kBlendModeNames[static_cast<std::underlying_type_t<BlendMode>>(
      blend_mode)];
}

ColorHSB ColorHSB::FromRGB(Color rgb) {
  Scalar R = rgb.red;
  Scalar G = rgb.green;
  Scalar B = rgb.blue;

  Scalar v = 0.0;
  Scalar x = 0.0;
  Scalar f = 0.0;

  int64_t i = 0;

  x = fmin(R, G);
  x = fmin(x, B);

  v = fmax(R, G);
  v = fmax(v, B);

  if (v == x) {
    return ColorHSB(0.0, 0.0, v, rgb.alpha);
  }

  f = (R == x) ? G - B : ((G == x) ? B - R : R - G);
  i = (R == x) ? 3 : ((G == x) ? 5 : 1);

  return ColorHSB(((i - f / (v - x)) / 6.0), (v - x) / v, v, rgb.alpha);
}

Color ColorHSB::ToRGBA() const {
  Scalar h = hue * 6.0;
  Scalar s = saturation;
  Scalar v = brightness;

  Scalar m = 0.0;
  Scalar n = 0.0;
  Scalar f = 0.0;

  int64_t i = 0;

  if (h == 0) {
    h = 0.01;
  }

  if (h == 0.0) {
    return Color(v, v, v, alpha);
  }

  i = static_cast<int64_t>(floor(h));

  f = h - i;

  if (!(i & 1)) {
    f = 1 - f;
  }

  m = v * (1 - s);
  n = v * (1 - s * f);

  switch (i) {
    case 6:
    case 0:
      return Color(v, n, m, alpha);
    case 1:
      return Color(n, v, m, alpha);
    case 2:
      return Color(m, v, n, alpha);
    case 3:
      return Color(m, n, v, alpha);
    case 4:
      return Color(n, m, v, alpha);
    case 5:
      return Color(v, m, n, alpha);
  }
  return Color(0, 0, 0, alpha);
}

Color::Color(const ColorHSB& hsbColor) : Color(hsbColor.ToRGBA()) {}

Color::Color(const Vector4& value)
    : red(value.x), green(value.y), blue(value.z), alpha(value.w) {}

static constexpr inline Color Min(Color c, float threshold) {
  return Color(std::min(c.red, threshold), std::min(c.green, threshold),
               std::min(c.blue, threshold), std::min(c.alpha, threshold));
}

// The following HSV utilities correspond to the W3C blend definitions
// implemented in: impeller/compiler/shader_lib/impeller/blending.glsl

static constexpr inline Scalar Luminosity(Vector3 color) {
  return color.x * 0.3f + color.y * 0.59f + color.z * 0.11f;
}

static constexpr inline Vector3 ClipColor(Vector3 color) {
  Scalar lum = Luminosity(color);
  Scalar mn = std::min(std::min(color.x, color.y), color.z);
  Scalar mx = std::max(std::max(color.x, color.y), color.z);
  // `lum - mn` and `mx - lum` will always be >= 0 in the following conditions,
  // so adding a tiny value is enough to make these divisions safe.
  if (mn < 0.0f) {
    color = lum + (((color - lum) * lum) / (lum - mn + kEhCloseEnough));
  }
  if (mx > 1.0) {
    color =
        lum + (((color - lum) * (1.0f - lum)) / (mx - lum + kEhCloseEnough));
  }
  return color;
}

static constexpr inline Vector3 SetLuminosity(Vector3 color,
                                              Scalar luminosity) {
  Scalar relative_lum = luminosity - Luminosity(color);
  return ClipColor(color + relative_lum);
}

static constexpr inline Scalar Saturation(Vector3 color) {
  return std::max(std::max(color.x, color.y), color.z) -
         std::min(std::min(color.x, color.y), color.z);
}

static constexpr inline Vector3 SetSaturation(Vector3 color,
                                              Scalar saturation) {
  Scalar mn = std::min(std::min(color.x, color.y), color.z);
  Scalar mx = std::max(std::max(color.x, color.y), color.z);
  return (mn < mx) ? ((color - mn) * saturation) / (mx - mn) : Vector3();
}

static constexpr inline Vector3 ComponentChoose(Vector3 a,
                                                Vector3 b,
                                                Vector3 value,
                                                Scalar cutoff) {
  return Vector3(value.x > cutoff ? b.x : a.x,  //
                 value.y > cutoff ? b.y : a.y,  //
                 value.z > cutoff ? b.z : a.z   //
  );
}

static constexpr inline Vector3 ToRGB(Color color) {
  return {color.red, color.green, color.blue};
}

static constexpr inline Color FromRGB(Vector3 color, Scalar alpha) {
  return {color.x, color.y, color.z, alpha};
}

/// Composite a blended color onto the destination.
/// All three parameters are unpremultiplied. Returns a premultiplied result.
///
/// This routine is the same as `IPApplyBlendedColor` in the Impeller shader
/// library.
static constexpr inline Color ApplyBlendedColor(Color dst,
                                                Color src,
                                                Vector3 blend_result) {
  dst = dst.Premultiply();
  src =
      // Use the blended color for areas where the source and destination
      // colors overlap.
      FromRGB(blend_result, src.alpha * dst.alpha).Premultiply() +
      // Use the original source color for any remaining non-overlapping areas.
      src.Premultiply() * (1.0f - dst.alpha);

  // Source-over composite the blended source color atop the destination.
  return src + dst * (1.0f - src.alpha);
}

static constexpr inline Color DoColorBlend(
    Color dst,
    Color src,
    const std::function<Vector3(Vector3, Vector3)>& blend_rgb_func) {
  const Vector3 blend_result = blend_rgb_func(ToRGB(dst), ToRGB(src));
  return ApplyBlendedColor(dst, src, blend_result).Unpremultiply();
}

static constexpr inline Color DoColorBlendComponents(
    Color dst,
    Color src,
    const std::function<Scalar(Scalar, Scalar)>& blend_func) {
  Vector3 blend_result = Vector3(blend_func(dst.red, src.red),      //
                                 blend_func(dst.green, src.green),  //
                                 blend_func(dst.blue, src.blue));   //
  return ApplyBlendedColor(dst, src, blend_result).Unpremultiply();
}

Color Color::Blend(Color src, BlendMode blend_mode) const {
  Color dst = *this;

  switch (blend_mode) {
    case BlendMode::kClear:
      return Color::BlackTransparent();
    case BlendMode::kSource:
      return src;
    case BlendMode::kDestination:
      return dst;
    case BlendMode::kSourceOver:
      // r = s + (1-sa)*d
      return (src.Premultiply() + dst.Premultiply() * (1 - src.alpha))
          .Unpremultiply();
    case BlendMode::kDestinationOver:
      // r = d + (1-da)*s
      return (dst.Premultiply() + src.Premultiply() * (1 - dst.alpha))
          .Unpremultiply();
    case BlendMode::kSourceIn:
      // r = s * da
      return (src.Premultiply() * dst.alpha).Unpremultiply();
    case BlendMode::kDestinationIn:
      // r = d * sa
      return (dst.Premultiply() * src.alpha).Unpremultiply();
    case BlendMode::kSourceOut:
      // r = s * ( 1- da)
      return (src.Premultiply() * (1 - dst.alpha)).Unpremultiply();
    case BlendMode::kDestinationOut:
      // r = d * (1-sa)
      return (dst.Premultiply() * (1 - src.alpha)).Unpremultiply();
    case BlendMode::kSourceATop:
      // r = s*da + d*(1-sa)
      return (src.Premultiply() * dst.alpha +
              dst.Premultiply() * (1 - src.alpha))
          .Unpremultiply();
    case BlendMode::kDestinationATop:
      // r = d*sa + s*(1-da)
      return (dst.Premultiply() * src.alpha +
              src.Premultiply() * (1 - dst.alpha))
          .Unpremultiply();
    case BlendMode::kXor:
      // r = s*(1-da) + d*(1-sa)
      return (src.Premultiply() * (1 - dst.alpha) +
              dst.Premultiply() * (1 - src.alpha))
          .Unpremultiply();
    case BlendMode::kPlusAdvanced:
      [[fallthrough]];
    case BlendMode::kPlus:
      // r = min(s + d, 1)
      return (Min(src.Premultiply() + dst.Premultiply(), 1)).Unpremultiply();
    case BlendMode::kModulate:
      // r = s*d
      return (src.Premultiply() * dst.Premultiply()).Unpremultiply();
    case BlendMode::kScreen: {
      return DoColorBlend(dst, src, [](Vector3 d, Vector3 s) -> Vector3 {
        return s + d - s * d;
      });
    }
    case BlendMode::kOverlay:
      return DoColorBlend(dst, src, [](Vector3 d, Vector3 s) -> Vector3 {
        // The same as HardLight, but with the source and destination reversed.
        Vector3 screen_src = 2.0 * d - 1.0;
        Vector3 screen = screen_src + s - screen_src * s;
        return ComponentChoose(s * (2.0 * d),  //
                               screen,         //
                               d,              //
                               0.5);
      });
    case BlendMode::kDarken:
      return DoColorBlend(
          dst, src, [](Vector3 d, Vector3 s) -> Vector3 { return d.Min(s); });
    case BlendMode::kLighten:
      return DoColorBlend(
          dst, src, [](Vector3 d, Vector3 s) -> Vector3 { return d.Max(s); });
    case BlendMode::kColorDodge:
      return DoColorBlendComponents(dst, src, [](Scalar d, Scalar s) -> Scalar {
        if (d < kEhCloseEnough) {
          return 0.0f;
        }
        if (1.0 - s < kEhCloseEnough) {
          return 1.0f;
        }
        return std::min(1.0f, d / (1.0f - s));
      });
    case BlendMode::kColorBurn:
      return DoColorBlendComponents(dst, src, [](Scalar d, Scalar s) -> Scalar {
        if (1.0 - d < kEhCloseEnough) {
          return 1.0f;
        }
        if (s < kEhCloseEnough) {
          return 0.0f;
        }
        return 1.0f - std::min(1.0f, (1.0f - d) / s);
      });
    case BlendMode::kHardLight:
      return DoColorBlend(dst, src, [](Vector3 d, Vector3 s) -> Vector3 {
        Vector3 screen_src = 2.0 * s - 1.0;
        Vector3 screen = screen_src + d - screen_src * d;
        return ComponentChoose(d * (2.0 * s),  //
                               screen,         //
                               s,              //
                               0.5);
      });
    case BlendMode::kSoftLight:
      return DoColorBlend(dst, src, [](Vector3 d, Vector3 s) -> Vector3 {
        Vector3 D = ComponentChoose(((16.0 * d - 12.0) * d + 4.0) * d,  //
                                    Vector3(std::sqrt(d.x), std::sqrt(d.y),
                                            std::sqrt(d.z)),  //
                                    d,                        //
                                    0.25);
        return ComponentChoose(d - (1.0 - 2.0 * s) * d * (1.0 - d),  //
                               d + (2.0 * s - 1.0) * (D - d),        //
                               s,                                    //
                               0.5);
      });
    case BlendMode::kDifference:
      return DoColorBlend(dst, src, [](Vector3 d, Vector3 s) -> Vector3 {
        return (d - s).Abs();
      });
    case BlendMode::kExclusion:
      return DoColorBlend(dst, src, [](Vector3 d, Vector3 s) -> Vector3 {
        return d + s - 2.0f * d * s;
      });
    case BlendMode::kMultiply:
      return DoColorBlend(
          dst, src, [](Vector3 d, Vector3 s) -> Vector3 { return d * s; });
    case BlendMode::kHue: {
      return DoColorBlend(dst, src, [](Vector3 d, Vector3 s) -> Vector3 {
        return SetLuminosity(SetSaturation(s, Saturation(d)), Luminosity(d));
      });
    }
    case BlendMode::kSaturation:
      return DoColorBlend(dst, src, [](Vector3 d, Vector3 s) -> Vector3 {
        return SetLuminosity(SetSaturation(d, Saturation(s)), Luminosity(d));
      });
    case BlendMode::kColor:
      return DoColorBlend(dst, src, [](Vector3 d, Vector3 s) -> Vector3 {
        return SetLuminosity(s, Luminosity(d));
      });
    case BlendMode::kLuminosity:
      return DoColorBlend(dst, src, [](Vector3 d, Vector3 s) -> Vector3 {
        return SetLuminosity(d, Luminosity(s));
      });
  }
}

Color Color::ApplyColorMatrix(const ColorMatrix& color_matrix) const {
  auto* c = color_matrix.array;
  return Color(
             c[0] * red + c[1] * green + c[2] * blue + c[3] * alpha + c[4],
             c[5] * red + c[6] * green + c[7] * blue + c[8] * alpha + c[9],
             c[10] * red + c[11] * green + c[12] * blue + c[13] * alpha + c[14],
             c[15] * red + c[16] * green + c[17] * blue + c[18] * alpha + c[19])
      .Clamp01();
}

Color Color::LinearToSRGB() const {
  static auto conversion = [](Scalar component) {
    if (component <= 0.0031308) {
      return component * 12.92;
    }
    return 1.055 * pow(component, (1.0 / 2.4)) - 0.055;
  };

  return Color(conversion(red), conversion(green), conversion(blue), alpha);
}

Color Color::SRGBToLinear() const {
  static auto conversion = [](Scalar component) {
    if (component <= 0.04045) {
      return component / 12.92;
    }
    return pow((component + 0.055) / 1.055, 2.4);
  };

  return Color(conversion(red), conversion(green), conversion(blue), alpha);
}

std::string ColorToString(const Color& color) {
  return SPrintF("R=%.1f,G=%.1f,B=%.1f,A=%.1f",  //
                 color.red,                      //
                 color.green,                    //
                 color.blue,                     //
                 color.alpha                     //
  );
}

}  // namespace impeller
