'use strict';

var React = require('react');

function _interopNamespaceDefault(e) {
  var n = Object.create(null);
  if (e) {
    Object.keys(e).forEach(function (k) {
      if (k !== 'default') {
        var d = Object.getOwnPropertyDescriptor(e, k);
        Object.defineProperty(n, k, d.get ? d : {
          enumerable: true,
          get: function () { return e[k]; }
        });
      }
    });
  }
  n.default = e;
  return Object.freeze(n);
}

var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);

function _assertThisInitialized(e) {
  if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  return e;
}
function _callSuper(t, o, e) {
  return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e));
}
function _classCallCheck(a, n) {
  if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
}
function _defineProperties(e, r) {
  for (var t = 0; t < r.length; t++) {
    var o = r[t];
    o.enumerable = o.enumerable || false, o.configurable = true, "value" in o && (o.writable = true), Object.defineProperty(e, _toPropertyKey(o.key), o);
  }
}
function _createClass(e, r, t) {
  return r && _defineProperties(e.prototype, r), Object.defineProperty(e, "prototype", {
    writable: false
  }), e;
}
function _defineProperty(e, r, t) {
  return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
    value: t,
    enumerable: true,
    configurable: true,
    writable: true
  }) : e[r] = t, e;
}
function _getPrototypeOf(t) {
  return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) {
    return t.__proto__ || Object.getPrototypeOf(t);
  }, _getPrototypeOf(t);
}
function _inherits(t, e) {
  if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function");
  t.prototype = Object.create(e && e.prototype, {
    constructor: {
      value: t,
      writable: true,
      configurable: true
    }
  }), Object.defineProperty(t, "prototype", {
    writable: false
  }), e && _setPrototypeOf(t, e);
}
function _isNativeReflectConstruct() {
  try {
    var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
  } catch (t) {}
  return (_isNativeReflectConstruct = function () {
    return !!t;
  })();
}
function _objectWithoutProperties(e, t) {
  if (null == e) return {};
  var o,
    r,
    i = _objectWithoutPropertiesLoose(e, t);
  if (Object.getOwnPropertySymbols) {
    var n = Object.getOwnPropertySymbols(e);
    for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
  }
  return i;
}
function _objectWithoutPropertiesLoose(r, e) {
  if (null == r) return {};
  var t = {};
  for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
    if (-1 !== e.indexOf(n)) continue;
    t[n] = r[n];
  }
  return t;
}
function _possibleConstructorReturn(t, e) {
  if (e && ("object" == typeof e || "function" == typeof e)) return e;
  if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined");
  return _assertThisInitialized(t);
}
function _setPrototypeOf(t, e) {
  return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {
    return t.__proto__ = e, t;
  }, _setPrototypeOf(t, e);
}
function _toPrimitive(t, r) {
  if ("object" != typeof t || !t) return t;
  var e = t[Symbol.toPrimitive];
  if (void 0 !== e) {
    var i = e.call(t, r);
    if ("object" != typeof i) return i;
    throw new TypeError("@@toPrimitive must return a primitive value.");
  }
  return (String )(t);
}
function _toPropertyKey(t) {
  var i = _toPrimitive(t, "string");
  return "symbol" == typeof i ? i : i + "";
}

var VIEWBOX_WIDTH = 100;
var VIEWBOX_HEIGHT = 100;
var VIEWBOX_HEIGHT_HALF = 50;
var VIEWBOX_CENTER_X = 50;
var VIEWBOX_CENTER_Y = 50;

function Path(_ref) {
  var className = _ref.className,
    counterClockwise = _ref.counterClockwise,
    dashRatio = _ref.dashRatio,
    pathRadius = _ref.pathRadius,
    strokeWidth = _ref.strokeWidth,
    style = _ref.style;
  return /*#__PURE__*/React__namespace.createElement("path", {
    className: className,
    style: Object.assign({}, style, getDashStyle({
      pathRadius: pathRadius,
      dashRatio: dashRatio,
      counterClockwise: counterClockwise
    })),
    d: getPathDescription({
      pathRadius: pathRadius,
      counterClockwise: counterClockwise
    }),
    strokeWidth: strokeWidth,
    fillOpacity: 0
  });
}

