//
// Copyright 2014 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
//

part of charted.core.interpolators;

/// [Interpolator] accepts [t], such that 0.0 < t < 1.0 and returns
/// a value in a pre-defined range.
typedef Interpolator<S> = S Function(num t);

/// [InterpolatorGenerator] accepts two parameters [a], [b] and returns an
/// [Interpolator] for transitioning from [a] to [b]
typedef InterpolatorGenerator<T, S> = Interpolator<S> Function(T a, T b);

/// List of registered interpolators - [createInterpolatorFromRegistry]
/// iterates through this list from backwards and the first non-null
/// interpolate function is returned to the caller.
List<InterpolatorGenerator> _interpolators = [createInterpolatorByType];

/// Returns a default interpolator between values [a] and [b]. Unless
/// more interpolators are added, one of the internal implementations are
/// selected by the type of [a] and [b].
Interpolator createInterpolatorFromRegistry(a, b) {
  Interpolator fn;
  int i = _interpolators.length;
  while (--i >= 0 && fn == null) {
    fn = _interpolators[i](a, b);
  }
  return fn;
}

/// Creates an interpolator based on the type of [a] and [b].
///
/// Usage note: Use this method only when type of [a] and [b] are not known.
///     When used, this function will prevent tree shaking of all built-in
///     interpolators.
Interpolator createInterpolatorByType(a, b) {
  if (a is List && b is List) {
    return createListInterpolator(a, b);
  } else if (a is Map && b is Map) {
    return createMapInterpolator(a, b);
  } else if (a is String && b is String) {
    return createStringInterpolator(a, b);
  } else if (a is num && b is num) {
    return createNumberInterpolator(a, b);
  } else if (a is Color && b is Color) {
    return createRgbColorInterpolator(a, b);
  } else {
    return (t) => (t <= 0.5) ? a : b;
  }
}

//
// Implementations of InterpolatorGenerator
//

/// Generate a numeric interpolator between numbers [a] and [b]
Interpolator<num> createNumberInterpolator(num a, num b) {
  b -= a;
  return (t) => a + b * t;
}

/// Generate a rounded number interpolator between numbers [a] and [b]
Interpolator<num> createRoundedNumberInterpolator(num a, num b) {
  b -= a;
  return (t) => (a + b * t).round();
}

/// Generate an interpolator between two strings [a] and [b].
///
/// The interpolator will interpolate all the number pairs in both strings
/// that have same number of numeric parts.  The function assumes the non
/// number part of the string to be identical and would use string [b] for
/// merging the non numeric part of the strings.
///
/// Eg: Interpolate between $100.0 and $150.0
Interpolator<String> createStringInterpolator(String a, String b) {
  if (a == null || b == null) return (num t) => b;

  // See if both A and B represent colors as RGB or HEX strings.
  // If yes, use color interpolators
  if (Color.isRgbColorString(a) && Color.isRgbColorString(b)) {
    return createRgbColorInterpolator(
        new Color.fromRgbString(a), new Color.fromRgbString(b));
  }

  // See if both A and B represent colors as HSL strings.
  // If yes, use color interpolators.
  if (Color.isHslColorString(a) && Color.isHslColorString(b)) {
    return createHslColorInterpolator(
        new Color.fromHslString(a), new Color.fromHslString(b));
  }

  var numberRegEx = new RegExp(r'[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?');
  var numMatchesInA = numberRegEx.allMatches(a);
  var numMatchesInB = numberRegEx.allMatches(b);
  List<String> stringParts = [];
  List<String> numberPartsInA = [];
  List<String> numberPartsInB = [];
  List<Interpolator<num>> interpolators = [];
  int s0 = 0;

  numberPartsInA.addAll(numMatchesInA.map((m) => m.group(0)));

  for (Match m in numMatchesInB) {
    stringParts.add(b.substring(s0, m.start));
    numberPartsInB.add(m.group(0));
    s0 = m.end;
  }

  if (s0 < b.length) stringParts.add(b.substring(s0));

  int numberLength = math.min(numberPartsInA.length, numberPartsInB.length);
  int maxLength = math.max(numberPartsInA.length, numberPartsInB.length);
  for (var i = 0; i < numberLength; i++) {
    interpolators.add(createNumberInterpolator(
        num.parse(numberPartsInA[i]), num.parse(numberPartsInB[i])));
  }
  if (numberPartsInA.length < numberPartsInB.length) {
    for (var i = numberLength; i < maxLength; i++) {
      interpolators.add(createNumberInterpolator(
          num.parse(numberPartsInB[i]), num.parse(numberPartsInB[i])));
    }
  }

  return (num t) {
    StringBuffer sb = new StringBuffer();
    for (var i = 0; i < stringParts.length; i++) {
      sb.write(stringParts[i]);
      if (interpolators.length > i) {
        sb.write(interpolators[i](t));
      }
    }
    return sb.toString();
  };
}

