Pre-release
AdventureJS Docs Downloads
Score: 0 Moves: 0
// GoalManager.js

(function () {
  /* global adventurejs A */

  /**
   *
   * @class adventurejs.GoalManager
   * @ajsnavheading FrameworkClasses
   * @param {Game} game A reference to the game instance.
   * @summary Manages the display of the goal system.
   * @classdesc
   * <p>
   * <strong>GoalManager</strong> manages the job of displaying goals.
   * It contains all the methods needed to create the
   * Goal pop-up screen.
   * </p>
   * <p>
   * GoalManager is created automatically
   * by {@link adventurejs.Game|Game}. This is an internal class that
   * authors should not need to construct or modify. However, if
   * you'd like to try, you can find styles for the Goal
   * pop-ups in <a href="/css/adventurejs.css">adventurejs.css</a>.
   * All relevant styles are prefixed with '.goal_'.
   * </p>
   */
  class GoalManager {
    constructor(game) {
      /**
       * A reference back to the main {@link adventurejs.Game|Game} object.
       * @var {Object} adventurejs.GoalManager#game
       * @default {}
       */
      this.game = game;

      /**
       * Used to manage the drawing of the goal dialog.
       * @var {Object} adventurejs.GoalManager#initialized
       * @default false
       */
      this.initialized = false;

      /**
       * Div element to contain the Goal dialog.
       * @var {HTMLElement} adventurejs.GoalManager#goal_dialog
       * @default {}
       */

      // MODAL VERSION
      // this.goal_dialog = document.createElement("dialog");

      // NON-MODAL VERSION
      this.goal_dialog = document.createElement("div");
      this.goal_dialog.setAttribute("aria-hidden", true);
      this.goal_dialog.setAttribute("aria-modal", true);
      this.goal_dialog.role = "dialog";
      this.goal_dialog.style.display = "none";
      this.goal_dialog.tabIndex = "1";

      this.goal_dialog.classList.add("ajs-goal-dialog", "ajs-dialog");
      this.goal_dialog.setAttribute(
        "aria-labelledby",
        `${this.game.game_name}-goal-dialog-title`
      );
      this.game.display.dialogsEl.appendChild(this.goal_dialog);

      // Source HTML is stored in goalManager.html
      this.goal_dialog.innerHTML = `
        <div class="ajs-goal-dialog-outer ajs-dialog-outer">
          <div class="ajs-goal-dialog-inner ajs-dialog-inner">

            <h2 id="${this.game.game_name}-goal-dialog-title" class="ajs-goal-dialog-title ajs-dialog-title">GOALS</h2>

            <div class="ajs-goal-dialog-content ajs-dialog-content">

              <!-- put content here -->
              <div class="ajs-goal-list-container">
                <div id="${this.game.game_name}-goal-list">
                </div>              
              </div>


              <div class="ajs-goal-dialog-buttons ajs-dialog-button-container">
                <button
                  id="${this.game.game_name}-goal-dialog-cancel-button"
                  class="ajs-goal-dialog-cancel-button ajs-cancel-button ajs-button ajs-dialog-button button-secondary"
                  type="button"
                  value="Cancel"
                  name="goalCancel"
                >
                  Exit
                </button>
              </div>
              <!-- /ajs-goal-dialog-buttons -->

            </div>
            <!-- /ajs-goal-dialog-content -->

          </div> 
          <!-- /ajs-goal-dialog-inner -->
        </div>
        <!-- /ajs-goal-dialog-outer -->
      `;

      // goal_list is where we'll put our text
      this.goal_list = this.goal_dialog.querySelector(
        `#${this.game.game_name}-goal-list`
      );

      // --------------------------------------------------
      // EXIT BUTTON
      // --------------------------------------------------

      /**
       * Button element to dispel the Goal dialog.
       * @var {HTMLElement} adventurejs.GoalManager#goalCancel
       * @default {}
       */
      this.goalCancel = this.game.display.displayEl.querySelector(
        `#${this.game.game_name}-goal-dialog-cancel-button`
      );
      this.goalCancel.manager = this;
      this.goalCancel.addEventListener("click", function () {
        this.manager.clickClose();
      });

      this.handleEscape = this.handleEscape.bind(this);
    } // constructor

    /**
     * Open the Goal modal dialog.
     * @memberOf adventurejs.GoalManager
     * @method adventurejs.GoalManager#openDialog
     * @kind function
     */
    openDialog() {
      // if (!this.initialized) {
      if (this.game.goalcard.introduction) {
        this.goal_list.innerHTML = `
            <div class="ajs-goal-introduction">
              ${this.game.goalcard.introduction}
            </div>
          `;
      }
      this.goal_list.innerHTML = this.game.goalcard.listGoals();
      this.initialized = true;
      // }

      document.addEventListener("keyup", this.handleEscape);

      // activate dialog
      this.goal_dialog.classList.add("active");

      // MODAL VERSION
      // this.goal_dialog.showModal();

      // NON-MODAL VERSION
      // deactivate main content
      document.activeElement.blur();
      this.game.display.contentEl.blur();
      this.game.display.contentEl.setAttribute("aria-hidden", true);
      this.game.display.contentEl.setAttribute("inert", "");
      // activate dialog
      this.goal_dialog.style.display = "block";
      this.goal_dialog.classList.add("active");
      this.goal_dialog.setAttribute("aria-hidden", false);
      this.goal_dialog.focus();
    }

    /* *
     * Prep goal data for display in the goals modal.
     * @memberOf adventurejs.GoalManager
     * @method adventurejs.GoalManager#drawGoals
     * @kind function
     */
    // drawGoals(goals = this.game.goalcard.goals, html = "") {}

    /**
     * Close the Goal modal dialog.
     * @memberOf adventurejs.GoalManager
     * @method adventurejs.GoalManager#closeDialog
     * @kind function
     */
    closeDialog() {
      document.removeEventListener("keyup", this.handleEscape);
      this.goal_dialog.classList.remove("active");

      // MODAL VERSION
      // this.goal_dialog.close();

      // NON-MODAL VERSION
      document.activeElement.blur();
      this.goal_dialog.setAttribute("aria-hidden", true);
      setTimeout(() => {
        this.goal_dialog.style.display = "none";
        this.game.display.contentEl.setAttribute("aria-hidden", false);
        this.game.display.contentEl.removeAttribute("inert");
        // set focus on input
        this.game.display.inputEl.focus();
      }, 250);
    }

    /**
     * Function that closes the dialog on escape keyup.
     * @param {*} event
     */
    handleEscape(event) {
      var key = event.which || event.keyCode;
      if (key === 27) {
        event.stopPropagation();
        this.game.goalManager.clickClose(this);
      }
    }

    /**
     * Function that gets called by the Close button.
     * @memberOf adventurejs.GoalManager
     * @method adventurejs.GoalManager#clickClose
     * @kind function
     */
    clickClose() {
      this.closeDialog();
      var msg = "Goals closed.";
      this.game.print(msg);
      return;
    }

    /**
     * Provides a chainable shortcut method for setting a number of properties on the instance.
     * @method adventurejs.GoalManager#set
     * @param {Object} props A generic object containing properties to copy to the DisplayObject instance.
     * @returns {adventurejs.GoalManager} Returns the instance the method is called on (useful for chaining calls.)
     * @chainable
     */
    set(props) {
      return A.deepSet.call(this.game, props, this);
    }
  }
  adventurejs.GoalManager = GoalManager;
})();