// SVG path description specifies how the path should be drawn
function getPathDescription(_ref2) {
  var pathRadius = _ref2.pathRadius,
    counterClockwise = _ref2.counterClockwise;
  var radius = pathRadius;
  var rotation = counterClockwise ? 1 : 0;

  // Move to center of canvas
  // Relative move to top canvas
  // Relative arc to bottom of canvas
  // Relative arc to top of canvas
  return "\n      M ".concat(VIEWBOX_CENTER_X, ",").concat(VIEWBOX_CENTER_Y, "\n      m 0,-").concat(radius, "\n      a ").concat(radius, ",").concat(radius, " ").concat(rotation, " 1 1 0,").concat(2 * radius, "\n      a ").concat(radius, ",").concat(radius, " ").concat(rotation, " 1 1 0,-").concat(2 * radius, "\n    ");
}
function getDashStyle(_ref3) {
  var counterClockwise = _ref3.counterClockwise,
    dashRatio = _ref3.dashRatio,
    pathRadius = _ref3.pathRadius;
  var diameter = Math.PI * 2 * pathRadius;
  var gapLength = (1 - dashRatio) * diameter;
  return {
    // Have dash be full diameter, and gap be full diameter
    strokeDasharray: "".concat(diameter, "px ").concat(diameter, "px"),
    // Shift dash backward by gapLength, so gap starts appearing at correct distance
    strokeDashoffset: "".concat(counterClockwise ? -gapLength : gapLength, "px")
  };
}

var CircularProgressbar = /*#__PURE__*/function (_React$Component) {
  function CircularProgressbar() {
    _classCallCheck(this, CircularProgressbar);
    return _callSuper(this, CircularProgressbar, arguments);
  }
  _inherits(CircularProgressbar, _React$Component);
  return _createClass(CircularProgressbar, [{
    key: "getBackgroundPadding",
    value: function getBackgroundPadding() {
      if (!this.props.background) {
        // Don't add padding if not displaying background
        return 0;
      }
      return this.props.backgroundPadding;
    }
  }, {
    key: "getPathRadius",
    value: function getPathRadius() {
      // The radius of the path is defined to be in the middle, so in order for the path to
      // fit perfectly inside the 100x100 viewBox, need to subtract half the strokeWidth
      return VIEWBOX_HEIGHT_HALF - this.props.strokeWidth / 2 - this.getBackgroundPadding();
    }

    // Ratio of path length to trail length, as a value between 0 and 1
  }, {
    key: "getPathRatio",
    value: function getPathRatio() {
      var _this$props = this.props,
        value = _this$props.value,
        minValue = _this$props.minValue,
        maxValue = _this$props.maxValue;
      var boundedValue = Math.min(Math.max(value, minValue), maxValue);
      return (boundedValue - minValue) / (maxValue - minValue);
    }
  }, {
    key: "render",
    value: function render() {
      var _this$props2 = this.props,
        circleRatio = _this$props2.circleRatio,
        className = _this$props2.className,
        classes = _this$props2.classes,
        counterClockwise = _this$props2.counterClockwise,
        styles = _this$props2.styles,
        strokeWidth = _this$props2.strokeWidth,
        text = _this$props2.text;
      var pathRadius = this.getPathRadius();
      var pathRatio = this.getPathRatio();
      return /*#__PURE__*/React__namespace.createElement("svg", {
        className: "".concat(classes.root, " ").concat(className),
        style: styles.root,
        viewBox: "0 0 ".concat(VIEWBOX_WIDTH, " ").concat(VIEWBOX_HEIGHT),
        "data-test-id": "CircularProgressbar"
      }, this.props.background ? /*#__PURE__*/React__namespace.createElement("circle", {
        className: classes.background,
        style: styles.background,
        cx: VIEWBOX_CENTER_X,
        cy: VIEWBOX_CENTER_Y,
        r: VIEWBOX_HEIGHT_HALF
      }) : null, /*#__PURE__*/React__namespace.createElement(Path, {
        className: classes.trail,
        counterClockwise: counterClockwise,
        dashRatio: circleRatio,
        pathRadius: pathRadius,
        strokeWidth: strokeWidth,
        style: styles.trail
      }), /*#__PURE__*/React__namespace.createElement(Path, {
        className: classes.path,
        counterClockwise: counterClockwise,
        dashRatio: pathRatio * circleRatio,
        pathRadius: pathRadius,
        strokeWidth: strokeWidth,
        style: styles.path
      }), text ? /*#__PURE__*/React__namespace.createElement("text", {
        className: classes.text,
        style: styles.text,
        x: VIEWBOX_CENTER_X,
        y: VIEWBOX_CENTER_Y
      }, text) : null);
    }
  }]);
}(React__namespace.Component);
_defineProperty(CircularProgressbar, "defaultProps", {
  background: false,
  backgroundPadding: 0,
  circleRatio: 1,
  classes: {
    root: 'CircularProgressbar',
    trail: 'CircularProgressbar-trail',
    path: 'CircularProgressbar-path',
    text: 'CircularProgressbar-text',
    background: 'CircularProgressbar-background'
  },
  counterClockwise: false,
  className: '',
  maxValue: 100,
  minValue: 0,
  strokeWidth: 8,
  styles: {
    root: {},
    trail: {},
    path: {},
    text: {},
    background: {}
  },
  text: ''
});