/// Generate an interpolator for RGB values.
Interpolator<String> createRgbColorInterpolator(Color a, Color b) {
  if (a == null || b == null) return (num t) => b.toRgbaString();
  var ar = a.r, ag = a.g, ab = a.b, br = b.r - ar, bg = b.g - ag, bb = b.b - ab;

  return (num t) => new Color.fromRgba((ar + br * t).round(),
          (ag + bg * t).round(), (ab + bb * t).round(), 1.0)
      .toRgbaString();
}

/// Generate an interpolator using HSL color system converted to Hex string.
Interpolator<String> createHslColorInterpolator(Color a, Color b) {
  if (a == null || b == null) return (num t) => b.toHslaString();
  var ah = a.h, as = a.s, al = a.l, bh = b.h - ah, bs = b.s - as, bl = b.l - al;

  return (num t) => new Color.fromHsla((ah + bh * t).round(),
          (as + bs * t).round(), (al + bl * t).round(), 1.0)
      .toHslaString();
}

/// Generates an interpolator to interpolate each element between lists
/// [a] and [b] using registered interpolators.
Interpolator<List> createListInterpolator(List a, List b) {
  if (a == null || b == null) return (t) => b;
  var x = <Interpolator>[],
      aLength = a.length,
      numInterpolated = b.length,
      output =
          new List<dynamic>.filled(math.max(aLength, numInterpolated), null);
  num n0 = math.min(aLength, numInterpolated);
  int i;

  for (i = 0; i < n0; i++) x.add(createInterpolatorFromRegistry(a[i], b[i]));
  for (; i < aLength; ++i) output[i] = a[i];
  for (; i < numInterpolated; ++i) output[i] = b[i];

  return (num t) {
    for (i = 0; i < n0; ++i) output[i] = x[i](t);
    return output;
  };
}

/// Generates an interpolator to interpolate each value on [a] to [b] using
/// registered interpolators.
Interpolator<Map> createMapInterpolator(Map a, Map b) {
  if (a == null || b == null) return (t) => b;
  var interpolatorsMap = new Map(),
      output = new Map(),
      aKeys = a.keys.toList(),
      bKeys = b.keys.toList();

  aKeys.forEach((k) {
    if (b[k] != null) {
      interpolatorsMap[k] = (createInterpolatorFromRegistry(a[k], b[k]));
    } else {
      output[k] = a[k];
    }
  });

  bKeys.forEach((k) {
    if (output[k] == null) {
      output[k] = b[k];
    }
  });

  return (t) {
    interpolatorsMap.forEach((k, v) => output[k] = v(t));
    return output;
  };
}

