"use strict";

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

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.thinnerShapesNeeded = exports.sameAxes = exports.roundNumber = exports.polygonToArea = exports.pointsToArea = exports.point = exports.lineToArea = exports.isDuplicatedMark = exports.getTickValues = exports.getRightestPoints = exports.getMiddleOfTwoPoints = exports.getAngleDeg = exports.getAdjustedGraphLimits = exports.findLongestWord = exports.equalPoints = exports.countWords = exports.bounds = exports.arrowDimensions = exports.areArraysOfObjectsEqual = exports.amountToIncreaseWidth = void 0;

var _head = _interopRequireDefault(require("lodash/head"));

var _tail = _interopRequireDefault(require("lodash/tail"));

var _plot = require("@pie-lib/plot");

var _invariant = _interopRequireDefault(require("invariant"));

var _isEqual = _interopRequireDefault(require("lodash/isEqual"));

var _isEmpty = _interopRequireDefault(require("lodash/isEmpty"));

var _cloneDeep = _interopRequireDefault(require("lodash/cloneDeep"));

var bounds = _plot.utils.bounds;
exports.bounds = bounds;
var point = _plot.utils.point; //TODO: This can be removed?

exports.point = point;

var getAngleDeg = function getAngleDeg() {
  return 0;
}; //TODO: This can be removed?


exports.getAngleDeg = getAngleDeg;

var arrowDimensions = function arrowDimensions() {
  return 0;
};

exports.arrowDimensions = arrowDimensions;

var getTickValues = function getTickValues(prop) {
  var tickValues = [];
  var tickVal = 0;

  while (tickVal >= prop.min && tickValues.indexOf(tickVal) < 0) {
    tickValues.push(tickVal);
    tickVal = Math.round((tickVal - prop.step) * 10000) / 10000;
  }

  tickVal = Math.round(prop.step * 10000) / 10000;

  while (tickVal <= prop.max && tickValues.indexOf(tickVal) < 0) {
    tickValues.push(tickVal);
    tickVal = Math.round((tickVal + prop.step) * 10000) / 10000;
  } // return only ticks that are inside the min-max interval


  if (tickValues) {
    return tickValues.filter(function (tV) {
      return tV >= prop.min && tV <= prop.max;
    });
  }

  return [];
};

exports.getTickValues = getTickValues;

var countWords = function countWords(label) {
  if (label == null || (0, _isEmpty["default"])(label)) {
    return 1;
  }

  var words = label.split(' ');
  return words.length;
}; // findLongestWord is also used in plot


exports.countWords = countWords;

var findLongestWord = function findLongestWord(label) {
  var longestWord = (label || '').replace(/<[^>]+>/g, '').split(' ').sort(function (a, b) {
    return b.length - a.length;
  });
  return longestWord[0].length;
}; // amountToIncreaseWidth is also used in plot


exports.findLongestWord = findLongestWord;

var amountToIncreaseWidth = function amountToIncreaseWidth(longestWord) {
  if (!longestWord) {
    return 0;
  }

  return longestWord * 10;
};

exports.amountToIncreaseWidth = amountToIncreaseWidth;

var polygonToArea = function polygonToArea(points) {
  var h = (0, _head["default"])(points);
  var area = {
    left: h.x,
    top: h.y,
    bottom: h.y,
    right: h.x
  };
  return (0, _tail["default"])(points).reduce(function (a, p) {
    a.left = Math.min(a.left, p.x);
    a.top = Math.max(a.top, p.y);
    a.bottom = Math.min(a.bottom, p.y);
    a.right = Math.max(a.right, p.x);
    return a;
  }, area);
};

exports.polygonToArea = polygonToArea;

var lineToArea = function lineToArea(from, to) {
  return pointsToArea(from, to);
};

exports.lineToArea = lineToArea;

var pointsToArea = function pointsToArea(a, b) {
  (0, _invariant["default"])(!!a && !!b, 'a or b is undefined');
  var left = Math.min(a.x, b.x);
  var top = Math.max(a.y, b.y);
  var bottom = Math.min(a.y, b.y);
  var right = Math.max(a.x, b.x);
  return {
    left: left,
    top: top,
    bottom: bottom,
    right: right
  };
};

exports.pointsToArea = pointsToArea;

var getRightestPoints = function getRightestPoints(points) {
  var sortedPoints = (0, _cloneDeep["default"])(points);
  sortedPoints.sort(function (a, b) {
    return b.x - a.x;
  });
  return {
    a: sortedPoints[0],
    b: sortedPoints[1]
  };
};

exports.getRightestPoints = getRightestPoints;

var getMiddleOfTwoPoints = function getMiddleOfTwoPoints(a, b) {
  return {
    x: (a.x + b.x) / 2,
    y: (a.y + b.y) / 2
  };
};

exports.getMiddleOfTwoPoints = getMiddleOfTwoPoints;

var roundNumber = function roundNumber(number) {
  return parseFloat(number.toFixed(4));
};

