baja/nav/NavFileSpace.js

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

/**
 * Defines `NavFileSpace` (not exposed on `baja` namespace).
 * @module baja/nav/NavFileSpace
 */
define([ "bajaScript/comm",
        "bajaScript/baja/nav/NavContainer",
        "bajaScript/baja/comm/Callback" ], 
        function (baja, NavContainer, Callback) {
  
  "use strict";
  
  var subclass = baja.subclass,
      callSuper = baja.callSuper,
      objectify = baja.objectify,
      
      navFileRoot,
      navFileMap = {};
      
  
  /**
   * The decoded NavFile Space.
   *
   * @inner
   * @public
   * @class
   * @alias module:baja/nav/NavFileSpace
   * @extends baja.NavContainer
   */
  var NavFileSpace = function NavFileSpace() {
    callSuper(NavFileSpace, this, [ {
      navName: "navfile",
      ord: "dummy:",
      icon: "module://icons/x16/object.png"
    } ]); 
  };
  
  subclass(NavFileSpace, NavContainer);
  
  function decodeNavJson(json) {
    if (json === null) {
      return null;
    }
  
    var i,
        node = baja.$("baja:NavFileNode", {
          navName: json.n,
          displayName: json.d,
          description: json.e,
          ord: json.o,
          icon: json.i
        });
    
    // Register in the map
    navFileMap[json.o] = node;
              
    if (json.k) {
      for (i = 0; i < json.k.length; ++i) {
        node.$addChildNode(decodeNavJson(json.k[i]));
      }
    }
  
    return node;
  }
  
  /**
   * If the NavFile isn't already loaded, make a network call to load 
   * the NavFile across the network.
   * 
   * An object literal is used for the method's arguments.
   *
   * @param {Object} obj the object literal for the method's arguments.
   * @param {Function} [obj.ok] (Deprecated: use Promise) called once the
   * NavFile has been loaded. The Nav Root Node will be passed to this function
   * when invoked.
   * @param {Function} [obj.fail] (Deprecated: use Promise) called if any errors
   * occur.
   * @param {baja.comm.Batch} [obj.batch] if specified, this will batch any
   * network calls.
   * @returns {Promise.<baja.NavNode>} a promise that will be resolved once the
   * root nav file node has been retrieved.
   */
  NavFileSpace.prototype.load = function (obj) {
    obj = objectify(obj, "ok");
    
    var cb = new Callback(obj.ok, obj.fail, obj.batch);
    
    // If already loaded then don't bother making a network call
    if (navFileRoot !== undefined) {
      cb.ok(navFileRoot);
    } else {
      // Add an intermediate callback to decode the NavFile
      cb.addOk(function (ok, fail, navFileJson) {        
        // Parse NavFile JSON
        navFileRoot = decodeNavJson(navFileJson);   
        
        ok(navFileRoot);
      });
    
      baja.comm.navFile(cb);
    }
    return cb.promise();
  };
  
  /**
   * Return the NavFileRoot.
   * 
   * If there's no NavFile specified for the user or the space is unloaded, this will return null.
   *
   * @returns nav file root node (or null if there's no specified NavFile).
   */
  NavFileSpace.prototype.getRootNode = function () {
    return navFileRoot || null;
  };
  
  /**
   * Look up the NavNode for the specified Nav ORD.
   *
   * @param {String|baja.Ord} ord the Nav ORD used to look up the Nav ORD.
   *
   * @returns Nav Node
   */
  NavFileSpace.prototype.lookup = function (ord) {
    if (!this.getRootNode()) {
      return null;
    }
    return navFileMap[ord.toString()] || null;
  };
  
  /**
   * Access the Nav Children.
   * 
   * @see baja.NavContainer#getNavChildren
   */
  NavFileSpace.prototype.getNavChildren = function (obj) {
    obj = objectify(obj, "ok");
    var root = this.getRootNode(),
        cb;
    if (root) {
      return root.getNavChildren(obj);
    }
    cb = new Callback(obj.ok);
    cb.ok([]);
    return cb.promise();
  };
  
  /**
   * Return the Nav Display Name.
   * 
   * @returns {String}
   */
  NavFileSpace.prototype.getNavDisplayName = function () {
    var root = this.getRootNode();
    return root ? root.getNavDisplayName() : this.$navDisplayName;
  };
  
  /**
   * Return the Nav ORD.
   *
   * @returns {baja.Ord}
   */
  NavFileSpace.prototype.getNavOrd = function () {
    var root = this.getRootNode();
    return root ? root.getNavOrd() : callSuper("getNavOrd", NavFileSpace, this);
  };
          
  return NavFileSpace;
});