Source: home.js

/**
  * Construct a new Home object.
  *
  * @class
  * @param {HTMLElement} element the HTML element in which to insert the rooms
  *                      and controls for this home.
  * @param {Object} options basic options for this home. This must include
  *                 <code>name</code> and <code>control_endpoint</code>. Control
  *                 updates will be POSTed to
  *                 <code>control_endpoint/control_id</code>.
  */
function Home(element, options) {
  "use strict";
  this.options = options;
  this.rooms = { };

  var home_source = $("#home-template").html();
  var home_template = Handlebars.compile(home_source);
  this.root = $(element).append(home_template(options));
  
  var room_source = $("#room-template").html();
  this.room_template = Handlebars.compile(room_source);
}

Home.controls = { };
/**
  * Register a new control type.
  *
  * @param {String} type controls of this type will be created using the
  *                      registered control function.
  * @param {Class} control the object that will be instantiated for every
  *                        control of this type. This must have a constructor
  *                        (which is given a {@link Home} instance and options
  *                        parameters) and a <code>render</code> method.
  */
Home.register_control = function(type, control) {
  "use strict";
  Home.controls[type] = control;
};

/**
  * Add a room to this home.
  * 
  * @this {Home}
  * @param {String} id the id of the new room.
  * @param {Object} room the room to add. This must include a <code>name</code>
  *                      and can include a map of <code>controls</code>. Example:
  * <pre><code>
  * {
  *   "name": "Bedroom",
  *   "controls": {
  *     "bedroom/lights": {"type": "on-off", "name": "Lights", "on": true}
  *   }
  * }
  * </pre></code>
  * @see Home#add_control
  */
Home.prototype.add_room = function(id, room) {
  "use strict";
  this.rooms[id] = room;

  room.html = $(this.room_template(room));
  if (room.controls) {
    var control_ids = Object.keys(room.controls);
    for (var i = 0; i < control_ids.length; i ++) {
      this.add_control(id, control_ids[i], room.controls[control_ids[i]]);
    }
  }
  this.root.append(room.html);
};

/**
  * Add a control to a room.
  *
  * @param {String} room_id the id of the room in which to add the control. The
  *                         room has to have been added via {@link #add_room}.
  * @param {String} control_id the id of the control being added.
  * @param {Object} control the control to add. Requires a <code>type</code>
  *                         that has been registered earlier with
  *                         {@link Home.register_control} and any other
  *                         control-specific options. Example:
  * <pre><code>
  * {"type": "on-off", "name": "Lights", "on": true}
  * </pre></code>
  */
Home.prototype.add_control = function(room_id, control_id, control) {
  "use strict";
  var room = this.rooms[room_id];
  if (!room.controls) {
    room.controls = { };
  }
  room.controls[control_id] = control;
  var controls_container = room.html.find(".controls");
  if (Home.controls[control.type]) {
    control.instance = new Home.controls[control.type](this, control_id, control);
    controls_container.append(control.instance.render());
  }
};