Source: topbar.js

import * as Editor from './editor-page.js';

/**
 * Initializes all listener actions for the top bar,
 * which will then have functionality when the
 * user clicks on them.
 */
export function initListeners() {
  // go back to previous page
  const back = document.querySelector('#back-button');
  back.addEventListener('click', () => {
    window.history.back();
  });

  // go back to home menu
  const home = document.querySelector('#home-button');
  home.addEventListener('click', (e) => {
    window.location.href = './homepage.html';
  });

  // lets the user edit the card name directly
  const cardTitle = document.querySelector('#card-title');
  cardTitle.addEventListener('focusout', () => {
    let name = cardTitle.innerHTML;
    if (name === '') name = Editor.nextUntitled();
    if (name !== Editor.cardName) {
      Editor.setSaved(false);
      Editor.setCardName(name);
    }
  });

  // resets the card to its last save
  const reset = document.querySelector('#reset-button');
  reset.addEventListener('click', Editor.reset);

  // delete button
  // triggers a confirmation before deleting
  const del = document.querySelector('#delete-button');
  del.addEventListener('click', triggerDeleteMenu);

  // saves the card
  const saveNormal = document.querySelector('#save-button');
  saveNormal.addEventListener('click', Editor.saveAs);

  // triggers the save as menu
  const saveAs = document.querySelector('#save-as');
  saveAs.addEventListener('click', triggerSaveAsMenu);

  // triggers the open card menu
  const openMenu = document.querySelector('#file-open');
  openMenu.addEventListener('click', triggerOpenMenu);

  const jpgexport = document.getElementById('export-jpg');
  const pngexport = document.getElementById('export-png');
  const jsonexport = document.getElementById('export-json');
  const duplicate = document.getElementById('file-duplicate');

  // duplicates the current card
  duplicate.addEventListener('click', () => {
    Editor.setSaved(false);
    Editor.setCardName(`Copy of ${Editor.cardName}`);
  });

  // exports the current card shown to JPG
  // only saves front or back one at a time
  jpgexport.addEventListener('click', () => {
    const active = Editor.frontCanvas.active;
    let activeCanvas;
    let name;
    if (active) {
      activeCanvas = Editor.frontCanvas;
      name = `${Editor.cardName}-front.jpg`;
    } else {
      activeCanvas = Editor.backCanvas;
      name = `${Editor.cardName}-back.jpg`;
    }

    const url = activeCanvas.canvas.toDataURL('image/jpeg', 0.95);
    Editor.downloadURL(url, name);
  });

  // exports the current card shown to PNG
  // only saves front or back one at a time
  pngexport.addEventListener('click', () => {
    const active = Editor.frontCanvas.active;
    let activeCanvas;
    let name;

    if (active) {
      activeCanvas = Editor.frontCanvas;
      name = `${Editor.cardName}-front.png`;
    } else {
      activeCanvas = Editor.backCanvas;
      name = `${Editor.cardName}-back.png`;
    }

    const url = activeCanvas.canvas.toDataURL('image/png');
    Editor.downloadURL(url, name);
  });

  // exports the current card to JSON
  jsonexport.addEventListener('click', () => {
    const exportData = {
      front: Editor.frontCanvas.exportJSON(),
      back: Editor.backCanvas.exportJSON()
    };
    const str = JSON.stringify(exportData, null, 2);
    const blob = new Blob([str], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    Editor.downloadURL(url, `${Editor.cardName}.json`);
    URL.revokeObjectURL(url);
  });

  const fileNew = document.querySelector('#file-new');
  fileNew.addEventListener('click', () => {
    Editor.openNew();
  });
}

/**
 * Removes the current popup menu, hiding it from
 * the user. This is important because we reuse the same
 * div to handle the popup menu, so we need to hide it away
 * whenever a menu is gone; we can't delete it.
 */
export function removePopupMenu() {
  const menu = document.querySelector('#popup-menu');
  if (!menu) { return; }

  menu.innerHTML = '';
  menu.style.display = 'none';
}

/**
 * Makes the popup menu into a confirmation screen before
 * the user deletes the current card.
 *
 * @param {*} e The click event triggering the menu; unused
 */
function triggerDeleteMenu(e) {
  const menu = document.querySelector('#popup-menu');
  if (!menu) { return; }

  menu.innerHTML =
    `
    <p>Are you sure you want to delete this card? It will be lost forever...</p>
    <button id='popup-delete-button'>Delete Card</button>
    `;
  menu.style.display = 'block';

  const style = document.createElement('style');
  style.innerHTML =
    `
    #popup-menu {
        display: block;
        position: absolute;
        z-index: 1;
        width: 250px;
        height: 150px;
        background-color: var(--sidebar-bg);
        padding: 15px;
        border-radius: 5px;
        top: 38vh;
    }
    
    #popup-menu button {
        background-color: red;
        border: 0;
        padding: 0.4rem;
        color: white;
        border-radius: 3px;
    }
    
    #popup-menu button:hover {
        background-color: rgb(227, 0, 0);
    }
    `;

  menu.appendChild(style);

  const innerDelete = document.querySelector('#popup-delete-button');
  innerDelete.addEventListener('click', (e) => {
    console.log('delete');
    Editor.deleteCard();
    removePopupMenu();
  });
}

/**
 * Triggers an open menu, where the user can
 * select a card to open from their list of currently
 * available cards.
 */
function triggerOpenMenu() {
  const menu = document.querySelector('#popup-menu');
  if (!menu) { return; }

  menu.innerHTML =
    `
    <div id="modal-content">
      <h2>Open Business Card</h2>
      <label for="card-select">Select a saved card:</label>
      <select id="card-select">
      </select>
      <button id="open-card-btn">Open</button>
      <button id="cancel-open-btn">Cancel</button>
    </div>
    `;
  menu.style.display = 'block';

  const style = document.createElement('style');
  style.innerHTML =
    `
    #popup-menu {
      position: fixed;
      top: 40vh;
      left: 50%;
      transform: translateX(-50%);
      z-index: 1000;
      width: 300px;
      background-color: var(--sidebar-bg);
      padding: 20px;
      border-radius: 10px;
      box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
      font-family: sans-serif;
    }

    #popup-menu h2 {
      margin-top: 0;
      font-size: 18px;
      text-align: center;
    }

    #popup-menu label {
      display: block;
      margin-bottom: 5px;
      font-size: 14px;
    }

    #popup-menu select {
      width: 100%;
      padding: 0.4rem;
      margin-bottom: 15px;
      border: 1px solid #ccc;
      border-radius: 4px;
      font-size: 14px;
    }

    #popup-menu button {
      width: 100%;
      background-color: var(--save-bg);
      border: none;
      padding: 0.5rem;
      margin-top: 5px;
      color: white;
      border-radius: 4px;
      font-size: 14px;
      cursor: pointer;
    }

    #popup-menu button:hover {
      background-color: var(--save-hover-bg);
    }
    `;

  menu.appendChild(style);

  const select = document.getElementById('card-select');
  const cards = Editor.importCardsList();
  const cardNames = Object.keys(cards);
  if (cardNames.length === 0) {
    const option = document.createElement('option');
    option.textContent = 'No saved cards!';
    option.disabled = true;
    option.selected = true;
    select.appendChild(option);
  } else {
    for (let i = 0; i < cardNames.length; i++) {
      const option = document.createElement('option');
      option.value = cardNames[i];
      option.textContent = cardNames[i];
      if (cardNames[i] === Editor.cardName) { option.selected = 'selected'; }
      select.appendChild(option);
    }
  }

  document.getElementById('cancel-open-btn').addEventListener('click', () => {
    removePopupMenu();
  });

  const openCard = document.querySelector('#open-card-btn');
  openCard.addEventListener('click', () => {
    const selected = select.value;
    Editor.frontCanvas.importJSON(cards[selected].front);
    Editor.backCanvas.importJSON(cards[selected].back);
    Editor.setSaved(true);
    Editor.setCardName(selected);
    Editor.exportCurrentCardName();
    removePopupMenu();
  });
}

/**
 * Opens a "save as" menu, where the user can choose the
 * name of their card that they want to save it as.
 *
 * @param {*} e The click event triggering the menu; unused
 */
function triggerSaveAsMenu(e) {
  const menu = document.querySelector('#popup-menu');
  if (!menu) { return; }

  menu.innerHTML =
    `
    <label for="popup-save-as">Title: </label>
    <input type="text" title="popup-save-as" id="popup-save-as" autocomplete="off"></input>
    <button id="popup-save-button">Save</button>
    `;
  menu.style.display = 'block';

  const style = document.createElement('style');
  style.innerHTML =
    `
    #popup-menu {
        display: block;
        position: absolute;
        align-content: center;
        z-index: 1;
        width: 250px;
        height: 100px;
        background-color: var(--sidebar-bg);
        padding: 15px;
        border-radius: 5px;
        top: 40vh;
    }
    
    #popup-menu input[type='text'] {
        border: 0;
    }
    
    #popup-menu button {
        background-color: var(--save-bg);
        border: 0;
        padding: 0.4rem;
        color: white;
        border-radius: 3px;
    }
    
    #popup-menu button:hover {
        background-color: var(--save-hover-bg);
    }
    `;

  menu.appendChild(style);

  const saveButton = document.querySelector('#popup-save-button');
  saveButton.addEventListener('click', (e) => {
    const name = document.querySelector('#popup-save-as').value;
    Editor.saveAs(name);
    removePopupMenu();
  });
}

/**
 * Sets the name in the top bar, adding an asterisk
 * if the card isn't saved.
 *
 * @param {String} name Name to set to
 */
export function setName(name) {
  if (!name) { name = 'Untitled'; }

  let bold = false;
  const saveStar = document.querySelector('#save-star');
  if (!Editor.saved) {
    bold = true;
    saveStar.innerHTML = '*';
  } else {
    saveStar.innerHTML = '';
  }

  const cardTitle = document.querySelector('#card-title');
  cardTitle.innerHTML = name;
  if (bold) cardTitle.style.fontWeight = 'bold';
  else cardTitle.style.fontWeight = 'normal';
}