/// Returns the interpolator that interpolators two transform strings
/// [a] and [b] by their translate, rotate, scale and skewX parts.
Interpolator<String> createTransformInterpolator(String a, String b) {
  if (a == null || b == null) return (t) => b;
  var numRegExStr = r'[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?',
      numberRegEx = new RegExp(numRegExStr),
      translateRegEx =
          new RegExp(r'translate\(' + '$numRegExStr,$numRegExStr' + r'\)'),
      scaleRegEx =
          new RegExp(r'scale\(' + numRegExStr + r',' + numRegExStr + r'\)'),
      rotateRegEx = new RegExp(r'rotate\(' + numRegExStr + r'(deg)?\)'),
      skewRegEx = new RegExp(r'skewX\(' + numRegExStr + r'(deg)?\)'),
      translateA = translateRegEx.firstMatch(a),
      scaleA = scaleRegEx.firstMatch(a),
      rotateA = rotateRegEx.firstMatch(a),
      skewA = skewRegEx.firstMatch(a),
      translateB = translateRegEx.firstMatch(b),
      scaleB = scaleRegEx.firstMatch(b),
      rotateB = rotateRegEx.firstMatch(b),
      skewB = skewRegEx.firstMatch(b);

  List<num> numSetA = [], numSetB = [];
  String tempStr;

  // translate
  if (translateA != null) {
    tempStr = a.substring(translateA.start, translateA.end);
    var match = numberRegEx.allMatches(tempStr);
    for (Match m in match) {
      numSetA.add(num.parse(m.group(0)));
    }
  } else {
    numSetA.addAll(const [0, 0]);
  }

  if (translateB != null) {
    tempStr = b.substring(translateB.start, translateB.end);
    var match = numberRegEx.allMatches(tempStr);
    for (Match m in match) {
      numSetB.add(num.parse(m.group(0)));
    }
  } else {
    numSetB.addAll(const [0, 0]);
  }

  // scale
  if (scaleA != null) {
    tempStr = a.substring(scaleA.start, scaleA.end);
    var match = numberRegEx.allMatches(tempStr);
    for (Match m in match) {
      numSetA.add(num.parse(m.group(0)));
    }
  } else {
    numSetA.addAll(const [1, 1]);
  }

  if (scaleB != null) {
    tempStr = b.substring(scaleB.start, scaleB.end);
    var match = numberRegEx.allMatches(tempStr);
    for (Match m in match) {
      numSetB.add(num.parse(m.group(0)));
    }
  } else {
    numSetB.addAll(const [1, 1]);
  }

  // rotate
  if (rotateA != null) {
    tempStr = a.substring(rotateA.start, rotateA.end);
    var match = numberRegEx.firstMatch(tempStr);
    numSetA.add(num.parse(match.group(0)));
  } else {
    numSetA.add(0);
  }

  if (rotateB != null) {
    tempStr = b.substring(rotateB.start, rotateB.end);
    var match = numberRegEx.firstMatch(tempStr);
    numSetB.add(num.parse(match.group(0)));
  } else {
    numSetB.add(0);
  }

  // rotate < 180 degree
  if (numSetA[4] != numSetB[4]) {
    if (numSetA[4] - numSetB[4] > 180) {
      numSetB[4] += 360;
    } else if (numSetB[4] - numSetA[4] > 180) {
      numSetA[4] += 360;
    }
  }

  // skew
  if (skewA != null) {
    tempStr = a.substring(skewA.start, skewA.end);
    var match = numberRegEx.firstMatch(tempStr);
    numSetA.add(num.parse(match.group(0)));
  } else {
    numSetA.add(0);
  }

  if (skewB != null) {
    tempStr = b.substring(skewB.start, skewB.end);
    var match = numberRegEx.firstMatch(tempStr);
    numSetB.add(num.parse(match.group(0)));
  } else {
    numSetB.add(0);
  }

  return (num t) {
    return 'translate(${createNumberInterpolator(numSetA[0], numSetB[0])(t)},'
        '${createNumberInterpolator(numSetA[1], numSetB[1])(t)})'
        'scale(${createNumberInterpolator(numSetA[2], numSetB[2])(t)},'
        '${createNumberInterpolator(numSetA[3], numSetB[3])(t)})'
        'rotate(${createNumberInterpolator(numSetA[4], numSetB[4])(t)})'
        'skewX(${createNumberInterpolator(numSetA[5], numSetB[5])(t)})';
  };
}

/// Returns the interpolator that interpolators zoom list [a] to [b]. Zoom
/// lists are described by triple elements [ux0, uy0, w0] and [ux1, uy1, w1].
Interpolator<List<num>> createZoomInterpolator(List a, List b) {
  if (a == null || b == null) return (t) => b;
  assert(a.length == b.length && a.length == 3);

  var sqrt2 = math.SQRT2, param2 = 2, param4 = 4;

  num ux0 = a[0], uy0 = a[1], w0 = a[2], ux1 = b[0], uy1 = b[1], w1 = b[2];

  num dx = ux1 - ux0,
      dy = uy1 - uy0,
      d2 = dx * dx + dy * dy,
      d1 = math.sqrt(d2),
      b0 = (w1 * w1 - w0 * w0 + param4 * d2) / (2 * w0 * param2 * d1),
      b1 = (w1 * w1 - w0 * w0 - param4 * d2) / (2 * w1 * param2 * d1),
      r0 = math.log(math.sqrt(b0 * b0 + 1) - b0),
      r1 = math.log(math.sqrt(b1 * b1 + 1) - b1),
      dr = r1 - r0,
      S = ((!dr.isNaN) ? dr : math.log(w1 / w0)) / sqrt2;

  return (num t) {
    var s = t * S;
    if (!dr.isNaN) {
      // General case.
      var coshr0 = cosh(r0),
          u = w0 / (param2 * d1) * (coshr0 * tanh(sqrt2 * s + r0) - sinh(r0));
      return [ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / cosh(sqrt2 * s + r0)];
    }
    // Special case for u0 ~= u1.
    return <num>[ux0 + t * dx, uy0 + t * dy, w0 * math.exp(sqrt2 * s)];
  };
}

/// Reverse interpolator for a number.
Interpolator<num> uninterpolateNumber(num a, num b) {
  b = 1 / (b - a);
  return (x) => (x - a) * b;
}

/// Reverse interpolator for a clamped number.
Interpolator<num> uninterpolateClamp(num a, num b) {
  b = 1 / (b - a);
  return (x) => math.max(0, math.min(1, (x - a) * b));
}
