/* config: {
  title: string,
  content: string,
  id: string,
  width?: number = 600,
  height?: number = 400,
  minWidth?: number = 200,
  minHeight?: number = 200,
  posX?: number = null, // automatically centers window based on w/h
  posY?: number = null,
  onDestroy?: () => void
} */

let WINDOWS = {};
let MOUSE_MOVE_PROCESSING = {};
let globalIncrement = 1;

function createWindow(config) {
  if (document.getElementById(config.id)) {
    WINDOWS[config.id].element.style.zIndex = globalIncrement;
    WINDOWS[config.id].zIndex = globalIncrement;
    globalIncrement++;
    return;
  }

  // 1 - border
  // 10 - padding
  // 35 - header
  let _windowPaddingX = 1*2 + 10*2;
  let _windowPaddingY = 1*2 + 10*2 + 35;

  config.width = config.width || 600;
  config.height = config.height || 400;
  config.minWidth = config.minWidth || 200;
  config.minHeight = config.minHeight || 200;

  let realWidth = Math.max(config.minWidth, Math.min(config.width, innerWidth - _windowPaddingX - 20));
  let realHeight = Math.max(config.minHeight, Math.min(config.height, innerHeight - _windowPaddingY - 20));

  let posX = config.posX || Math.round((innerWidth / 2) - ((realWidth + _windowPaddingX) / 2));
  let posY = config.posY || Math.round((innerHeight / 2) - ((realHeight + _windowPaddingY) / 2));

  let wO = document.createElement("div");
  wO.classList.add("window-outer");

  let w = document.createElement("div");
  w.classList.add("window");
  w.style.width = `${realWidth}px`;
  w.style.height = `${realHeight}px`;
  w.innerHTML = config.content;

  let wH = document.createElement("div");
  wH.classList.add("window-header");
  wH.innerHTML = `
    <i class="window-header-button blank"></i>
    <i class="window-header-button blank"></i>
    <i class="window-header-button blank"></i>
    <strong class="window-header-title">${config.title}</strong>
    <i data-no-move class="window-header-button minimize"></i>
    <i data-no-move class="window-header-button fullscreen"></i>
    <i data-no-move class="window-header-button close"></i>
  `;

  let wC = document.createElement("div");
  wC.classList.add("window-container");
  wC.style.left = `${posX}px`;
  wC.style.top = `${posY}px`;
  wC.id = config.id;
  wC.style.zIndex = globalIncrement;
  wC.style.width = `${realWidth + _windowPaddingX - 2}px`;

  wO.append(w)
  wC.append(wH, wO);

  document.body.append(wC);
  WINDOWS[config.id] = {
    element: wC,
    height: realHeight,
    width: realWidth,
    posX: posX,
    posY: posY,
    mouseDown: false,
    fullscreen: false,
    zIndex: globalIncrement,
    vars: {}
  };

  function mouseMoveEvent(x, y) {
    WINDOWS[config.id].posX = Math.max(0, Math.min(innerWidth - WINDOWS[config.id].width - _windowPaddingX, x - WINDOWS[config.id].vars.mouseOffsetX));
    WINDOWS[config.id].posY = Math.max(0, Math.min(innerHeight - WINDOWS[config.id].height - _windowPaddingY, y - WINDOWS[config.id].vars.mouseOffsetY));
    wC.style.left = `${WINDOWS[config.id].posX}px`;
    wC.style.top = `${WINDOWS[config.id].posY}px`;
  }

  wC.addEventListener("mousedown", function() {
    wC.style.zIndex = globalIncrement;
    WINDOWS[config.id].zIndex = globalIncrement;
    globalIncrement++;
  })

  wH.addEventListener("mousedown", function(e) {
    if (e.target.dataset.noMove !== undefined) {
      return;
    }

    WINDOWS[config.id].mouseDown = true;
    WINDOWS[config.id].vars.mouseOffsetX = e.clientX - WINDOWS[config.id].posX;
    WINDOWS[config.id].vars.mouseOffsetY = e.clientY - WINDOWS[config.id].posY;
    MOUSE_MOVE_PROCESSING[config.id] = {
      callback: mouseMoveEvent,
      mouseUp: true
    };
  });

  wH.querySelector(".close").addEventListener("click", function() {
    delete WINDOWS[config.id];
    delete MOUSE_MOVE_PROCESSING[config.id];
    wC.remove();

    if (typeof config.onDestroy === "function") {
      config.onDestroy();
    }
  });

  wH.querySelector(".fullscreen").addEventListener("click", function() {
    if (WINDOWS[config.id].fullscreen) {
      WINDOWS[config.id].posX = WINDOWS[config.id].vars.oldPosX;
      WINDOWS[config.id].posY = WINDOWS[config.id].vars.oldPosY;
      WINDOWS[config.id].width = WINDOWS[config.id].vars.oldWidth;
      WINDOWS[config.id].height = WINDOWS[config.id].vars.oldHeight;
      WINDOWS[config.id].fullscreen = false;
      delete WINDOWS[config.id].vars.oldPosX;
      delete WINDOWS[config.id].vars.oldPosY;
      delete WINDOWS[config.id].vars.oldWidth;
      delete WINDOWS[config.id].vars.oldHeight;
      wC.style.left = `${WINDOWS[config.id].posX}px`;
      wC.style.top = `${WINDOWS[config.id].posY}px`;
      wC.style.width = `${WINDOWS[config.id].width + _windowPaddingX - 2}px`;
      w.style.width = `${WINDOWS[config.id].width}px`;
      w.style.height = `${WINDOWS[config.id].height}px`;
    } else {
      WINDOWS[config.id].vars.oldPosX = WINDOWS[config.id].posX;
      WINDOWS[config.id].vars.oldPosY = WINDOWS[config.id].posY;
      WINDOWS[config.id].vars.oldWidth = WINDOWS[config.id].width;
      WINDOWS[config.id].vars.oldHeight = WINDOWS[config.id].height;
      WINDOWS[config.id].fullscreen = true;
      WINDOWS[config.id].posX = 0;
      WINDOWS[config.id].posY = 0;
      WINDOWS[config.id].width = innerWidth;
      WINDOWS[config.id].height = innerHeight;
      wC.style.left = "0px";
      wC.style.top = "0px";
      wC.style.width = `${WINDOWS[config.id].width}px`;
      w.style.width = `${WINDOWS[config.id].width - _windowPaddingX}px`;
      w.style.height = `${WINDOWS[config.id].height - _windowPaddingY}px`;
    }
  });

  globalIncrement++;
}

