baja/obj/FrozenEnum.js

/**
 * @copyright 2015 Tridium, Inc. All Rights Reserved.
 * @author Gareth Johnson
 */

/**
 * Defines {@link baja.FrozenEnum}.
 * @module baja/obj/FrozenEnum
 */
define([ "bajaScript/sys",
        "bajaScript/baja/obj/DynamicEnum",
        "bajaScript/baja/obj/Enum" ], 
        function (baja, DynamicEnum, Enum) {
  
  "use strict";
  
  var subclass = baja.subclass,
      callSuper = baja.callSuper;
  
  /**
   * Represents a `baja:FrozenEnum` in BajaScript.
   * 
   * In Niagara, a `BFrozenEnum` is a hard coded set of enumerations and is immutable.
   * 
   * `FrozenEnum` objects are treated in a special way in BajaScript. A 
   * `FrozenEnum`'s range (also known as a Contract in BajaScript) is lazily 
   * requested and stored within the BajaScript registry. Therefore, this 
   * object shouldn't be used directly. 
   *
   * @class
   * @alias baja.FrozenEnum
   * @extends baja.Enum
   *
   * @see baja.FrozenEnum#get
   * 
   * @example
   * // Here's the preferred way to access a `FrozenEnum`:
   * var en = baja.$("baja:Weekday").get("monday");
   */
   var FrozenEnum = function FrozenEnum() {
    // This Constructor should be considered private
    callSuper(FrozenEnum, this, arguments);  
    this.$ordinal = 0;
  };
  
  subclass(FrozenEnum, Enum);
  
  /**
   * Called once a Contract has been loaded onto a `FrozenEnum`.
   * 
   * This method is designed to be overridden.
   *
   * @private
   */
  FrozenEnum.prototype.contractCommitted = function () { 
  };
  
  /**
   * Make a `FrozenEnum`.
   *
   * @private
   *
   * @param {String|Number} arg the tag or ordinal of the frozen enum we want to access.
   *
   * @see baja.FrozenEnum#make
   *
   * @returns {baja.FrozenEnum} the frozen enum.
   */  
  FrozenEnum.prototype.make = function (arg) {
    return this.get(arg);
  };
  
  /**
   * Decode a `FrozenEnum` from a `String`.
   *
   * @param {String} str
   * @returns {baja.FrozenEnum}
   */   
  FrozenEnum.prototype.decodeFromString = function (str) {   
    return this.get(str);  
  };
  
  /**
   * Encode the `FrozenEnum` to a `String`.
   *
   * @returns {String}
   */ 
  FrozenEnum.prototype.encodeToString = function () {    
    return this.getTag();
  };
  
  /**
   * Default FrozenEnum instance.
   *
   * @private
   * @type {baja.FrozenEnum}
   */   
  FrozenEnum.DEFAULT = new FrozenEnum();
        
  /**
   * Return true if the enum is active.
   *
   * @returns {Boolean} true if active.
   */
  FrozenEnum.prototype.isActive = function () {
    return this.$ordinal !== 0;
  };
  
  /**
   * Return the ordinal for the frozen enum.
   *
   * @returns {Number} ordinal.
   */
  FrozenEnum.prototype.getOrdinal = function () {
    return this.$ordinal;
  };
  
  /**
   * Return the range for the frozen enum.
   *
   * @returns {baja.EnumRange} range.
   */
  FrozenEnum.prototype.getRange = function () {
    return this.getType().getRange();
  };
  
  /**
   * Return the tag for the `FrozenEnum`.
   *
   * @returns {String} tag
   */
  FrozenEnum.prototype.getTag = function () {
    return this.getType().getTag(this.$ordinal);
  };
  
  /**
   * Return the display tag for the `FrozenEnum`.
   * 
   * A display tag is a translated human friendly readable version of a tag.
   *
   * @returns {String} display tag.
   */
  FrozenEnum.prototype.getDisplayTag = function () {
    return this.getType().getDisplayTag(this.$ordinal);
  };
  
  /**
   * Return the `String` representation of a `FrozenEnum`.
   *
   * @returns {String} string
   */
  FrozenEnum.prototype.toString = function () {   
    return this.getDisplayTag();  
  };
  
  /**
   * Get a FrozenEnum.
   * 
   * This is the primary way to access an enum.
   *
   * @param {String|Number} arg the tag of ordinal of the enum to get.
   * @returns {baja.FrozenEnum} the frozen enum.
   * @throws {Error} if the tag or ordinal is invalid.
   * 
   * @example
   *   var en = baja.$("baja:Weekday").get("monday");
   */
  FrozenEnum.prototype.get = function (arg) {   
    return this.getRange().get(arg);  
  };
  
  /**
   * Equals comparison via tag or ordinal.
   * 
   * This is a convenient way to compare enums.
   *
   * @param {String|Number|baja.FrozenEnum} arg the enum, tag or ordinal used for comparison.
   * @returns {Boolean} true if equal.
   * 
   * @example
   *   var monday = baja.$("baja:Weekday").get("monday");
   *   baja.outln("Is the day Tuesday?: " + monday.is("tuesday"));
   */
  FrozenEnum.prototype.is = function (arg) {  
    var tof = typeof arg;
    
    if (tof === "string" || tof === "number") {
      return this.equals(this.getRange().get(arg)); 
    }
    
    return this.equals(arg);
  };
  
  /**
   * Return the Frozen Enum as a Dynamic Enum.
   * 
   * @see baja.DynamicEnum#make
   * 
   * @returns {baja.DynamicEnum}
   */
  FrozenEnum.prototype.asDynamic = function () {
    return DynamicEnum.make({ en: this });
  };
  
  return FrozenEnum;
});