/*
 * Copyright © 2023  Behdad Esfahbod
 *
 *  This is part of HarfBuzz, a text shaping library.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 */

#include "hb.hh"

/* This file is a straight port of the following:
 *
 * https://github.com/fonttools/fonttools/blob/f73220816264fc383b8a75f2146e8d69e455d398/Lib/fontTools/varLib/instancer/solver.py
 *
 * See XXX markers for unfinished parts.
 *
 * Where that file returns None for a triple, we return Triple{}.
 * This should be safe.
 */

constexpr static float EPSILON = 1.f / (1 << 14);
constexpr static float MAX_F2DOT14 = float (0x7FFF) / (1 << 14);

struct Triple {

  Triple () :
    minimum (0.f), middle (0.f), maximum (0.f) {}

  Triple (float minimum_, float middle_, float maximum_) :
    minimum (minimum_), middle (middle_), maximum (maximum_) {}

  float minimum;
  float middle;
  float maximum;
};

static inline Triple _reverse_negate(const Triple &v)
{ return {-v.maximum, -v.middle, -v.minimum}; }

using result_item_t = hb_pair_t<float, Triple>;
using result_t = hb_vector_t<result_item_t>;

static inline result_t
_solve (Triple tent, Triple axisLimit, bool negative = false)
{
  float axisMin = axisLimit.minimum;
  float axisDef = axisLimit.middle;
  float axisMax = axisLimit.maximum;
  float lower = tent.minimum;
  float peak  = tent.middle;
  float upper = tent.maximum;

  // Mirror the problem such that axisDef <= peak
  if (axisDef > peak)
  {
    result_t vec = _solve (_reverse_negate (tent),
			   _reverse_negate (axisLimit),
			   !negative);

    for (auto &p : vec)
      p = hb_pair (p.first, _reverse_negate (p.second));

    return vec;
  }
  // axisDef <= peak

  /* case 1: The whole deltaset falls outside the new limit; we can drop it
   *
   *                                          peak
   *  1.........................................o..........
   *                                           / \
   *                                          /   \
   *                                         /     \
   *                                        /       \
   *  0---|-----------|----------|-------- o         o----1
   *    axisMin     axisDef    axisMax   lower     upper
   */
  if (axisMax <= lower && axisMax < peak)
      return result_t{};  // No overlap

  /* case 2: Only the peak and outermost bound fall outside the new limit;
   * we keep the deltaset, update peak and outermost bound and and scale deltas
   * by the scalar value for the restricted axis at the new limit, and solve
   * recursively.
   *
   *                                  |peak
   *  1...............................|.o..........
   *                                  |/ \
   *                                  /   \
   *                                 /|    \
   *                                / |     \
   *  0--------------------------- o  |      o----1
   *                           lower  |      upper
   *                                  |
   *                                axisMax
   *
   * Convert to:
   *
   *  1............................................
   *                                  |
   *                                  o peak
   *                                 /|
   *                                /x|
   *  0--------------------------- o  o upper ----1
   *                           lower  |
   *                                  |
   *                                axisMax
   */
  if (axisMax < peak)
  {
    float mult = 1.f; //XXX supportScalar({"tag": axisMax}, {"tag": tent})
    tent = Triple{lower, axisMax, axisMax};

    result_t vec = _solve (tent, axisLimit);

    for (auto &p : vec)
      p = hb_pair (p.first * mult, p.second);

    return vec;
  }

  // lower <= axisDef <= peak <= axisMax

  float gain = 1.0f; // XXX supportScalar({"tag": axisDef}, {"tag": tent})
  result_t out {hb_pair (gain, Triple{})};

  // First, the positive side

  // outGain is the scalar of axisMax at the tent.
  float outGain = 1.f; // XXX supportScalar({"tag": axisMax}, {"tag": tent})

  /* Case 3a: Gain is more than outGain. The tent down-slope crosses
   * the axis into negative. We have to split it into multiples.
   *
   *                      | peak  |
   *  1...................|.o.....|..............
   *                      |/x\_   |
   *  gain................+....+_.|..............
   *                     /|    |y\|
   *  ................../.|....|..+_......outGain
   *                   /  |    |  | \
   *  0---|-----------o   |    |  |  o----------1
   *    axisMin    lower  |    |  |   upper
   *                      |    |  |
   *                axisDef    |  axisMax
   *                           |
   *                      crossing
   */
  if (gain > outGain)
  {
    // Crossing point on the axis.
    float crossing = peak + ((1 - gain) * (upper - peak) / (1 - outGain));

    Triple loc{peak, peak, crossing};
    float scalar = 1.f;

    // The part before the crossing point.
    out.push (hb_pair (scalar - gain, loc));

    /* The part after the crossing point may use one or two tents,
     * depending on whether upper is before axisMax or not, in one
     * case we need to keep it down to eternity.
     *
     * Case 3a1, similar to case 1neg; just one tent needed, as in
     * the drawing above.
     */
    if (upper >= axisMax)
    {
      Triple loc {crossing, axisMax, axisMax};
      float scalar = 1.f; // XXX supportScalar({"tag": axisMax}, {"tag": tent})

      out.push (hb_pair (scalar - gain, loc));
    }

    /* Case 3a2: Similar to case 2neg; two tents needed, to keep
     * down to eternity.
     *
     *                      | peak             |
     *  1...................|.o................|...
     *                      |/ \_              |
     *  gain................+....+_............|...
     *                     /|    | \xxxxxxxxxxy|
     *                    / |    |  \_xxxxxyyyy|
     *                   /  |    |    \xxyyyyyy|
     *  0---|-----------o   |    |     o-------|--1
     *    axisMin    lower  |    |      upper  |
     *                      |    |             |
     *                axisDef    |             axisMax
     *                           |
     *                      crossing
     */
    else
    {
      // A tent's peak cannot fall on axis default. Nudge it.
      if (upper == axisDef)
	upper += EPSILON;

      // Downslope.
      Triple loc1 {crossing, upper, axisMax};
      float scalar1 = 0.f;

      // Eternity justify.
      Triple loc2 {upper, axisMax, axisMax};
      float scalar2 = 1.f; // supportScalar({"tag": axisMax}, {"tag": tent})

      out.push (hb_pair (scalar1 - gain, loc1));
      out.push (hb_pair (scalar2 - gain, loc2));
    }
  }

  /* Case 3: Outermost limit still fits within F2Dot14 bounds;
   * we keep deltas as is and only scale the axes bounds. Deltas beyond -1.0
   * or +1.0 will never be applied as implementations must clamp to that range.
   *
   * A second tent is needed for cases when gain is positive, though we add it
   * unconditionally and it will be dropped because scalar ends up 0.
   *
   * TODO: See if we can just move upper closer to adjust the slope, instead of
   * second tent.
   *
   *            |           peak |
   *  1.........|............o...|..................
   *            |           /x\  |
   *            |          /xxx\ |
   *            |         /xxxxx\|
   *            |        /xxxxxxx+
   *            |       /xxxxxxxx|\
   *  0---|-----|------oxxxxxxxxx|xo---------------1
   *    axisMin |  lower         | upper
   *            |                |
   *          axisDef          axisMax
   */
  else if (axisDef + (axisMax - axisDef) * 2 >= upper)
  {
    if (!negative && axisDef + (axisMax - axisDef) * MAX_F2DOT14 < upper)
    {
      // we clamp +2.0 to the max F2Dot14 (~1.99994) for convenience
      upper = axisDef + (axisMax - axisDef) * MAX_F2DOT14;
      assert (peak < upper);
    }

    // Special-case if peak is at axisMax.
    if (axisMax == peak)
	upper = peak;

    Triple loc1 {hb_max (axisDef, lower), peak, upper};
    float scalar1 = 1.f;

    Triple loc2 {peak, upper, upper};
    float scalar2 = 0.f;

    // Don't add a dirac delta!
    if (axisDef < upper)
	out.push (hb_pair (scalar1 - gain, loc1));
    if (peak < upper)
	out.push (hb_pair (scalar2 - gain, loc2));
  }

  /* Case 4: New limit doesn't fit; we need to chop into two tents,
   * because the shape of a triangle with part of one side cut off
   * cannot be represented as a triangle itself.
   *
   *            |   peak |
   *  1.........|......o.|...................
   *            |     /x\|
   *            |    |xxy|\_
   *            |   /xxxy|  \_
   *            |  |xxxxy|    \_
   *            |  /xxxxy|      \_
   *  0---|-----|-oxxxxxx|        o----------1
   *    axisMin | lower  |        upper
   *            |        |
   *          axisDef  axisMax
   */
  else
  {
    Triple loc1 {hb_max (axisDef, lower), peak, axisMax};
    float scalar1 = 1.f;

    Triple loc2 {peak, axisMax, axisMax};
    float scalar2 = 1.f; // XXX supportScalar({"tag": axisMax}, {"tag": tent})

    out.push (hb_pair (scalar1 - gain, loc1));
    // Don't add a dirac delta!
    if (peak < axisMax)
      out.push (hb_pair (scalar2 - gain, loc2));
  }

  /* Now, the negative side
   *
   * Case 1neg: Lower extends beyond axisMin: we chop. Simple.
   *
   *                     |   |peak
   *  1..................|...|.o.................
   *                     |   |/ \
   *  gain...............|...+...\...............
   *                     |x_/|    \
   *                     |/  |     \
   *                   _/|   |      \
   *  0---------------o  |   |       o----------1
   *              lower  |   |       upper
   *                     |   |
   *               axisMin   axisDef
   */
  if (lower <= axisMin)
  {
    Triple loc {axisMin, axisMin, axisDef};
    float scalar = 1.f; // XXX supportScalar({"tag": axisMin}, {"tag": tent})

    out.push (hb_pair (scalar - gain, loc));
  }

  /* Case 2neg: Lower is betwen axisMin and axisDef: we add two
   * tents to keep it down all the way to eternity.
   *
   *      |               |peak
   *  1...|...............|.o.................
   *      |               |/ \
   *  gain|...............+...\...............
   *      |yxxxxxxxxxxxxx/|    \
   *      |yyyyyyxxxxxxx/ |     \
   *      |yyyyyyyyyyyx/  |      \
   *  0---|-----------o   |       o----------1
   *    axisMin    lower  |       upper
   *                      |
   *                    axisDef
   */
  else
  {
    // A tent's peak cannot fall on axis default. Nudge it.
    if (lower == axisDef)
      lower -= EPSILON;

    // Downslope.
    Triple loc1 {axisMin, lower, axisDef};
    float scalar1 = 0.f;

    // Eternity justify.
    Triple loc2 {axisMin, axisMin, lower};
    float scalar2 = 0.f;

    out.push (hb_pair (scalar1 - gain, loc1));
    out.push (hb_pair (scalar2 - gain, loc2));
  }

  return out;
}

