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

#include "impeller/geometry/scalar.h"
#include "impeller/geometry/vector.h"

namespace impeller {

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::operator+(const Color& c) const {
  return Color(Vector4(*this) + Vector4(c));
}

Color Color::operator-(const Color& c) const {
  return Color(Vector4(*this) - Vector4(c));
}

Color Color::operator*(Scalar value) const {
  return Color(red * value, green * value, blue * value, alpha * value);
}

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) {}

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

Color Color::BlendColor(const Color& src,
                        const Color& dst,
                        BlendMode blend_mode) {
  static auto apply_rgb_srcover_alpha = [&](auto f) -> Color {
    return Color(f(src.red, dst.red), f(src.green, dst.green),
                 f(src.blue, dst.blue),
                 dst.alpha * (1 - src.alpha) + src.alpha  // srcOver alpha
    );
  };

  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 + dst * (1 - src.alpha);
    case BlendMode::kDestinationOver:
      // r = d + (1-da)*s
      return dst + src * (1 - dst.alpha);
    case BlendMode::kSourceIn:
      // r = s * da
      return src * dst.alpha;
    case BlendMode::kDestinationIn:
      // r = d * sa
      return dst * src.alpha;
    case BlendMode::kSourceOut:
      // r = s * ( 1- da)
      return src * (1 - dst.alpha);
    case BlendMode::kDestinationOut:
      // r = d * (1-sa)
      return dst * (1 - src.alpha);
    case BlendMode::kSourceATop:
      // r = s*da + d*(1-sa)
      return src * dst.alpha + dst * (1 - src.alpha);
    case BlendMode::kDestinationATop:
      // r = d*sa + s*(1-da)
      return dst * src.alpha + src * (1 - dst.alpha);
    case BlendMode::kXor:
      // r = s*(1-da) + d*(1-sa)
      return src * (1 - dst.alpha) + dst * (1 - src.alpha);
    case BlendMode::kPlus:
      // r = min(s + d, 1)
      return Min(src + dst, 1);
    case BlendMode::kModulate:
      // r = s*d
      return src * dst;
    case BlendMode::kScreen: {
      // r = s + d - s*d
      return src + dst - src * dst;
    }
    case BlendMode::kOverlay:
      return apply_rgb_srcover_alpha([&](auto s, auto d) {
        if (d * 2 < dst.alpha) {
          return 2 * s * d;
        }
        return src.alpha * dst.alpha - 2 * (dst.alpha - s) * (src.alpha - d);
      });
    case BlendMode::kDarken: {
      return apply_rgb_srcover_alpha([&](auto s, auto d) {
        return (1 - dst.alpha) * s + (1 - src.alpha) * d + std::min(s, d);
      });
    }
    case BlendMode::kLighten:
      return apply_rgb_srcover_alpha([&](auto s, auto d) {
        return (1 - dst.alpha) * s + (1 - src.alpha) * d + std::max(s, d);
      });
    case BlendMode::kColorDodge:
      return apply_rgb_srcover_alpha([&](auto s, auto d) {
        if (d == 0) {
          return s * (1 - src.alpha);
        }
        if (s == src.alpha) {
          return s + dst.alpha * (1 - src.alpha);
        }
        return src.alpha *
                   std::min(dst.alpha, d * src.alpha / (src.alpha - s)) +
               s * (1 - dst.alpha + dst.alpha * (1 - src.alpha));
      });
    case BlendMode::kColorBurn:
      return apply_rgb_srcover_alpha([&](auto s, auto d) {
        if (s == 0) {
          return dst.alpha * (1 - src.alpha);
        }
        if (d == dst.alpha) {
          return d + s * (1 - dst.alpha);
        }
        // s.a * (d.a - min(d.a, (d.a - s) * s.a/s)) + s * (1-d.a) + d.a * (1 -
        // s.a)
        return src.alpha *
                   (dst.alpha -
                    std::min(dst.alpha, (dst.alpha - d) * src.alpha / s)) +
               s * (1 - dst.alpha) + dst.alpha * (1 - src.alpha);
      });
    case BlendMode::kHardLight:
      return apply_rgb_srcover_alpha([&](auto s, auto d) {
        if (src.alpha >= s * (1 - dst.alpha) + d * (1 - src.alpha) + 2 * s) {
          return 2 * s * d;
        }
        // s.a * d.a - 2 * (d.a - d) * (s.a - s)
        return src.alpha * dst.alpha - 2 * (dst.alpha - d) * (src.alpha - s);
      });
    case BlendMode::kDifference:
      return apply_rgb_srcover_alpha([&](auto s, auto d) {
        // s + d - 2 * min(s * d.a, d * s.a);
        return s + d - 2 * std::min(s * dst.alpha, d * src.alpha);
      });
    case BlendMode::kExclusion:
      return apply_rgb_srcover_alpha([&](auto s, auto d) {
        // s + d - 2 * s * d
        return s + d - 2 * s * d;
      });
    case BlendMode::kMultiply:
      return apply_rgb_srcover_alpha([&](auto s, auto d) {
        // s * (1 - d.a) + d * (1 - s.a) + (s * d)
        return s * (1 - dst.alpha) + d * (1 - src.alpha) + (s * d);
      });
    case BlendMode::kHue:
    case BlendMode::kSaturation:
    case BlendMode::kColor:
    case BlendMode::kLuminosity:
    case BlendMode::kSoftLight:
    default:
      return src + dst * (1 - src.alpha);
  }
}

}  // namespace impeller
