// Copyright 2014 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.

import 'dart:io';
import 'dart:math';

import 'package:collection/collection.dart';
import 'package:meta/meta.dart';
import 'package:vector_math/vector_math_64.dart';
import 'package:xml/xml.dart' hide parse;

// String to use for a single indentation.
const String kIndent = '  ';

/// Represents an animation, and provides logic to generate dart code for it.
class Animation {
  const Animation(this.size, this.paths);

  factory Animation.fromFrameData(List<FrameData> frames) {
    _validateFramesData(frames);
    final Point<double> size = frames[0].size;
    final List<PathAnimation> paths = <PathAnimation>[];
    for (int i = 0; i < frames[0].paths.length; i += 1) {
      paths.add(PathAnimation.fromFrameData(frames, i));
    }
    return Animation(size, paths);
  }

  /// The size of the animation (width, height) in pixels.
  final Point<double> size;

  /// List of paths in the animation.
  final List<PathAnimation> paths;

  static void _validateFramesData(List<FrameData> frames) {
    final Point<double> size = frames[0].size;
    final int numPaths = frames[0].paths.length;
    for (int i = 0; i < frames.length; i += 1) {
      final FrameData frame = frames[i];
      if (size != frame.size)
        throw Exception(
            'All animation frames must have the same size,\n'
            'first frame size was: (${size.x}, ${size.y})\n'
            'frame $i size was: (${frame.size.x}, ${frame.size.y})'
        );
      if (numPaths != frame.paths.length)
        throw Exception(
            'All animation frames must have the same number of paths,\n'
            'first frame has $numPaths paths\n'
            'frame $i has ${frame.paths.length} paths'
        );
    }
  }

  String toDart(String className, String varName) {
    final StringBuffer sb = StringBuffer();
    sb.write('const $className $varName = const $className(\n');
    sb.write('${kIndent}const Size(${size.x}, ${size.y}),\n');
    sb.write('${kIndent}const <_PathFrames>[\n');
    for (final PathAnimation path in paths)
      sb.write(path.toDart());
    sb.write('$kIndent],\n');
    sb.write(');');
    return sb.toString();
  }
}

/// Represents the animation of a single path.
class PathAnimation {
  const PathAnimation(this.commands, {required this.opacities});

  factory PathAnimation.fromFrameData(List<FrameData> frames, int pathIdx) {
    if (frames.isEmpty)
      return const PathAnimation(<PathCommandAnimation>[], opacities: <double>[]);

    final List<PathCommandAnimation> commands = <PathCommandAnimation>[];
    for (int commandIdx = 0; commandIdx < frames[0].paths[pathIdx].commands.length; commandIdx += 1) {
      final int numPointsInCommand = frames[0].paths[pathIdx].commands[commandIdx].points.length;
      final List<List<Point<double>>> points = List<List<Point<double>>>.filled(numPointsInCommand, <Point<double>>[]);
      final String commandType = frames[0].paths[pathIdx].commands[commandIdx].type;
      for (int i = 0; i < frames.length; i += 1) {
        final FrameData frame = frames[i];
        final String currentCommandType = frame.paths[pathIdx].commands[commandIdx].type;
        if (commandType != currentCommandType)
          throw Exception(
              'Paths must be built from the same commands in all frames '
              "command $commandIdx at frame 0 was of type '$commandType' "
              "command $commandIdx at frame $i was of type '$currentCommandType'"
          );
        for (int j = 0; j < numPointsInCommand; j += 1)
          points[j].add(frame.paths[pathIdx].commands[commandIdx].points[j]);
      }
      commands.add(PathCommandAnimation(commandType, points));
    }

    final List<double> opacities =
      frames.map<double>((FrameData d) => d.paths[pathIdx].opacity).toList();

    return PathAnimation(commands, opacities: opacities);
  }

  /// List of commands for drawing the path.
  final List<PathCommandAnimation> commands;
  /// The path opacity for each animation frame.
  final List<double> opacities;

