part of skysprites;

enum EffectLineWidthMode {
  linear,
  barrel,
}

enum EffectLineAnimationMode {
  none,
  scroll,
  random,
}

class EffectLine extends Node {

  EffectLine({
    this.texture: null,
    this.transferMode: ui.TransferMode.dstOver,
    List<Point> points,
    this.widthMode : EffectLineWidthMode.linear,
    this.minWidth: 10.0,
    this.maxWidth: 10.0,
    this.widthGrowthSpeed: 0.0,
    this.animationMode: EffectLineAnimationMode.none,
    this.scrollSpeed: 0.1,
    double scrollStart: 0.0,
    this.fadeDuration: null,
    this.fadeAfterDelay: null,
    this.textureLoopLength: null,
    this.simplify: true,
    ColorSequence colorSequence
  }) {
    if (points == null) this.points = [];
    else this.points = points;

    _colorSequence = colorSequence;
    if (_colorSequence == null)
      _colorSequence = new ColorSequence.fromStartAndEndColor(
        new Color(0xffffffff),
        new Color(0xffffffff));

    _offset = scrollStart;

    _painter = new TexturedLinePainter(points, _colors, _widths, texture);
    _painter.textureLoopLength = textureLoopLength;
  }

  final Texture texture;

  final ui.TransferMode transferMode;

  final EffectLineWidthMode widthMode;
  final double minWidth;
  final double maxWidth;
  final double widthGrowthSpeed;

  final EffectLineAnimationMode animationMode;
  final double scrollSpeed;
  ColorSequence _colorSequence;
  ColorSequence get colorSequence => _colorSequence;

  List<Point> _points;

  List<Point> get points => _points;

  set points(List<Point> points) {
    _points = points;
    _pointAges = [];
    for (int i = 0; i < _points.length; i++) {
      _pointAges.add(0.0);
    }
  }

  List<double> _pointAges;
  List<Color> _colors;
  List<double> _widths;

  final double fadeDuration;
  final double fadeAfterDelay;

  final double textureLoopLength;

  final bool simplify;

  TexturedLinePainter _painter;
  double _offset = 0.0;

  void update(double dt) {
    // Update scrolling position
    if (animationMode == EffectLineAnimationMode.scroll) {
      _offset += dt * scrollSpeed;
      _offset %= 1.0;
    } else if (animationMode == EffectLineAnimationMode.random) {
      _offset = randomDouble();
    }

    // Update age of line points and remove if neccesasry
    if (fadeDuration != null && fadeAfterDelay != null) {
      // Increase age of points
      for (int i = _points.length - 1; i >= 0; i--) {
        _pointAges[i] += dt;
      }

      // Check if the first/oldest point should be removed
      while(_points.length > 0 && _pointAges[0] > (fadeDuration + fadeAfterDelay)) {
        // Update scroll if it isn't the last and only point that is about to removed
        if (_points.length > 1 && textureLoopLength != null) {
          double dist = GameMath.distanceBetweenPoints(_points[0], _points[1]);
          _offset = (_offset - (dist / textureLoopLength)) % 1.0;
          if (_offset < 0.0) _offset += 1;
        }

        // Remove the point
        _pointAges.removeAt(0);
        _points.removeAt(0);
      }
    }
  }

  void paint(PaintingCanvas canvas) {
    if (points.length < 2) return;

    _painter.points = points;

    // Calculate colors
    List<double> stops = _painter.calculatedTextureStops;

    List<Color> colors = [];
    for (int i = 0; i < stops.length; i++) {
      double stop = stops[i];
      Color color = _colorSequence.colorAtPosition(stop);

      if (fadeDuration != null && fadeAfterDelay != null) {
        double age = _pointAges[i];
        if (age > fadeAfterDelay) {
          double fade = 1.0 - (age - fadeAfterDelay) / fadeDuration;
          int alpha = (color.alpha * fade).toInt().clamp(0, 255);
          color = new Color.fromARGB(alpha, color.red, color.green, color.blue);
        }
      }
      colors.add(color);
    }
    _painter.colors = colors;

    // Calculate widths
    List<double> widths = [];
    for (int i = 0; i < stops.length; i++) {
      double stop = stops[i];
      double growth = math.max(widthGrowthSpeed * _pointAges[i], 0.0);
      if (widthMode == EffectLineWidthMode.linear) {
        double width = minWidth + (maxWidth - minWidth) * stop + growth;
        widths.add(width);
      } else if (widthMode == EffectLineWidthMode.barrel) {
        double width = minWidth + math.sin(stop * math.PI) * (maxWidth - minWidth) + growth;
        widths.add(width);
      }
    }
    _painter.widths = widths;

    _painter.textureStopOffset = _offset;

    _painter.paint(canvas);
  }

  void addPoint(Point point) {
    // Skip duplicate points
    if (points.length > 0 && point.x == points[points.length - 1].x && point.y == points[points.length - 1].y)
      return;

    if (simplify && points.length >= 2 && GameMath.distanceBetweenPoints(point, points[points.length - 2]) < 10.0) {
      // Check if we should remove last point before adding the new one

      // Calculate the square distance from the middle point to the line of the
      // new point and the second to last point
      double dist2 = _distToSeqment2(
        points[points.length - 1],
        point,
        points[points.length - 2]
      );

      // If the point is on the line, remove it
      if (dist2 < 1.0) {
        _points.removeAt(_points.length - 1);
      }
    }

    // Add point and point's age
    _points.add(point);
    _pointAges.add(0.0);
  }

  double _sqr(double x) => x * x;

  double _dist2(Point v, Point w) => _sqr(v.x - w.x) + _sqr(v.y - w.y);

  double _distToSeqment2(Point p, Point v, Point w) {
    double l2 = _dist2(v, w);
    if (l2 == 0.0) return _dist2(p, v);
    double t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;
    if (t < 0) return _dist2(p, v);
    if (t > 1) return _dist2(p, w);
    return _dist2(p, new Point(v.x + t * (w.x - v.x), v.y + t * (w.y - v.y)));
  }
}