window.addEventListener("mousemove", function(e) {
  for (const key of Object.keys(MOUSE_MOVE_PROCESSING)) {
    MOUSE_MOVE_PROCESSING[key].callback(e.clientX, e.clientY);
  }
});

window.addEventListener("mouseup", function() {
  for (const key of Object.keys(MOUSE_MOVE_PROCESSING)) {
    if (MOUSE_MOVE_PROCESSING[key].mouseUp) {
      delete MOUSE_MOVE_PROCESSING[key];
    };
  }
});

function windowPreset(template) {
  let el = document.querySelector(`#window-templates > [data-template-id="${template}"]`);

  if (!el) { return; }

  let config = {
    id: template
  };

  for (const field of el.querySelectorAll("[data-template-field]")) {
    config[field.dataset.templateField] = field.dataset.isNumber === "" ? +field.innerText : field.innerHTML;
  }

  createWindow(config);
}

function copyButton() {
  navigator.clipboard.writeText("<a href=\"https://trinkey.com/\" target=\"_blank\"><img src=\"https://trinkey.com/img/88x31.png\" alt=\"trinkey's 88x31. image of her cat on the right with the word trinkey taking up the rest of the button.\" title=\"trinkey's 88x31. image of her cat on the right with the word trinkey taking up the rest of the button.\"></a>");
}