exports.roundNumber = roundNumber;

var sameAxes = function sameAxes(p1, p2) {
  return p1 && p2 && (roundNumber(p1.x) === roundNumber(p2.x) || roundNumber(p1.y) === roundNumber(p2.y));
};

exports.sameAxes = sameAxes;

var equalPoints = function equalPoints(p1, p2) {
  return p1 && p2 && (0, _isEqual["default"])({
    x: roundNumber(p1.x),
    y: roundNumber(p1.y)
  }, {
    x: roundNumber(p2.x),
    y: roundNumber(p2.y)
  });
};

exports.equalPoints = equalPoints;

var getDistanceBetweenTicks = function getDistanceBetweenTicks(axis, size) {
  var min = axis.min,
      max = axis.max,
      step = axis.step;
  var nbOfTicks = (max - min) / step;
  return size / nbOfTicks;
};

var thinnerShapesNeeded = function thinnerShapesNeeded(graphProps) {
  var domain = graphProps.domain,
      range = graphProps.range,
      _graphProps$size = graphProps.size,
      width = _graphProps$size.width,
      height = _graphProps$size.height; // 14 is the default width of a point

  return getDistanceBetweenTicks(domain, width) < 14 || getDistanceBetweenTicks(range, height) < 14;
};

exports.thinnerShapesNeeded = thinnerShapesNeeded;

var getAdjustedGraphLimits = function getAdjustedGraphLimits(graphProps) {
  var domain = graphProps.domain,
      range = graphProps.range,
      _graphProps$size2 = graphProps.size,
      width = _graphProps$size2.width,
      height = _graphProps$size2.height;
  var domainTicksDistance = getDistanceBetweenTicks(domain, width);
  var rangeTicksDistance = getDistanceBetweenTicks(range, height); // 15 is the distance required for the arrow to extend the graph

  var domainPadding = domain.step / (domainTicksDistance / 15);
  var rangePadding = range.step / (rangeTicksDistance / 15);
  return {
    domain: {
      min: domain.min - domainPadding,
      max: domain.max + domainPadding
    },
    range: {
      min: range.min - rangePadding,
      max: range.max + rangePadding
    }
  };
};

exports.getAdjustedGraphLimits = getAdjustedGraphLimits;

var sortPoints = function sortPoints(array) {
  return (array || []).sort(function (a, b) {
    return a.x - b.x || a.y - b.y;
  });
}; // check colliniarity of 3 points (source: https://www.geeksforgeeks.org/program-check-three-points-collinear/)


var checkCollinearity = function checkCollinearity(a, b, c) {
  return (a.x - b.x) * (c.y - b.y) === (c.x - b.x) * (a.y - b.y);
}; // 2 lines are overlapping if all 4 points are collinear


var isSameLine = function isSameLine(markA, markB) {
  return checkCollinearity(markA.from, markB.from, markB.to) && checkCollinearity(markA.to, markB.from, markB.to);
};

var isDuplicatedMark = function isDuplicatedMark(mark, marks, oldMark) {
  var type = mark.type,
      building = mark.building;

  if (building) {
    return false;
  }

  var filteredMarks = (marks || []).filter(function (m) {
    return m.type === type && !m.building;
  });
  var index = filteredMarks.findIndex(function (m) {
    return (0, _isEqual["default"])(m, oldMark);
  });

  if (index !== -1) {
    filteredMarks.splice(index, 1);
  }

  var duplicated = filteredMarks.find(function (m) {
    if (type === 'line') {
      var from = mark.from,
          to = mark.to;
      return equalPoints(from, m.from) && equalPoints(to, m.to) || equalPoints(from, m.to) && equalPoints(to, m.from) || type === 'line' && isSameLine(m, mark);
    } else if (type === 'polygon') {
      return (0, _isEqual["default"])(sortPoints((0, _cloneDeep["default"])(mark.points)), sortPoints((0, _cloneDeep["default"])(m.points)));
    }
  });
  return !!duplicated;
};

exports.isDuplicatedMark = isDuplicatedMark;

var areArraysOfObjectsEqual = function areArraysOfObjectsEqual(array1, array2) {
  // Check if both arrays have the same length
  if (array1.length !== array2.length) {
    return false;
  } // Iterate through each object in the arrays


  for (var i = 0; i < array1.length; i++) {
    // Get the current objects in both arrays
    var obj1 = array1[i];
    var obj2 = array2[i]; // Check if the objects have the same number of properties

    if (Object.keys(obj1).length !== Object.keys(obj2).length) {
      return false;
    } // Iterate through each property in the objects


    for (var key in obj1) {
      // Check if the properties and their values are equal
      if (obj1[key] !== obj2[key]) {
        return false;
      }
    }
  } // If all objects are equal, the arrays are the same


  return true;
};

exports.areArraysOfObjectsEqual = areArraysOfObjectsEqual;
//# sourceMappingURL=utils.js.map