  @override
  String toString() {
    return 'PathAnimation(commands: $commands, opacities: $opacities)';
  }

  String toDart() {
    final StringBuffer sb = StringBuffer();
    sb.write('${kIndent * 2}const _PathFrames(\n');
    sb.write('${kIndent * 3}opacities: const <double>[\n');
    for (final double opacity in opacities)
      sb.write('${kIndent * 4}$opacity,\n');
    sb.write('${kIndent * 3}],\n');
    sb.write('${kIndent * 3}commands: const <_PathCommand>[\n');
    for (final PathCommandAnimation command in commands)
      sb.write(command.toDart());
    sb.write('${kIndent * 3}],\n');
    sb.write('${kIndent * 2}),\n');
    return sb.toString();
  }
}

/// Represents the animation of a single path command.
class PathCommandAnimation {
  const PathCommandAnimation(this.type, this.points);

  /// The command type.
  final String type;

  /// A matrix with the command's points in different frames.
  ///
  /// points[i][j] is the i-th point of the command at frame j.
  final List<List<Point<double>>> points;

  @override
  String toString() {
    return 'PathCommandAnimation(type: $type, points: $points)';
  }

  String toDart() {
    String dartCommandClass;
    switch (type) {
      case 'M':
        dartCommandClass = '_PathMoveTo';
        break;
      case 'C':
        dartCommandClass = '_PathCubicTo';
        break;
      case 'L':
        dartCommandClass = '_PathLineTo';
        break;
      case 'Z':
        dartCommandClass = '_PathClose';
        break;
      default:
        throw Exception('unsupported path command: $type');
    }
    final StringBuffer sb = StringBuffer();
    sb.write('${kIndent * 4}const $dartCommandClass(\n');
    for (final List<Point<double>> pointFrames in points) {
      sb.write('${kIndent * 5}const <Offset>[\n');
      for (final Point<double> point in pointFrames)
        sb.write('${kIndent * 6}const Offset(${point.x}, ${point.y}),\n');
      sb.write('${kIndent * 5}],\n');
    }
    sb.write('${kIndent * 4}),\n');
    return sb.toString();
  }
}

/// Interprets some subset of an SVG file.
///
/// Recursively goes over the SVG tree, applying transforms and opacities,
/// and build a FrameData which is a flat representation of the paths in the SVG
/// file, after applying transformations and converting relative coordinates to
/// absolute.
///
/// This does not support the SVG specification, but is just built to
/// support SVG files exported by a specific tool the motion design team is
/// using.
FrameData interpretSvg(String svgFilePath) {
  final File file = File(svgFilePath);
  final String fileData = file.readAsStringSync();
  final XmlElement svgElement = _extractSvgElement(XmlDocument.parse(fileData));
  final double width = parsePixels(_extractAttr(svgElement, 'width')).toDouble();
  final double height = parsePixels(_extractAttr(svgElement, 'height')).toDouble();

  final List<SvgPath> paths =
    _interpretSvgGroup(svgElement.children, _Transform());
  return FrameData(Point<double>(width, height), paths);
}

List<SvgPath> _interpretSvgGroup(List<XmlNode> children, _Transform transform) {
  final List<SvgPath> paths = <SvgPath>[];
  for (final XmlNode node in children) {
    if (node.nodeType != XmlNodeType.ELEMENT)
      continue;
    final XmlElement element = node as XmlElement;

    if (element.name.local == 'path') {
      paths.add(SvgPath.fromElement(element)._applyTransform(transform));
    }

    if (element.name.local == 'g') {
      double opacity = transform.opacity;
      if (_hasAttr(element, 'opacity'))
        opacity *= double.parse(_extractAttr(element, 'opacity'));

      Matrix3 transformMatrix = transform.transformMatrix;
      if (_hasAttr(element, 'transform'))
        transformMatrix = transformMatrix.multiplied(
          _parseSvgTransform(_extractAttr(element, 'transform')));

      final _Transform subtreeTransform = _Transform(
        transformMatrix: transformMatrix,
        opacity: opacity,
      );
      paths.addAll(_interpretSvgGroup(element.children, subtreeTransform));
    }
  }
  return paths;
}

