import PogObject from "../PogData";

const data = new PogObject("Draggable", {});

/**
 * Adds simple dragging mechanism to `display` whenever `enableDrag` is true.
 * Also automatically keeps track of `display`'s last saved position across
 * reloads.
 *
 * @param {string} id unique id for the `display` to be saved
 * @param {Display} display the Display to add dragging capability
 * @param {() => boolean} enableDrag the display will be draggable when `enableDrag` returns true
 * @param {"DELTA" | "JUMP"} dragMode whether to have the dragging calculate the
 * position using the delta or to jump to the mouse. Default is using delta.
 */
export const makeDisplayDraggable = (
  id,
  display,
  enableDrag,
  dragMode = "DELTA"
) => {
  if (id in data) {
    const { x, y } = data[id];
    display.setRenderLoc(x, y);
  } else {
    data[id] = {
      x: display.getRenderX(),
      y: display.getRenderY(),
    };
  }

  register("dragged", (dx, dy, mx, my) => {
    if (!enableDrag()) return;

    if (dragMode === "DELTA") {
      display.setRenderLoc(
        display.getRenderX() + dx,
        display.getRenderY() + dy
      );
    } else if (dragMode === "JUMP") {
      display.setRenderLoc(mx, my);
    }

    data[id] = {
      x: display.getRenderX(),
      y: display.getRenderY(),
    };
  });
};

/**
 * Adds simple dragging mechanism to `object` whenever `enableDrag` is true.
 * Also automatically keeps track of `object`'s last saved position across
 * reloads.
 *
 * @param {string} id unique id for the `object` to be saved
 * @param {{ x: number; y: number; }} object the coordinate object to update when dragging
 * @param {() => boolean} enableDrag the display will be draggable when `enableDrag` returns true
 * @param {"DELTA" | "JUMP"} dragMode whether to have the dragging calculate the
 * position using the delta or to jump to the mouse. Default is using delta.
 */
export const makeObjectDraggable = (
  id,
  object,
  enableDrag,
  dragMode = "DELTA"
) => {
  if (id in data) {
    const { x, y } = data[id];
    object.x = x;
    object.y = y;
  } else {
    data[id] = {
      x: object.x,
      y: object.y,
    };
  }

  register("dragged", (dx, dy, mx, my) => {
    if (!enableDrag()) return;

    if (dragMode === "DELTA") {
      object.x += dx;
      object.y += dy;
    } else if (dragMode === "JUMP") {
      object.x = mx;
      object.y = my;
    }

    data[id] = {
      x: object.x,
      y: object.y,
    };
  });
};

register("gameUnload", () => {
  data.save();
});
