text: import Point from '../geometry/point';
  import { last } from '../util';
  
  var ShapeMap = {
      l: function(path, options) {
          var parameters = options.parameters;
          var position = options.position;
  
          for (var i = 0; i < parameters.length; i += 2) {
              var point = new Point(parameters[i], parameters[i + 1]);
  
              if (options.isRelative) {
                  point.translateWith(position);
              }
  
              path.lineTo(point.x, point.y);
  
              position.x = point.x;
              position.y = point.y;
          }
      },
  
      c: function(path, options) {
          var parameters = options.parameters;
          var position = options.position;
  
          for (var i = 0; i < parameters.length; i += 6) {
              var controlOut = new Point(parameters[i], parameters[i + 1]);
              var controlIn = new Point(parameters[i + 2], parameters[i + 3]);
              var point = new Point(parameters[i + 4], parameters[i + 5]);
              if (options.isRelative) {
                  controlIn.translateWith(position);
                  controlOut.translateWith(position);
                  point.translateWith(position);
              }
  
              path.curveTo(controlOut, controlIn, point);
  
              position.x = point.x;
              position.y = point.y;
          }
      },
  
      v: function(path, options) {
          var value = options.isRelative ? 0 : options.position.x;
  
          toLineParamaters(options.parameters, true, value);
          this.l(path, options);
      },
  
      h: function(path, options) {
          var value = options.isRelative ? 0 : options.position.y;
  
          toLineParamaters(options.parameters, false, value);
          this.l(path, options);
      },
  
      a: function(path, options) {
          var parameters = options.parameters;
          var position = options.position;
  
          for (var i = 0; i < parameters.length; i += 7) {
              var radiusX = parameters[i];
              var radiusY = parameters[i + 1];
              var rotation = parameters[i + 2];
              var largeArc = parameters[i + 3];
              var swipe = parameters[i + 4];
              var endPoint = new Point(parameters[i + 5], parameters[i + 6]);
  
              if (options.isRelative) {
                  endPoint.translateWith(position);
              }
              if (position.x !== endPoint.x || position.y !== endPoint.y) {
                  path.arcTo(endPoint, radiusX, radiusY, largeArc, swipe, rotation);
  
                  position.x = endPoint.x;
                  position.y = endPoint.y;
              }
          }
      },
  
      s: function(path, options) {
          var parameters = options.parameters;
          var position = options.position;
          var previousCommand = options.previousCommand;
          var lastControlIn;
  
          if (previousCommand === "s" || previousCommand === "c") {
              lastControlIn = last(last(path.paths).segments).controlIn();
          }
  
          for (var i = 0; i < parameters.length; i += 4) {
              var controlIn = new Point(parameters[i], parameters[i + 1]);
              var endPoint = new Point(parameters[i + 2], parameters[i + 3]);
              var controlOut = (void 0);
  
              if (options.isRelative) {
                  controlIn.translateWith(position);
                  endPoint.translateWith(position);
              }
  
              if (lastControlIn) {
                  controlOut = reflectionPoint(lastControlIn, position);
              } else {
                  controlOut = position.clone();
              }
  
              lastControlIn = controlIn;
  
              path.curveTo(controlOut, controlIn, endPoint);
  
              position.x = endPoint.x;
              position.y = endPoint.y;
          }
      },
  
      q: function(path, options) {
          var parameters = options.parameters;
          var position = options.position;
  
          for (var i = 0; i < parameters.length; i += 4) {
              var controlPoint = new Point(parameters[i], parameters[i + 1]);
              var endPoint = new Point(parameters[i + 2], parameters[i + 3]);
  
              if (options.isRelative) {
                  controlPoint.translateWith(position);
                  endPoint.translateWith(position);
              }
  
              var cubicControlPoints = quadraticToCubicControlPoints(position, controlPoint, endPoint);
  
              path.curveTo(cubicControlPoints.controlOut, cubicControlPoints.controlIn, endPoint);
  
              position.x = endPoint.x;
              position.y = endPoint.y;
          }
      },
  
      t: function(path, options) {
          var parameters = options.parameters;
          var position = options.position;
          var previousCommand = options.previousCommand;
          var controlPoint;
  
          if (previousCommand === "q" || previousCommand === "t") {
              var lastSegment = last(last(path.paths).segments);
              controlPoint = lastSegment.controlIn().clone()
                  .translateWith(position.scaleCopy(-1 / 3))
                  .scale(3 / 2);
          }
  
          for (var i = 0; i < parameters.length; i += 2) {
              var endPoint = new Point(parameters[i], parameters[i + 1]);
              if (options.isRelative) {
                  endPoint.translateWith(position);
              }
  
              if (controlPoint) {
                  controlPoint = reflectionPoint(controlPoint, position);
              } else {
                  controlPoint = position.clone();
              }
  
              var cubicControlPoints = quadraticToCubicControlPoints(position, controlPoint, endPoint);
  
              path.curveTo(cubicControlPoints.controlOut, cubicControlPoints.controlIn, endPoint);
  
              position.x = endPoint.x;
              position.y = endPoint.y;
          }
      }
  };
  
  function toLineParamaters(parameters, isVertical, value) {
      var insertPosition = isVertical ? 0 : 1;
  
      for (var i = 0; i < parameters.length; i += 2) {
          parameters.splice(i + insertPosition, 0, value);
      }
  }
  
  function reflectionPoint(point, center) {
      if (point && center) {
          return center.scaleCopy(2).translate(-point.x, -point.y);
      }
  }
  
  var third = 1 / 3;
  
  function quadraticToCubicControlPoints(position, controlPoint, endPoint) {
      var scaledPoint = controlPoint.clone().scale(2 / 3);
      return {
          controlOut: scaledPoint.clone().translateWith(position.scaleCopy(third)),
          controlIn: scaledPoint.translateWith(endPoint.scaleCopy(third))
      };
  }
  
  export default ShapeMap;