/*
 * Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.ux.material.libmonet.hct;

import com.google.ux.material.libmonet.utils.ColorUtils;
import com.google.ux.material.libmonet.utils.MathUtils;

/**
 * In traditional color spaces, a color can be identified solely by the observer's measurement of
 * the color. Color appearance models such as CAM16 also use information about the environment where
 * the color was observed, known as the viewing conditions.
 *
 * <p>For example, white under the traditional assumption of a midday sun white point is accurately
 * measured as a slightly chromatic blue by CAM16. (roughly, hue 203, chroma 3, lightness 100)
 *
 * <p>This class caches intermediate values of the CAM16 conversion process that depend only on
 * viewing conditions, enabling speed ups.
 */
public final class ViewingConditions {
  /** sRGB-like viewing conditions. */
  public static final ViewingConditions DEFAULT =
      ViewingConditions.defaultWithBackgroundLstar(50.0);

  private final double aw;
  private final double nbb;
  private final double ncb;
  private final double c;
  private final double nc;
  private final double n;
  private final double[] rgbD;
  private final double fl;
  private final double flRoot;
  private final double z;

  public double getAw() {
    return aw;
  }

  public double getN() {
    return n;
  }

  public double getNbb() {
    return nbb;
  }

  double getNcb() {
    return ncb;
  }

  double getC() {
    return c;
  }

  double getNc() {
    return nc;
  }

  public double[] getRgbD() {
    return rgbD;
  }

  double getFl() {
    return fl;
  }

  public double getFlRoot() {
    return flRoot;
  }

  double getZ() {
    return z;
  }

  /**
   * Create ViewingConditions from a simple, physically relevant, set of parameters.
   *
   * @param whitePoint White point, measured in the XYZ color space. default = D65, or sunny day
   *     afternoon
   * @param adaptingLuminance The luminance of the adapting field. Informally, how bright it is in
   *     the room where the color is viewed. Can be calculated from lux by multiplying lux by
   *     0.0586. default = 11.72, or 200 lux.
   * @param backgroundLstar The lightness of the area surrounding the color. measured by L* in
   *     L*a*b*. default = 50.0
   * @param surround A general description of the lighting surrounding the color. 0 is pitch dark,
   *     like watching a movie in a theater. 1.0 is a dimly light room, like watching TV at home at
   *     night. 2.0 means there is no difference between the lighting on the color and around it.
   *     default = 2.0
   * @param discountingIlluminant Whether the eye accounts for the tint of the ambient lighting,
   *     such as knowing an apple is still red in green light. default = false, the eye does not
   *     perform this process on self-luminous objects like displays.
   */
  public static ViewingConditions make(
      double[] whitePoint,
      double adaptingLuminance,
      double backgroundLstar,
      double surround,
      boolean discountingIlluminant) {
    // A background of pure black is non-physical and leads to infinities that represent the idea
    // that any color viewed in pure black can't be seen.
    backgroundLstar = Math.max(0.1, backgroundLstar);
    // Transform white point XYZ to 'cone'/'rgb' responses
    double[][] matrix = Cam16.XYZ_TO_CAM16RGB;
    double[] xyz = whitePoint;
    double rW = (xyz[0] * matrix[0][0]) + (xyz[1] * matrix[0][1]) + (xyz[2] * matrix[0][2]);
    double gW = (xyz[0] * matrix[1][0]) + (xyz[1] * matrix[1][1]) + (xyz[2] * matrix[1][2]);
    double bW = (xyz[0] * matrix[2][0]) + (xyz[1] * matrix[2][1]) + (xyz[2] * matrix[2][2]);
    double f = 0.8 + (surround / 10.0);
    double c =
        (f >= 0.9)
            ? MathUtils.lerp(0.59, 0.69, ((f - 0.9) * 10.0))
            : MathUtils.lerp(0.525, 0.59, ((f - 0.8) * 10.0));
    double d =
        discountingIlluminant
            ? 1.0
            : f * (1.0 - ((1.0 / 3.6) * Math.exp((-adaptingLuminance - 42.0) / 92.0)));
    d = MathUtils.clampDouble(0.0, 1.0, d);
    double nc = f;
    double[] rgbD =
        new double[] {
          d * (100.0 / rW) + 1.0 - d, d * (100.0 / gW) + 1.0 - d, d * (100.0 / bW) + 1.0 - d
        };
    double k = 1.0 / (5.0 * adaptingLuminance + 1.0);
    double k4 = k * k * k * k;
    double k4F = 1.0 - k4;
    double fl = (k4 * adaptingLuminance) + (0.1 * k4F * k4F * Math.cbrt(5.0 * adaptingLuminance));
    double n = (ColorUtils.yFromLstar(backgroundLstar) / whitePoint[1]);
    double z = 1.48 + Math.sqrt(n);
    double nbb = 0.725 / Math.pow(n, 0.2);
    double ncb = nbb;
    double[] rgbAFactors =
        new double[] {
          Math.pow(fl * rgbD[0] * rW / 100.0, 0.42),
          Math.pow(fl * rgbD[1] * gW / 100.0, 0.42),
          Math.pow(fl * rgbD[2] * bW / 100.0, 0.42)
        };

    double[] rgbA =
        new double[] {
          (400.0 * rgbAFactors[0]) / (rgbAFactors[0] + 27.13),
          (400.0 * rgbAFactors[1]) / (rgbAFactors[1] + 27.13),
          (400.0 * rgbAFactors[2]) / (rgbAFactors[2] + 27.13)
        };

    double aw = ((2.0 * rgbA[0]) + rgbA[1] + (0.05 * rgbA[2])) * nbb;
    return new ViewingConditions(n, aw, nbb, ncb, c, nc, rgbD, fl, Math.pow(fl, 0.25), z);
  }

  /**
   * Create sRGB-like viewing conditions with a custom background lstar.
   *
   * <p>Default viewing conditions have a lstar of 50, midgray.
   */
  public static ViewingConditions defaultWithBackgroundLstar(double lstar) {
    return ViewingConditions.make(
        ColorUtils.whitePointD65(),
        (200.0 / Math.PI * ColorUtils.yFromLstar(50.0) / 100.f),
        lstar,
        2.0,
        false);
  }

  /**
   * Parameters are intermediate values of the CAM16 conversion process. Their names are shorthand
   * for technical color science terminology, this class would not benefit from documenting them
   * individually. A brief overview is available in the CAM16 specification, and a complete overview
   * requires a color science textbook, such as Fairchild's Color Appearance Models.
   */
  private ViewingConditions(
      double n,
      double aw,
      double nbb,
      double ncb,
      double c,
      double nc,
      double[] rgbD,
      double fl,
      double flRoot,
      double z) {
    this.n = n;
    this.aw = aw;
    this.nbb = nbb;
    this.ncb = ncb;
    this.c = c;
    this.nc = nc;
    this.rgbD = rgbD;
    this.fl = fl;
    this.flRoot = flRoot;
    this.z = z;
  }
}
