"use strict";

var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = exports.SvgGradient = void 0;

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));

var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));

var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));

var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));

var _react = _interopRequireWildcard(require("react"));

var _propTypes = _interopRequireDefault(require("prop-types"));

var _ramda = require("ramda");

var _reactTransitionGroup = require("react-transition-group");

var _useTheme = _interopRequireDefault(require("../hooks/useTheme"));

var _Box = _interopRequireDefault(require("../Box"));

var _Text = _interopRequireDefault(require("../Text"));

var _math = require("../utils/math");

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

var joinWithDash = (0, _ramda.o)((0, _ramda.join)('-'), (0, _ramda.filter)(Boolean));

var getCirmcumference = function getCirmcumference(radius) {
  return 2 * radius * Math.PI;
};

var getArcCircumference = function getArcCircumference(C) {
  return function (arcAngle) {
    return arcAngle / 360 * C;
  };
};

var coord = function coord(x, y) {
  return {
    x: x,
    y: y
  };
};

var equalCoord = function equalCoord(x) {
  return {
    x: x,
    y: x
  };
};

var getArcProps = function getArcProps(_ref) {
  var radius = _ref.radius,
      arcAngle = _ref.arcAngle;
  var C = getCirmcumference(radius);
  var CArc = getArcCircumference(C)(arcAngle);
  var offset = C - CArc;
  return {
    CArc: CArc,
    C: C,
    offset: offset
  };
};

var SvgGradient = function SvgGradient(_ref2) {
  var variant = _ref2.variant,
      rest = (0, _objectWithoutProperties2["default"])(_ref2, ["variant"]);
  var theme = (0, _useTheme["default"])();
  var gradient = (0, _ramda.path)(['gauge', variant, 'gradient'].filter(Boolean))(theme);
  return /*#__PURE__*/_react["default"].createElement("linearGradient", (0, _extends2["default"])({
    x1: "0%",
    y1: "0%",
    x2: "100%",
    y2: "0%"
  }, rest), gradient.map(function (_ref3) {
    var _ref4 = (0, _slicedToArray2["default"])(_ref3, 2),
        offset = _ref4[0],
        stopColor = _ref4[1];

    return /*#__PURE__*/_react["default"].createElement("stop", (0, _extends2["default"])({
      key: "".concat(offset, "-").concat(stopColor)
    }, {
      offset: offset,
      stopColor: stopColor
    }));
  }));
};

