Pre-release
AdventureJS Docs Downloads Bundler Devlog
Score: 0 Moves: 0
// Outrocard.js
(function () {
  /* global AdventureJS A */

  /**
   * @class AdventureJS.Outrocard
   * @ajsinternal
   * @param {Game} game A reference to the game instance.
   * @ajsnavheading EngineClasses
   * @summary Manages the outrocard for a {@link AdventureJS.Game|Game} instance.
   * @classdesc
   * <p>
   * <strong>Outrocard</strong> can be used to print a completion screen
   * when a player reaches an end state of the game (win, lose, or draw).
   * Outrocard is created
   * automatically by {@link AdventureJS.Game|Game}. This is an internal
   * class that authors should not need to construct. However, authors
   * can set title options from their game file as shown below.
   * </p>
   * <h3 class="examples">Example:</h3>
   * <pre class="display"><code class="language-javascript">var MyGame = new AdventureJS.Game( "MyGame", "GameContainer" );
   * MyGame.Outrocard.set({
   * });
   * </code></pre>
   */
  class Outrocard {
    constructor(game) {
      this.game = game;

      /**
       * Optional text to show at the top of the outrocard.
       * @var {String} AdventureJS.Outrocard#text
       * @default ""
       */
      this.text = ``;

      /**
       * Show undo button on outrocard.
       * @var {Boolean} AdventureJS.Outrocard#show_undo
       * @default true
       */
      this.show_undo = true;

      /**
       * Show restore button on outrocard.
       * @var {Boolean} AdventureJS.Outrocard#show_restore
       * @default true
       */
      this.show_restore = true;

      /**
       * Show restart button on outrocard.
       * @var {Boolean} AdventureJS.Outrocard#show_restart
       * @default true
       */
      this.show_restart = true;

      /**
       * Show quit button on outrocard.
       * @var {Boolean} AdventureJS.Outrocard#show_quit
       * @default true
       */
      this.show_quit = true;

      /**
       * If true, clear the screen when showing the outro.
       * @var {Boolean} AdventureJS.Outrocard#clear_on_show
       * @default false
       */
      this.clear_on_show = false;

      /**
       * If true, clear the screen when choosing a followup option.
       * @var {Boolean} AdventureJS.Outrocard#clear_on_continue
       * @default false
       */
      this.clear_on_continue = false;

      /**
       * Hide statusbar when outrocard is shown
       * @var {Boolean} AdventureJS.Outrocard#hide_statusbar
       * @default false
       */
      this.hide_statusbar = false;

      /**
       * If statusbar was hidden on showing the outrocard,
       * restore it on hiding the outrocard.
       * @var {Boolean} AdventureJS.Introcard#show_statusbar_on_continue
       * @default true
       */
      this.show_statusbar_on_continue = true;

      /**
       * Hide titlebar when outrocard is shown.
       * @var {Boolean} AdventureJS.Outrocard#hide_titlebar
       * @default false
       */
      this.hide_titlebar = false;

      /**
       * If titlebar was hidden on showing the outrocard,
       * restore it on hiding the outrocard.
       * @var {Boolean} AdventureJS.Outrocard#show_titlebar_on_continue
       * @default true
       */
      this.show_titlebar_on_continue = true;

      /**
       * Used to keep track of the outrocard's visibility.
       * @var {Boolean} AdventureJS.Outrocard#is_shown
       * @default true
       */
      this.is_shown = false;
    }

    /**
     * Show the outrocard.
     * @method AdventureJS.Outrocard#show
     */
    show(msg = "", print = false) {
      let options = "";

      this.game.display.updateDisplaySizes(); // ensure that view height is correct

      if (this.clear_on_show) {
        this.game.display.clearOutput();
      }

      if (this.hide_statusbar) {
        this.game.display.hideStatusbar();
        if (this.show_statusbar_on_continue) {
          this.game.state_vars.show_statusbar = true;
        }
      }

      if (this.hide_titlebar) {
        this.game.display.hideTitlebar();
        if (this.show_titlebar_on_continue) {
          this.game.state_vars.show_titlebar = true;
        }
      }

      if (msg) {
        msg = A.FX.getSAF.call(this.game, msg);
      } else if (this.text) {
        msg = A.FX.getSAF.call(this.game, this.text);
      }
      if (msg) {
        msg = `<div class="ajs-p ajs-outro-text">${msg}</div>`;
      }

      let verbs = [];
      let game = this.game.game_name;
      if (this.show_undo) {
        verbs.push("undo");
        options += `
          <a href='#' 
            class='ajs-outro-link' 
            onclick='window.${game}.parser.parseInput("undo")'
          >undo</a>
        `;
      }

      if (this.show_restore) {
        verbs.push("restore");
        options += `
          <a href='#' 
            class='ajs-outro-link' 
            onclick='window.${game}.parser.parseInput("restore")'
          >restore</a>
        `;
      }

      if (this.show_restart) {
        verbs.push("restart");
        options += `
          <a href='#' 
            class='ajs-outro-link' 
            onclick='window.${game}.parser.parseInput("restart")'
          >restart</a>
        `;
      }

      if (this.show_quit) {
        verbs.push("quit");
        options += `
          <a href='#' 
            class='ajs-outro-link' 
            onclick='window.${game}.parser.parseInput("quit")'
          >quit</a>
        `;
      }

      if (options) {
        options = `<div class="ajs-p ajs-outro-links">${options}</div>`;
        msg = msg + options;
      }

      msg = `<div class="ajs-outrocard-container"><div class="ajs-outrocard">${msg}</div></div>`;

      if (msg) {
        if (print) this.game.print(msg);
        else this.game.overrideOutput(msg);

        if (verbs.length) {
          this.game.parser.restrictInput(verbs);
        }

        this.is_shown = true;
      }
    }

    /**
     * Hide the outrocard.
     * @method AdventureJS.Outrocard#hide
     */
    hide(input) {
      console.warn(`*** outrocard.hide(${input})`);

      if (["undo"].includes(input.toLowerCase())) {
        // this.game.display.clearOutput();
        this.clear();
      }
      if (this.show_statusbar_on_continue) {
        this.game.display.showStatusbar();
      }
      if (this.show_titlebar_on_continue) {
        this.game.display.showTitlebar();
      }
      this.is_shown = false;
    }

    /**
     * Clears the outrocard from the output without
     * removing other content.
     * @method AdventureJS.Outrocard#hide
     */
    clear() {
      const outro = this.game.display.outputEl.querySelector(
        ".ajs-outrocard-container"
      );
      outro.style.maxHeight = 0;
      setTimeout(() => {
        outro.remove();
      }, 500);
    }

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