File:EnvironmentPlugin.js

/**
 * @module Container
 * @namespace springroll
 */
(function()
{
	var $ = include('PBS.KIDS.$_auth', false);

	// Fallback to using the non PBSKIDS jQuery
	if (!$) $ = include('jQuery');

	// Event name to check when the handband is ready
	var HEADBAND_READY = "org_pbskids_parentsbar_HeadbandEvent_HeadbandReady";

	/**
	 * @class Container
	 */
	// Must have a higher priority than the AnalyticsPlugin
	var plugin = new springroll.ContainerPlugin(10);

	plugin.setup = function()
	{
		/**
		 * If we're running in production mode, this is automatically set
		 * by calling `open()`, otherwise for `openRemote()` or `openPath()`
		 * it should be handled manually.
		 * @property {Boolean} isProduction
		 * @default false
		 */
		this.isProduction = false;

		/**
		 * The place where to load games from
		 * @property {String} apiDomain
		 * @default 'http://springroll.pbskids.org'
		 */
		this.apiDomain = this.options.apiDomain || 'http://springroll.pbskids.org';

		/**
		 * If we're currently on a producer site
		 * @property {Boolean} hasHeadband
		 * @readOnly
		 */
		this.hasHeadband = !!document.getElementById('headband-container');

		/**
		 * If the headband is ready/loaded
		 * @property {Boolean} headbandReady
		 * @readOnly
		 */
		var parentsBar = include('org.pbskids.parentsBar', false);
		this.headbandReady = !!(parentsBar && parentsBar.ready);

		/**
		 * Open application based on a slug or bundleId in SpringRoll Connect
		 * @method open
		 * @param {string} game The game's bundleId or slug property
		 * @param {Object} [options] The open options
		 * @param {Boolean} [options.singlePlay=false] If we should play in single play mode
		 * @param {Object} [options.playOptions=null] The optional play options
		 * @param {String} [options.query=''] The application query string options (e.g., "?level=1")
		 */
		/**
		 * Open application based on a slug or bundleId in SpringRoll Connect, the game
		 * sould be set via the data-game attribute on the iframe.
		 * @method open
		 * @param {Object} [options] The open options
		 * @param {Boolean} [options.singlePlay=false] If we should play in single play mode
		 * @param {Object} [options.playOptions=null] The optional play options
		 * @param {String} [options.query=''] The application query string options (e.g., "?level=1")
		 */
		this.open = function(game, options)
		{
			// We're on a producer site but the headband isn't fully loaded
			if (this.hasHeadband && !this.headbandReady)
			{
				// Wait for the loaded ready event
				$(document).one(HEADBAND_READY, function()
					{
						if (this._destroyed) return;

						// We're fully loaded
						this.headbandReady = true;

						// Re-open the game
						this.open(game, options);
					}
					.bind(this));
				return;
			}

			if (typeof game == "object")
			{
				options = game;
				game = null;
			}

			game = game || this.main.data('game');

			if (!game)
			{
				throw "No data-game attribute or game parameter";
			}

			var api = '/api/release/' + game;
			var env = include('springroll.env', false);
			var domainOverride = this.main.data('domain');
			var domain;

			// Open a game based on the environment file
			if (this.main.data('env'))
			{
				$.getJSON(this.main.data('env'), function(env)
					{
						if (this._destroyed) return;

						domain = domainOverride || env.domain || this.apiDomain;
						// Only enable analtyics if we're on live
						this.isProduction = env.status == "prod";
						this.openRemote(domain + api + envToQuery(env, this.main), options);
					}
					.bind(this));
			}
			// Open game based on global environment setting
			else if (env)
			{
				domain = domainOverride || env.domain || this.apiDomain;
				// Only enable analtyics if we're on live
				this.isProduction = env.status == "prod";
				this.openRemote(domain + api + envToQuery(env, this.main), options);
			}
			// Open the production version of the game
			else
			{
				domain = domainOverride || this.apiDomain;
				this.isProduction = true; // enable the tracking
				this.openRemote(domain + api + envToQuery(
				{}, this.main), options);
			}
		};
	};

	// cleanup
	plugin.teardown = function()
	{
		$(document).off(HEADBAND_READY);
		delete this.isProduction;
		delete this.apiDomain;
		delete this.headbandReady;
		delete this.hasHeadband;
		delete this.open;
	};

	/**
	 * Convert an environment object into an API query string
	 * @method envToQuery
	 * @private
	 * @param {Object} env The environment settings
	 * @return {String} The query string
	 */
	var envToQuery = function(env, main)
	{
		env = env ||
		{};

		var debug = !!main.data('debug') || env.debug;
		var status = main.data('status') || env.status;
		var token = main.data('token') || env.token;

		var query = [];

		if (token) query.push("token=" + token);
		if (status) query.push("status=" + status);
		if (debug) query.push("debug=1");

		return query.length ? "?" + query.join('&') : "";
	};

}());