exports.SvgGradient = SvgGradient;
process.env.NODE_ENV !== "production" ? SvgGradient.propTypes = {
  variant: _propTypes["default"].string
} : void 0;
var Gauge = /*#__PURE__*/(0, _react.forwardRef)(function (_ref5, ref) {
  var _ref5$arcAngle = _ref5.arcAngle,
      arcAngle = _ref5$arcAngle === void 0 ? 240 : _ref5$arcAngle,
      _ref5$animationDurati = _ref5.animationDuration,
      animationDuration = _ref5$animationDurati === void 0 ? 1000 : _ref5$animationDurati,
      _ref5$size = _ref5.size,
      size = _ref5$size === void 0 ? 256 : _ref5$size,
      _ref5$rimStrokeWidth = _ref5.rimStrokeWidth,
      rimStrokeWidth = _ref5$rimStrokeWidth === void 0 ? 1 : _ref5$rimStrokeWidth,
      _ref5$gaugeStrokeWidt = _ref5.gaugeStrokeWidth,
      gaugeStrokeWidth = _ref5$gaugeStrokeWidt === void 0 ? 4 : _ref5$gaugeStrokeWidt,
      _ref5$value = _ref5.value,
      value = _ref5$value === void 0 ? 0 : _ref5$value,
      valueProps = _ref5.valueProps,
      _ref5$min = _ref5.min,
      min = _ref5$min === void 0 ? 0 : _ref5$min,
      _ref5$max = _ref5.max,
      max = _ref5$max === void 0 ? 1 : _ref5$max,
      _ref5$format = _ref5.format,
      format = _ref5$format === void 0 ? _ramda.identity : _ref5$format,
      _ref5$formatLegend = _ref5.formatLegend,
      formatLegend = _ref5$formatLegend === void 0 ? _ramda.identity : _ref5$formatLegend,
      title = _ref5.title,
      legendPropsProp = _ref5.legendProps,
      variant = _ref5.variant,
      rest = (0, _objectWithoutProperties2["default"])(_ref5, ["arcAngle", "animationDuration", "size", "rimStrokeWidth", "gaugeStrokeWidth", "value", "valueProps", "min", "max", "format", "formatLegend", "title", "legendProps", "variant"]);

  // hack to run animation after mount
  var _useState = (0, _react.useState)(false),
      _useState2 = (0, _slicedToArray2["default"])(_useState, 2),
      inProp = _useState2[0],
      setInProp = _useState2[1];

  (0, _react.useEffect)(function () {
    setInProp(true);
  }, []);
  var svgSize = 32; // Angle between horizontal axis and the start of gauge

  var alpha = (arcAngle - 180) / 2; // Labels needs to be moved a bit

  var alphaLabels = alpha + 10; // We need to move SVG Circle's zero angle
  // so the gauge stroke is visually symmetric.

  var rotateForSymmetryAngle = -alpha - 180; // Normalized value between 0-1

  var valueNormalized = (0, _ramda.clamp)(0, 1)((value - min) / (max - min)); // Coords of center of the canvas

  var center = equalCoord(svgSize / 2);
  var radiusRim = center.x - rimStrokeWidth / 2;
  var radiusGauge = center.x - (rimStrokeWidth + gaugeStrokeWidth / 2);
  var rimProps = getArcProps({
    radius: radiusRim,
    arcAngle: arcAngle
  });
  var gaugeProps = getArcProps({
    radius: radiusGauge,
    arcAngle: arcAngle * valueNormalized
  });
  var circleProps = {
    transform: "rotate(".concat(rotateForSymmetryAngle, " ").concat(center.x, " ").concat(center.y, ")")
  };

  var legendProps = _objectSpread({
    fill: '#000000',
    stroke: 'none',
    fontSize: '2px'
  }, legendPropsProp);

  var legend = coord(radiusRim * (0, _math.cos)(alphaLabels), radiusRim * (0, _math.sin)(alphaLabels));
  var transitionStyles = {
    entering: {
      strokeDashoffset: gaugeProps.offset
    },
    entered: {
      strokeDashoffset: gaugeProps.offset
    },
    exiting: {
      strokeDashoffset: gaugeProps.C
    },
    exited: {
      strokeDashoffset: gaugeProps.C
    }
  };
  var gradientId = joinWithDash(['gradient-arc', variant]);
  return /*#__PURE__*/_react["default"].createElement(_Box["default"], (0, _extends2["default"])({
    ref: ref,
    __css: {
      position: 'relative',
      width: "".concat(size, "px"),
      height: "".concat(size, "px")
    }
  }, rest), /*#__PURE__*/_react["default"].createElement(_Box["default"], (0, _extends2["default"])({
    mt: 0,
    mb: 0,
    fontSize: 8,
    __css: {
      whiteSpace: 'nowrap',
      transform: 'translate(-50%, -50%)',
      position: 'absolute',
      left: '50%',
      top: '50%'
    }
  }, valueProps), format(value)), /*#__PURE__*/_react["default"].createElement(_Box["default"], {
    as: "svg",
    viewBox: "0 0 ".concat(svgSize, " ").concat(svgSize),
    width: size,
    height: size,
    fill: "none",
    stroke: "currentcolor",
    role: "img",
    "aria-valuenow": value,
    "aria-valuemin": min,
    "aria-valuemax": max,
    __css: {
      color: 'primary'
    }
  }, /*#__PURE__*/_react["default"].createElement("defs", null, /*#__PURE__*/_react["default"].createElement(SvgGradient, {
    variant: variant,
    id: gradientId
  })), title && /*#__PURE__*/_react["default"].createElement("title", null, title), /*#__PURE__*/_react["default"].createElement(_Text["default"], (0, _extends2["default"])({
    variant: "",
    as: "text",
    x: center.x - legend.x,
    y: center.y + legend.y,
    textAnchor: "start"
  }, legendProps), formatLegend(min)), /*#__PURE__*/_react["default"].createElement(_Text["default"], (0, _extends2["default"])({
    variant: "",
    as: "text",
    x: center.x + legend.x,
    y: center.y + legend.y,
    textAnchor: "end"
  }, legendProps), formatLegend(max)), /*#__PURE__*/_react["default"].createElement("circle", (0, _extends2["default"])({
    strokeWidth: rimStrokeWidth,
    opacity: 4 / 5,
    cx: center.x,
    cy: center.y,
    r: radiusRim,
    stroke: "url(#".concat(gradientId, ")"),
    strokeDasharray: rimProps.C,
    strokeDashoffset: rimProps.offset
  }, circleProps)), /*#__PURE__*/_react["default"].createElement(_reactTransitionGroup.Transition, {
    "in": inProp,
    timeout: {
      enter: animationDuration,
      exit: animationDuration
    },
    appear: true
  }, function (state) {
    return /*#__PURE__*/_react["default"].createElement(_Box["default"], (0, _extends2["default"])({
      as: "circle",
      cx: center.x,
      cy: center.y,
      r: radiusGauge,
      opacity: 1 / 3,
      stroke: "url(#".concat(gradientId, ")"),
      strokeWidth: gaugeStrokeWidth,
      strokeDasharray: gaugeProps.C,
      __css: {
        transition: "stroke-dashoffset ".concat(animationDuration, "ms cubic-bezier(0, 0, 0.2, 1)")
      }
    }, transitionStyles[state], circleProps));
  })));
});
Gauge.displayName = 'Gauge';
process.env.NODE_ENV !== "production" ? Gauge.propTypes = {
  animationDuration: _propTypes["default"].number,
  arcAngle: _propTypes["default"].number,
  format: _propTypes["default"].func,
  formatLegend: _propTypes["default"].func,
  gaugeStrokeWidth: _propTypes["default"].number,
  legendProps: _propTypes["default"].object,
  max: _propTypes["default"].number,
  min: _propTypes["default"].number,
  rimStrokeWidth: _propTypes["default"].number,
  size: _propTypes["default"].number,
  title: _propTypes["default"].string,
  value: _propTypes["default"].number,
  valueProps: _propTypes["default"].object,
  variant: _propTypes["default"].string
} : void 0;
var _default = Gauge;
exports["default"] = _default;