import Decimal from 'decimal.js';

interface Path {
  x: number;
  y: number;
  [proppName: string]: any;
}

/**
 * 计算2D多边形包围盒
 * path: [
 *   { x: 100, y: 100 },
 *   { x: 200, y: 100 },
 *   { x: 200, y: 200 },
 *   { x: 0, y: 300 },
 * ],
 * @param {Array} path
 */
export const getBoundingBox = function (path: Path[]) {
  let min_x = 0,
    min_y = 0,
    max_x = 0,
    max_y = 0,
    width = 0,
    height = 0;
  const center = { x: 0, y: 0 };
  let resPath: Path[] = [];
  const length = path.length;

  let index = 0;
  for (const item of path) {
    const x1 = item.x;
    const y1 = item.y;

    if (index === 0) {
      min_x = x1;
      min_y = y1;
      max_x = x1;
      max_y = y1;
      path = [];
    } else {
      if (x1 > max_x) {
        max_x = x1;
      }
      if (x1 < min_x) {
        min_x = x1;
      }
      if (y1 > max_y) {
        max_y = y1;
      }
      if (y1 < min_y) {
        min_y = y1;
      }
    }

    index++;
  }

  if (length === 1) {
    center.x = min_x;
    center.y = min_y;
  } else if (length >= 2) {
    if (min_x === max_x) {
      // 垂直的线
      width = 0;
      height = Decimal.sub(max_y, min_y).toNumber();
      center.x = min_x;
      center.y = Decimal.sub(max_y, min_y).div(2).plus(min_y).toNumber();
    } else if (min_y === max_y) {
      // 水平的线
      width = Decimal.sub(max_x, min_x).toNumber();
      height = 0;
      center.y = min_y;
      center.x = Decimal.sub(max_x, min_x).div(2).plus(min_x).toNumber();
    } else {
      width = Decimal.sub(max_x, min_x).toNumber();
      height = Decimal.sub(max_y, min_y).toNumber();

      center.x = Decimal.sub(max_x, min_x).div(2).plus(min_x).toNumber();
      center.y = Decimal.sub(max_y, min_y).div(2).plus(min_y).toNumber();

      const point1 = {
        x: min_x,
        y: min_y,
      };
      const point2 = {
        x: max_x,
        y: min_y,
      };
      const point3 = {
        x: max_x,
        y: max_y,
      };
      const point4 = {
        x: min_x,
        y: max_y,
      };

      resPath = [point1, point2, point3, point4];
    }
  }

  return {
    min_x,
    min_y,
    max_x,
    max_y,
    path: resPath,
    center,
    width,
    height,
  };
};