// Given a points list in the form e.g: "25.0, 1.0 12.0, 12.0 23.0, 9.0" matches
// the coordinated of the first point and the rest of the string, for the
// example above:
// group 1 will match "25.0"
// group 2 will match "1.0"
// group 3 will match "12.0, 12.0 23.0, 9.0"
//
// Commas are optional.
final RegExp _pointMatcher = RegExp(r'^ *([\-\.0-9]+) *,? *([\-\.0-9]+)(.*)');

/// Parse a string with a list of points, e.g:
/// '25.0, 1.0 12.0, 12.0 23.0, 9.0' will be parsed to:
/// [Point(25.0, 1.0), Point(12.0, 12.0), Point(23.0, 9.0)].
///
/// Commas are optional.
List<Point<double>> parsePoints(String points) {
  String unParsed = points;
  final List<Point<double>> result = <Point<double>>[];
  while (unParsed.isNotEmpty && _pointMatcher.hasMatch(unParsed)) {
    final Match m = _pointMatcher.firstMatch(unParsed)!;
    result.add(Point<double>(
        double.parse(m.group(1)!),
        double.parse(m.group(2)!),
    ));
    unParsed = m.group(3)!;
  }
  return result;
}

/// Data for a single animation frame.
@immutable
class FrameData {
  const FrameData(this.size, this.paths);

  final Point<double> size;
  final List<SvgPath> paths;

  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType)
      return false;
    return other is FrameData
        && other.size == size
        && const ListEquality<SvgPath>().equals(other.paths, paths);
  }

  @override
  int get hashCode => Object.hash(size, Object.hashAll(paths));

  @override
  String toString() {
    return 'FrameData(size: $size, paths: $paths)';
  }
}

/// Represents an SVG path element.
@immutable
class SvgPath {
  const SvgPath(this.id, this.commands, {this.opacity = 1.0});

  final String id;
  final List<SvgPathCommand> commands;
  final double opacity;

  static const String _pathCommandAtom = r' *([a-zA-Z]) *([\-\.0-9 ,]*)';
  static final RegExp _pathCommandValidator = RegExp('^($_pathCommandAtom)*\$');
  static final RegExp _pathCommandMatcher = RegExp(_pathCommandAtom);

  static SvgPath fromElement(XmlElement pathElement) {
    assert(pathElement.name.local == 'path');
    final String id = _extractAttr(pathElement, 'id');
    final String dAttr = _extractAttr(pathElement, 'd');
    final List<SvgPathCommand> commands = <SvgPathCommand>[];
    final SvgPathCommandBuilder commandsBuilder = SvgPathCommandBuilder();
    if (!_pathCommandValidator.hasMatch(dAttr))
      throw Exception('illegal or unsupported path d expression: $dAttr');
    for (final Match match in _pathCommandMatcher.allMatches(dAttr)) {
      final String commandType = match.group(1)!;
      final String pointStr = match.group(2)!;
      commands.add(commandsBuilder.build(commandType, parsePoints(pointStr)));
    }
    return SvgPath(id, commands);
  }

  SvgPath _applyTransform(_Transform transform) {
    final List<SvgPathCommand> transformedCommands =
      commands.map<SvgPathCommand>((SvgPathCommand c) => c._applyTransform(transform)).toList();
    return SvgPath(id, transformedCommands, opacity: opacity * transform.opacity);
  }

  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType)
      return false;
    return other is SvgPath
        && other.id == id
        && other.opacity == opacity
        && const ListEquality<SvgPathCommand>().equals(other.commands, commands);
  }

  @override
  int get hashCode => Object.hash(id, Object.hashAll(commands), opacity);

  @override
  String toString() {
    return 'SvgPath(id: $id, opacity: $opacity, commands: $commands)';
  }

}

