// 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};
}

static constexpr inline Color DoColorBlend(
    Color d,
    Color s,
    const std::function<Vector3(Vector3, Vector3)>& blend_rgb_func) {
  d = d.Premultiply();
  s = s.Premultiply();
  const Vector3 rgb = blend_rgb_func(ToRGB(d), ToRGB(s));
  const Color blended = Color::Lerp(s, FromRGB(rgb, d.alpha), d.alpha);
  return Color::Lerp(d, blended, s.alpha).Unpremultiply();
}

static constexpr inline Color DoColorBlendComponents(
    Color d,
    Color s,
    const std::function<Scalar(Scalar, Scalar)>& blend_func) {
  d = d.Premultiply();
  s = s.Premultiply();
  const Color blended = Color::Lerp(s,
                                    Color(blend_func(d.red, s.red),      //
                                          blend_func(d.green, s.green),  //
                                          blend_func(d.blue, s.blue),    //
                                          d.alpha),
                                    d.alpha);
  return Color::Lerp(d, blended, s.alpha).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::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