/* Given a tuple (lower,peak,upper) "tent" and new axis limits
 * (axisMin,axisDefault,axisMax), solves how to represent the tent
 * under the new axis configuration.  All values are in normalized
 * -1,0,+1 coordinate system. Tent values can be outside this range.
 *
 * Return value: a list of tuples. Each tuple is of the form
 * (scalar,tent), where scalar is a multipler to multiply any
 * delta-sets by, and tent is a new tent for that output delta-set.
 * If tent value is Triple{}, that is a special deltaset that should
 * be always-enabled (called "gain").
 */
HB_INTERNAL result_t rebase_tent (Triple tent, Triple axisLimit);

result_t
rebase_tent (Triple tent, Triple axisLimit)
{
  float axisMin = axisLimit.minimum;
  float axisDef = axisLimit.middle;
  float axisMax = axisLimit.maximum;
  float lower = tent.minimum;
  float peak  = tent.middle;
  float upper = tent.maximum;

  assert (-1.f <= axisMin && axisMin <= axisDef && axisDef <= axisMax && axisMax <= +1.f);
  assert (-2.f <= lower && lower <= peak && peak <= upper && upper <= +2.f);
  assert (peak != 0.f);

  result_t sols = _solve (tent, axisLimit);

#if 0
  // XXX
  n = lambda v: normalizeValue(v, axisLimit, extrapolate=True)
  sols = [
      (scalar, (n(v[0]), n(v[1]), n(v[2])) if v is not None else None)
      for scalar, v in sols
      if scalar
  ]
#endif

  return sols;
}