/// Represents a single SVG path command from an SVG d element.
///
/// This class normalizes all the 'd' commands into a single type, that has
/// a command type and a list of points.
///
/// Some examples of how d commands translated to SvgPathCommand:
///   * "M 0.0, 1.0" => SvgPathCommand('M', [Point(0.0, 1.0)])
///   * "Z" => SvgPathCommand('Z', [])
///   * "C 1.0, 1.0 2.0, 2.0 3.0, 3.0" SvgPathCommand('C', [Point(1.0, 1.0),
///      Point(2.0, 2.0), Point(3.0, 3.0)])
@immutable
class SvgPathCommand {
  const SvgPathCommand(this.type, this.points);

  /// The command type.
  final String type;

  /// List of points used by this command.
  final List<Point<double>> points;

  SvgPathCommand _applyTransform(_Transform transform) {
    final List<Point<double>> transformedPoints =
    _vector3ArrayToPoints(
        transform.transformMatrix.applyToVector3Array(
            _pointsToVector3Array(points)
        )
    );
    return SvgPathCommand(type, transformedPoints);
  }

  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType)
      return false;
    return other is SvgPathCommand
        && other.type == type
        && const ListEquality<Point<double>>().equals(other.points, points);
  }

  @override
  int get hashCode => Object.hash(type, Object.hashAll(points));

  @override
  String toString() {
    return 'SvgPathCommand(type: $type, points: $points)';
  }
}

class SvgPathCommandBuilder {
  static const Map<String, void> kRelativeCommands = <String, void> {
    'c': null,
    'l': null,
    'm': null,
    't': null,
    's': null,
  };

  Point<double> lastPoint = const Point<double>(0.0, 0.0);
  Point<double> subPathStartPoint = const Point<double>(0.0, 0.0);

  SvgPathCommand build(String type, List<Point<double>> points) {
    List<Point<double>> absPoints = points;
    if (_isRelativeCommand(type)) {
      absPoints = points.map<Point<double>>((Point<double> p) => p + lastPoint).toList();
    }

    if (type == 'M' || type == 'm')
      subPathStartPoint = absPoints.last;

    if (type == 'Z' || type == 'z')
      lastPoint = subPathStartPoint;
    else
      lastPoint = absPoints.last;

    return SvgPathCommand(type.toUpperCase(), absPoints);
  }

  static bool _isRelativeCommand(String type) {
    return kRelativeCommands.containsKey(type);
  }
}

List<double> _pointsToVector3Array(List<Point<double>> points) {
  final List<double> result = List<double>.filled(points.length * 3, 0.0);
  for (int i = 0; i < points.length; i += 1) {
    result[i * 3] = points[i].x;
    result[i * 3 + 1] = points[i].y;
    result[i * 3 + 2] = 1.0;
  }
  return result;
}

List<Point<double>> _vector3ArrayToPoints(List<double> vector) {
  final int numPoints = (vector.length / 3).floor();
  final List<Point<double>> points = <Point<double>>[
    for (int i = 0; i < numPoints; i += 1)
      Point<double>(vector[i*3], vector[i*3 + 1]),
  ];
  return points;
}

/// Represents a transformation to apply on an SVG subtree.
///
/// This includes more transforms than the ones described by the SVG transform
/// attribute, e.g opacity.
class _Transform {

  /// Constructs a new _Transform, default arguments create a no-op transform.
  _Transform({Matrix3? transformMatrix, this.opacity = 1.0}) :
      transformMatrix = transformMatrix ?? Matrix3.identity();

  final Matrix3 transformMatrix;
  final double opacity;

  _Transform applyTransform(_Transform transform) {
    return _Transform(
        transformMatrix: transform.transformMatrix.multiplied(transformMatrix),
        opacity: transform.opacity * opacity,
    );
  }
}


