core/symbol.js

import { NONE } from "./color.js";

/**
 * An immutable visual representation of a piece on the board.
 *
 * Boards are marked as either "outside" (sunlit, natural colors) or
 * "underground" (dark, roguelike terminal palette). The symbol carries
 * separate color/background pairs for each mode.
 *
 * Symbols are layered: terrain → items → effects → agent. The top-most
 * non-null color and background values win for each cell.
 */
export class Symbol {
  static of(entity, color, bg, outsideColor, outsideBg) {
    if (arguments.length === 2) {
      return new Symbol(entity, color, null, color, null);
    } else if (arguments.length === 3) {
      return new Symbol(entity, color, bg, color, bg, entity);
    } else {
      return new Symbol(entity, color, bg, outsideColor, outsideBg);
    }
  }
  /**
   * @param {string} entity         - HTML entity / character to display
   * @param {Color|null} color     - Underground foreground color (null = inherit)
   * @param {Color|null} background - Underground background color (null = inherit)
   * @param {Color|null} outsideColor - Outside foreground color (null = same as color)
   * @param {Color|null} outsideBackground - Outside background color (null = same as background)
   */
  constructor(entity, color, background, outsideColor, outsideBackground) {
    this.entity = entity;
    this.color = color;
    this.background = background;
    this.outsideColor = outsideColor;
    this.outsideBackground = outsideBackground;
  }

  /** Foreground Color for the given lighting mode. @returns {Color|null} */
  getColor(outside) {
    return outside ? this.outsideColor : this.color;
  }

  /** Background Color for the given lighting mode. @returns {Color|null} */
  getBackground(outside) {
    return outside ? this.outsideBackground : this.background;
  }
}