export const copy = (v) => ({x: v.x, y: v.y});
export const dot = (a, b) => a.x * b.x + a.y * b.y;
export const cross = (a, b) => a.x * b.y - a.y * b.x;
const _add = (a, b) => ({x: a.x + b.x, y: a.y + b.y});
export const sub = (a, b) => ({x: a.x - b.x, y: a.y - b.y});
export const square = ({x, y}) => x ** 2 + y ** 2;
export const magnitude = ({x, y}) => Math.sqrt(square({x, y}));

// Arguments must be one vector and one scalar, but can be transposed
export const mult = (v, m) => {
  if (typeof v === 'object') return {x: v.x * m, y: v.y * m};
  else if (typeof m === 'object') return {x: m.x * v, y: m.y * v};
  else throw new Error('mult: no vector provided');
};

export const div = (v, m) => ({x: v.x / m, y: v.y / m});
export const zero = {x: 0, y: 0};

export const weightedAvg = (items) => {
  let res = zero;
  let W = 0;
  for (const [v, w] of items) {
    res = _add(res, mult(v, w));
    W += w;
  }
  return div(res, W);
};

export const components = (mag, dir) => mult(mag, {
  x: Math.cos(dir),
  y: Math.sin(dir),
});

export const direction = ({x, y}) => Math.atan2(y, x);
export const degrees = (rad) => rad * 180 / Math.PI;

export const add = (...vectors) => {
  let res = zero;
  for (const v of vectors) {
    res = _add(res, v);
  }
  return res;
}
