Source: editor_actions.js

/**
 * Presenter classes for managing editor UI actions and indicators.
 *
 * @license BSD, see LICENSE.md.
 */

/**
 * Manages the running indicator and progress bar display.
 */
class RunningIndicatorPresenter {
  constructor() {
    const self = this;
    self._runningIndicator = document.getElementById("running-indicator");
    self._progressBar = document.getElementById("simulation-progress");
    self._resultsSection = document.getElementById("results");
  }

  /**
   * Show the running indicator with progress at 0%.
   */
  show() {
    const self = this;
    self.reset();
    self._resultsSection.style.display = "block";
    self._runningIndicator.style.display = "block";
  }

  /**
   * Hide the running indicator.
   */
  hide() {
    const self = this;
    self._runningIndicator.style.display = "none";
  }

  /**
   * Update the progress bar.
   *
   * @param {number} percentage - Progress percentage (0-100)
   */
  updateProgress(percentage) {
    const self = this;
    self._progressBar.value = percentage;
  }

  /**
   * Reset progress to 0%.
   */
  reset() {
    const self = this;
    self.updateProgress(0);
  }
}

/**
 * Presenter controlling the main simulation buttons.
 *
 * Presenter which controls the functionality of the script and run button panel
 * in the UI which allow for basic tool functionality (switching authoring modes
 * and running the simulation).
 */
class ButtonPanelPresenter {
  /**
   * Creates a new ButtonPanelPresenter instance.
   *
   * @param {HTMLElement} root - The root element containing the button panel.
   * @param {Function} onBuild - Callback function triggered when build/run is initiated.
   */
  constructor(root, onBuild) {
    const self = this;
    self._root = root;

    self._availableDisplay = self._root.querySelector("#available-panel");
    self._autorunDisplay = self._root.querySelector("#auto-run-panel");
    self._loadingDisplay = self._root.querySelector("#loading");
    self._runButton = self._root.querySelector("#run-button");

    self._onBuild = onBuild;
    self._runButton.addEventListener("click", (run) => {
      self._onBuild(run);
    });

    self.enable();
  }

  /**
   * Enables the button panel and shows available options.
   */
  enable() {
    const self = this;
    self._availableDisplay.style.display = "block";
    self._autorunDisplay.style.display = "block";
    self._loadingDisplay.style.display = "none";
  }

  /**
   * Disables the button panel and shows loading state.
   */
  disable() {
    const self = this;
    self._availableDisplay.style.display = "none";
    self._autorunDisplay.style.display = "none";
    self._loadingDisplay.style.display = "block";
  }

  /**
   * Hides script-related buttons.
   */
  hideScriptButtons() {
    const self = this;
    self._runButton.style.display = "none";
  }

  /**
   * Shows script-related buttons.
   */
  showScriptButtons() {
    const self = this;
    self._runButton.style.display = "inline-block";
  }
}

/**
 * Manages tooltip display and user preferences for help tooltips.
 *
 * Handles initialization, user preference storage, and tooltip lifecycle
 * management using Tippy.js for accessible tooltip display.
 */
class TooltipPresenter {
  /**
   * Create a new tooltip presenter.
   *
   * @param {LocalStorageKeeper} storageKeeper - Storage manager for user preferences
   */
  constructor(storageKeeper) {
    const self = this;
    self._storageKeeper = storageKeeper;
    self._tooltipInstances = new Map();
    self._enabled = self._loadPreference();
    self._welcomeCheckbox = null;
    self._footerButton = null;
  }

  /**
   * Initialize the tooltip system.
   *
   * Sets up preference controls and creates tooltips if enabled.
   */
  initialize() {
    const self = this;
    self._setupPreferenceControls();
    if (self._enabled) {
      self._createTooltips();
    }
  }

  /**
   * Toggle tooltip visibility.
   *
   * @param {boolean} enabled - Whether tooltips should be shown
   */
  setEnabled(enabled) {
    const self = this;
    self._enabled = enabled;
    self._storageKeeper.setShowTooltips(enabled);

    if (enabled) {
      self._createTooltips();
    } else {
      self._destroyTooltips();
    }

    self._updateControls();
  }

  /**
   * Get current tooltip enabled state.
   *
   * @returns {boolean} Whether tooltips are currently enabled
   */
  isEnabled() {
    const self = this;
    return self._enabled;
  }

  /**
   * Load tooltip preference from storage.
   *
   * @returns {boolean} Tooltip preference (defaults to true)
   * @private
   */
  _loadPreference() {
    const self = this;
    const stored = self._storageKeeper.getShowTooltips();
    return stored !== null ? stored : true; // Default to enabled
  }

  /**
   * Setup preference control elements and event handlers.
   *
   * @private
   */
  _setupPreferenceControls() {
    const self = this;
    self._setupWelcomeScreen();
    self._setupFooterToggle();
  }

  /**
   * Setup welcome screen checkbox and event handler.
   *
   * @private
   */
  _setupWelcomeScreen() {
    const self = this;
    self._welcomeCheckbox = document.getElementById("tooltip-preference-check");
    self._welcomeCheckbox.checked = self._enabled;
    self._welcomeCheckbox.addEventListener("change", function (event) {
      self.setEnabled(event.target.checked);
    });
  }

  /**
   * Setup footer toggle button and event handler.
   *
   * @private
   */
  _setupFooterToggle() {
    const self = this;
    self._footerButton = document.getElementById("tooltip-toggle-button");
    self._updateControls();
    self._footerButton.addEventListener("click", function (event) {
      event.preventDefault();
      self.setEnabled(!self._enabled);
    });
  }

  /**
   * Update control elements to reflect current state.
   *
   * @private
   */
  _updateControls() {
    const self = this;

    self._welcomeCheckbox.checked = self._enabled;
    const footerText = self._enabled ? "Disable Tooltips" : "Enable Tooltips";
    self._footerButton.textContent = footerText;
  }

  /**
   * Create tooltips for all target elements.
   *
   * @private
   */
  _createTooltips() {
    const self = this;

    const elements = document.querySelectorAll("[data-tippy-content]");
    elements.forEach(function (element) {
      const instance = tippy(element, {
        appendTo: "parent",
      });
      self._tooltipInstances.set(element, instance);
    });
  }

  /**
   * Destroy all tooltip instances.
   *
   * @private
   */
  _destroyTooltips() {
    const self = this;

    self._tooltipInstances.forEach(function (instance) {
      instance.destroy();
    });
    self._tooltipInstances.clear();
  }
}

export {RunningIndicatorPresenter, ButtonPanelPresenter, TooltipPresenter};