const REQUEST_FULLSCREEN = [
  "requestFullscreen",
  "webkitRequestFullscreen",
  "webkitRequestFullScreen",
  "mozRequestFullScreen",
  "msRequestFullscreen",
  "webkitEnterFullscreen",
];

const EXIT_FULLSCREEN = [
  "exitFullscreen",
  "webkitExitFullscreen",
  "webkitCancelFullScreen",
  "mozCancelFullScreen",
  "msExitFullscreen",
  "webkitExitFullscreen",
];

const FULLSCREEN_ELEMENT = [
  "fullscreenElement",
  "webkitFullscreenElement",
  "webkitCurrentFullScreenElement",
  "mozFullScreenElement",
  "msFullscreenElement",
  "webkitDisplayingFullscreen",
];

const FULLSCREEN_CHANGE = [
  "fullscreenchange",
  "webkitfullscreenchange",
  "mozfullscreenchange",
  "MSFullscreenChange",
  "webkitbeginfullscreen",
  "webkitendfullscreen",
];

export class Fullscreen {
  constructor(element, document, changeCallback) {
    // iOS: a video element (native fullscreen)
    // Others: a wrapper around a video element
    this.element = element;

    // iOS: a video element (native fullscreen)
    // Others: document (global variable)
    this.document = document;
    this.changeCallback = changeCallback;

    FULLSCREEN_CHANGE.forEach((name) => {
      this.element.addEventListener(name, this.changeCallback);
    });
  }

  findApi(element, choices) {
    return choices.find((name) => {
      return typeof element[name] === "function";
    });
  }

  fullscreenEnabled() {
    return !!FULLSCREEN_ELEMENT.find((name) => !!this.document[name]);
  }

  requestFullscreen() {
    const element = this.element;
    const name = this.findApi(element, REQUEST_FULLSCREEN);
    return element[name].call(element);
  }

  exitFullscreen() {
    const document = this.document;
    const name = this.findApi(document, EXIT_FULLSCREEN);
    return document[name].call(document);
  }

  destroy() {
    FULLSCREEN_CHANGE.forEach((name) => {
      this.element.removeEventListener(name, this.changeCallback);
    });
  }
}
