/**
 * @module exclusive-interaction-bundle
 * This bundle manages interactions that can be considered "exclusive",
 * that means that they are mutually exclusive, only one set can be active
 * at a time.  This is useful for tools like measure tools or identify when
 * you want to be able to toggle other tools off when turning one on.
 */
export default {
  name: "exclusiveInteractions",

  getReducer: () => {
    const initialData = {
      interactions: [],
    };

    return (state = initialData, { type, payload }) => {
      switch (type) {
        case "EXCLUSIVE_INTERACTIONS_SET":
          return Object.assign({}, state, payload);
        default:
          return state;
      }
    };
  },

  /**
   * Adds an interaction or an array of interactions to the map and makes them available via
   * the `selectExclusiveInteractions` selector.
   * @param {object|object[]} interactions - `ol.Interaction` or an array of `ol.Interaction`s that will be added to the map.
   */
  doExclusiveInteractionsSet: (interactions) => ({ dispatch, store }) => {
    if (!interactions) return null;

    store.doExclusiveInteractionsUnset();

    if (!interactions.length) interactions = [interactions];
    interactions.forEach((interaction) => {
      store.doInteractionAdd(interaction, 0);
    });

    dispatch({
      type: "EXCLUSIVE_INTERACTIONS_SET",
      payload: {
        interactions: interactions,
      },
    });
  },

  /**
   * Remove all exclusive interactions from the map and reset the internal array of interactions.
   */
  doExclusiveInteractionsUnset: () => ({ dispatch, store }) => {
    const existingInteractions = store.selectExclusiveInteractions();
    if (existingInteractions.length) {
      existingInteractions.forEach((existingInteraction) => {
        doInteractionsRemove(existingInteraction);
      });
    }
    dispatch({
      type: "EXCLUSIVE_INTERACTIONS_UNSET",
      payload: {
        interactions: [],
      },
    });
  },

  /**
   * @returns the internal array of `ol.Interaction` objects that are being managed by the bundle
   */
  selectExclusiveInteractions: (state) => {
    return state.exclusiveInteractions.interactions;
  },
};
