
/**
 * This class is intended as a placeholder for utility methods unrelated
 * to actual classes of the game system or of FoundryVTT
 */
export class Misc {
  static isFunction(v) {
    return v && {}.toString.call(v) === '[object Function]';
  }

  static upperFirst(text) {
    return text.charAt(0).toUpperCase() + text.slice(1);
  }

  static toSignedString(number) {
    const value = parseInt(number)
    const isPositiveNumber = value != NaN && value > 0;
    return isPositiveNumber ? "+" + number : number
  }

  /**
   * Converts the value to an integer, or to 0 if undefined/null/not representing integer
   * @param {*} value value to convert to an integer using parseInt
   */
  static toInt(value) {
    if (value == undefined) {
      return 0;
    }
    const parsed = parseInt(value);
    return isNaN(parsed) ? 0 : parsed;
  }

  static getFractionHtml(diviseur) {
    if (!diviseur || diviseur <= 1) return undefined;
    switch (diviseur || 1) {
      case 2: return '&frac12;';
      case 4: return '&frac14;';
      default: return '1/' + diviseur;
    }
  }

  static classify(items, classifier = it => it.type, transform = it => it) {
    let itemsBy = {};
    Misc.classifyInto(itemsBy, items, classifier, transform);
    return itemsBy;
  }

  static classifyFirst(items, classifier) {
    let itemsBy = {};
    for (const item of items) {
      const classification = classifier(item);
      if (!itemsBy[classification]) {
        itemsBy[classification] = item;
      }
    }
    return itemsBy;
  }

  static classifyInto(itemsBy, items, classifier = it => it.type, transform = it => it) {
    for (const item of items) {
      const classification = classifier(item);
      let list = itemsBy[classification];
      if (!list) {
        list = [];
        itemsBy[classification] = list;
      }
      list.push(transform(item));
    }
  }

  static rollOneOf(array) {
    return array[new Roll("1d" + array.length).evaluate().total - 1];
  }

  static distinct(array) {
    return [...new Set(array)];
  }

  static actorData(actor) {
    return Misc.data(actor);
  }

  static itemData(item) {
    return Misc.data(item);
  }

  static data(it) {
    if (it instanceof Item) {
      return it.data;
    }
    if (it instanceof Actor) {
      return it.data;
    }
    return it;
  }

  static templateData(it) {
    return Misc.data(it)?.data ?? {}
  }
}