var _excluded = ["children"];
// This is a wrapper around CircularProgressbar that allows passing children,
// which will be vertically and horizontally centered inside the progressbar automatically.
function CircularProgressbarWithChildren(props) {
  props.children;
    var circularProgressbarProps = _objectWithoutProperties(props, _excluded);
  return /*#__PURE__*/React__namespace.createElement("div", {
    "data-test-id": "CircularProgressbarWithChildren"
  }, /*#__PURE__*/React__namespace.createElement("div", {
    style: {
      position: 'relative',
      width: '100%',
      height: '100%'
    }
  }, /*#__PURE__*/React__namespace.createElement(CircularProgressbar, circularProgressbarProps), props.children ? /*#__PURE__*/React__namespace.createElement("div", {
    "data-test-id": "CircularProgressbarWithChildren__children",
    style: {
      position: 'absolute',
      width: '100%',
      height: '100%',
      marginTop: '-100%',
      display: 'flex',
      flexDirection: 'column',
      justifyContent: 'center',
      alignItems: 'center'
    }
  }, props.children) : null));
}

function buildStyles(_ref) {
  var rotation = _ref.rotation,
    strokeLinecap = _ref.strokeLinecap,
    textColor = _ref.textColor,
    textSize = _ref.textSize,
    pathColor = _ref.pathColor,
    pathTransition = _ref.pathTransition,
    pathTransitionDuration = _ref.pathTransitionDuration,
    trailColor = _ref.trailColor,
    backgroundColor = _ref.backgroundColor;
  var rotationTransform = rotation == null ? undefined : "rotate(".concat(rotation, "turn)");
  var rotationTransformOrigin = rotation == null ? undefined : 'center center';
  return {
    root: {},
    path: removeUndefinedValues({
      stroke: pathColor,
      strokeLinecap: strokeLinecap,
      transform: rotationTransform,
      transformOrigin: rotationTransformOrigin,
      transition: pathTransition,
      transitionDuration: pathTransitionDuration == null ? undefined : "".concat(pathTransitionDuration, "s")
    }),
    trail: removeUndefinedValues({
      stroke: trailColor,
      strokeLinecap: strokeLinecap,
      transform: rotationTransform,
      transformOrigin: rotationTransformOrigin
    }),
    text: removeUndefinedValues({
      fill: textColor,
      fontSize: textSize
    }),
    background: removeUndefinedValues({
      fill: backgroundColor
    })
  };
}
function removeUndefinedValues(obj) {
  Object.keys(obj).forEach(function (key) {
    if (obj[key] == null) {
      delete obj[key];
    }
  });
  return obj;
}

exports.CircularProgress = CircularProgressbarWithChildren;
exports.CircularProgressBar = CircularProgressbar;
exports.buildStyles = buildStyles;
