export function isInteger(value) {
  if (Number.isInteger) {
    return Number.isInteger(value);
  }
  return typeof value === "number" && isFinite(value) && Math.floor(value) === value;
}

// Using this helper to ensure there are correct flow types
// https://github.com/facebook/flow/issues/2221
export function values(map) {
  if (Object.values) {
    // $FlowFixMe - Object.values currently does not have good flow support
    return Object.values(map);
  }
  return Object.keys(map).map((key) => map[key]);
}

// Could also extend to pass index and list

// TODO: swap order
export function findIndex(list, predicate) {
  if (list.findIndex) {
    return list.findIndex(predicate);
  }

  // Using a for loop so that we can exit early
  for (let i = 0; i < list.length; i++) {
    if (predicate(list[i])) {
      return i;
    }
  }
  // Array.prototype.find returns -1 when nothing is found
  return -1;
}

export function find(list, predicate) {
  if (list.find) {
    return list.find(predicate);
  }
  const index = findIndex(list, predicate);
  if (index !== -1) {
    return list[index];
  }
  // Array.prototype.find returns undefined when nothing is found
  return undefined;
}

// Using this rather than Array.from as Array.from adds 2kb to the gzip
// document.querySelector actually returns Element[], but flow thinks it is HTMLElement[]
// So we downcast the result to Element[]
export function toArray(list) {
  return Array.prototype.slice.call(list);
}