const String _transformCommandAtom = r' *([^(]+)\(([^)]*)\)';
final RegExp _transformValidator = RegExp('^($_transformCommandAtom)*\$');
final RegExp _transformCommand = RegExp(_transformCommandAtom);

Matrix3 _parseSvgTransform(String transform) {
  if (!_transformValidator.hasMatch(transform))
    throw Exception('illegal or unsupported transform: $transform');
  final Iterable<Match> matches =_transformCommand.allMatches(transform).toList().reversed;
  Matrix3 result = Matrix3.identity();
  for (final Match m in matches) {
    final String command = m.group(1)!;
    final String params = m.group(2)!;
    if (command == 'translate') {
      result = _parseSvgTranslate(params).multiplied(result);
      continue;
    }
    if (command == 'scale') {
      result = _parseSvgScale(params).multiplied(result);
      continue;
    }
    if (command == 'rotate') {
      result = _parseSvgRotate(params).multiplied(result);
      continue;
    }
    throw Exception('unimplemented transform: $command');
  }
  return result;
}

final RegExp _valueSeparator = RegExp('( *, *| +)');

Matrix3 _parseSvgTranslate(String paramsStr) {
  final List<String> params = paramsStr.split(_valueSeparator);
  assert(params.isNotEmpty);
  assert(params.length <= 2);
  final double x = double.parse(params[0]);
  final double y = params.length < 2 ? 0 : double.parse(params[1]);
  return _matrix(1.0, 0.0, 0.0, 1.0, x, y);
}

Matrix3 _parseSvgScale(String paramsStr) {
  final List<String> params = paramsStr.split(_valueSeparator);
  assert(params.isNotEmpty);
  assert(params.length <= 2);
  final double x = double.parse(params[0]);
  final double y = params.length < 2 ? 0 : double.parse(params[1]);
  return _matrix(x, 0.0, 0.0, y, 0.0, 0.0);
}

Matrix3 _parseSvgRotate(String paramsStr) {
  final List<String> params = paramsStr.split(_valueSeparator);
  assert(params.length == 1);
  final double a = radians(double.parse(params[0]));
  return _matrix(cos(a), sin(a), -sin(a), cos(a), 0.0, 0.0);
}

Matrix3 _matrix(double a, double b, double c, double d, double e, double f) {
  return Matrix3(a, b, 0.0, c, d, 0.0, e, f, 1.0);
}

// Matches a pixels expression e.g "14px".
// First group is just the number.
final RegExp _pixelsExp = RegExp(r'^([0-9]+)px$');

/// Parses a pixel expression, e.g "14px", and returns the number.
/// Throws an [ArgumentError] if the given string doesn't match the pattern.
int parsePixels(String pixels) {
  if (!_pixelsExp.hasMatch(pixels))
    throw ArgumentError(
      "illegal pixels expression: '$pixels'"
      ' (the tool currently only support pixel units).');
  return int.parse(_pixelsExp.firstMatch(pixels)!.group(1)!);
}

String _extractAttr(XmlElement element, String name) {
  try {
    return element.attributes.singleWhere((XmlAttribute x) => x.name.local == name)
        .value;
  } catch (e) {
    throw ArgumentError(
        "Can't find a single '$name' attributes in ${element.name}, "
        'attributes were: ${element.attributes}'
    );
  }
}

bool _hasAttr(XmlElement element, String name) {
  return element.attributes.where((XmlAttribute a) => a.name.local == name).isNotEmpty;
}

XmlElement _extractSvgElement(XmlDocument document) {
  return document.children.singleWhere(
    (XmlNode node) => node.nodeType  == XmlNodeType.ELEMENT &&
      _asElement(node).name.local == 'svg'
  ) as XmlElement;
}

XmlElement _asElement(XmlNode node) => node as XmlElement;
