/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * @fileoverview Browser environment for interacting with people.
 */


/**
 * @static
 * @class
 * Namespace for top-level people functions.
 *
 * @name opensocial
 */

/**
 * Namespace for top level people functions.
 *
 * @private
 * @constructor (note: a constructor for JsDoc purposes)
 */
var opensocial = function() {};


/**
 * Requests the container to send a specific message to the specified users. If
 * the container does not support this method the callback will be called with a
 * opensocial.ResponseItem. The response item will have its error code set to
 * NOT_IMPLEMENTED.
 *
 * @param {Array.&lt;String&gt; | String} recipients An ID, array of IDs, or a
 *     group reference; the supported keys are VIEWER, OWNER, VIEWER_FRIENDS,
 *    OWNER_FRIENDS, or a single ID within one of those groups
 * @param {opensocial.Message} message The message to send to the specified
 *     users.
 * @param {Function} opt_callback The function to call once the request has been
 *    processed; either this callback will be called or the gadget will be
 *    reloaded from scratch. This function will be passed one parameter, an
 *    opensocial.ResponseItem. The error code will be set to reflect whether
 *    there were any problems with the request. If there was no error, the
 *    message was sent. If there was an error, you can use the response item's
 *    getErrorCode method to determine how to proceed. The data on the response
 *    item will not be set.
 *
 * @member opensocial
 */
opensocial.requestSendMessage = function(recipients, message, opt_callback) {
  opensocial.Container.get().requestSendMessage(recipients, message,
      opt_callback);
};


/**
 * Requests the container to share this gadget with the specified users. If the
 * container does not support this method the callback will be called with a
 * opensocial.ResponseItem. The response item will have its error code set to
 * NOT_IMPLEMENTED.
 *
 * @param {Array.&lt;String&gt; | String} recipients An ID, array of IDs, or a
 *     group reference; the supported keys are VIEWER, OWNER, VIEWER_FRIENDS,
 *    OWNER_FRIENDS, or a single ID within one of those groups
 * @param {opensocial.Message} reason The reason the user wants the gadget to
 *     share itself. This reason can be used by the container when prompting the
 *     user for permission to share the app. It may also be ignored.
 * @param {Function} opt_callback The function to call once the request has been
 *    processed; either this callback will be called or the gadget will be
 *    reloaded from scratch. This function will be passed one parameter, an
 *    opensocial.ResponseItem. The error code will be set to reflect whether
 *    there were any problems with the request. If there was no error, the
 *    sharing request was sent. If there was an error, you can use the response
 *    item's getErrorCode method to determine how to proceed. The data on the
 *    response item will not be set.
 *
 * @member opensocial
 */
opensocial.requestShareApp = function(recipients, reason, opt_callback) {
   opensocial.Container.get().requestShareApp(recipients, reason, opt_callback);
};


/**
 * Takes an activity and tries to create it,
 * without waiting for the operation to complete.
 * Optionally calls a function when the operation completes.
 * <p>
 * <b>See also:</b>
 * <a href="#newActivity">newActivity()</a>
 * </p>
 *
 * <p class="note">
 * <b>Note:</b>
 * If this is the first activity that has been created for the user and
 * the request is marked as HIGH priority then this call may open a user flow
 * and navigate away from your gadget.
 *
 * If the container does not support this method the callback will be called
 * with a opensocial.ResponseItem. The response item will have its error code
 * set to NOT_IMPLEMENTED.
 *
 * @param {opensocial.Activity} activity The <a href="opensocial.Activity.html">
 *    activity</a> to create
 * @param {opensocial.CreateActivityPriority} priority The
 *    <a href="opensocial.CreateActivityPriority.html">priority</a> for this
 *    request
 * @param {Function} opt_callback The function to call once the request has been
 *    processed. This callback will either be called or the gadget will be
 *    reloaded from scratch. This function will be passed one parameter, an
 *    opensocial.ResponseItem. The error code will be set to reflect whether
 *    there were any problems with the request. If there was no error, the
 *    activity was created. If there was an error, you can use the response
 *    item's getErrorCode method to determine how to proceed. The data on the
 *    response item will not be set.
 *
 * @member opensocial
 */
opensocial.requestCreateActivity = function(activity, priority, opt_callback) {
 opensocial.Container.get().requestCreateActivity(activity, priority,
     opt_callback);
};


/**
 * @static
 * @class
 * The priorities a create activity request can have.
 * <p><b>See also:</b>
 * <a href="opensocial.html#requestCreateActivity">
 * opensocial.requestCreateActivity()</a>
 * </p>
 *
 * @name opensocial.CreateActivityPriority
 */
opensocial.CreateActivityPriority = {
  /**
   * If the activity is of high importance, it will be created even if this
   * requires asking the user for permission. This may cause the container to
   * open a user flow which may navigate away from your gagdet.
   *
   * @member opensocial.CreateActivityPriority
   */
  HIGH : 'HIGH',

  /**
   * If the activity is of low importance, it will not be created if the
   * user has not given permission for the current app to create activities.
   * With this priority, the requestCreateActivity call will never open a user
   * flow.
   *
   * @member opensocial.CreateActivityPriority
   */
  LOW : 'LOW'
};


/**
 * Returns true if the current gadget has access to the specified
 * permission. If the gadget calls opensocial.requestPermission and permissions
 * are granted then this function must return true on all subsequent calls.
 *
 * @param {opensocial.Permission} permission
 *    The <a href="opensocial.Permission.html">permission</a>
 * @return {Boolean}
 *    True if the gadget has access for the permission; false if it doesn't
 *
 * @member opensocial
 */
opensocial.hasPermission = function(permission) {
  return opensocial.Container.get().hasPermission(permission);
};


/**
 * Requests the user to grant access to the specified permissions. If the
 * container does not support this method the callback will be called with a
 * opensocial.ResponseItem. The response item will have its error code set to
 * NOT_IMPLEMENTED.
 *
 * @param {Array.&lt;opensocial.Permission&gt;} permissions
 *    The <a href="opensocial.Permission.html">permissions</a> to request
 *    from the viewer
 * @param {String} reason Displayed to the user as the reason why these
 *    permissions are needed
 * @param {Function} opt_callback The function to call once the request has been
 *    processed; either this callback will be called or the gadget will be
 *    reloaded from scratch. This function will be passed one parameter, an
 *    opensocial.ResponseItem. The error code will be set to reflect whether
 *    there were any problems with the request. If there was no error, all
 *    permissions were granted. If there was an error, you can use
 *    opensocial.hasPermission to check which permissions are still denied. The
 *    data on the response item will be set. It will be an array of the
 *    opensocial.Permissions that were granted.
 *
 * @member opensocial
 */
opensocial.requestPermission = function(permissions, reason, opt_callback) {
  opensocial.Container.get().requestPermission(permissions, reason,
      opt_callback);
};


/**
 * @static
 * @class
 *
 * The permissions an app can ask for.
 *
 * <p>
 * <b>See also:</b>
 * <a href="opensocial.html#hasPermission">
 * <code>opensocial.hasPermission()</code></a>,
 * <a href="opensocial.html#requestPermission">
 * <code>opensocial.requestPermission()</code></a>
 *
 * @name opensocial.Permission
 */
opensocial.Permission = {
  /**
   * Access to the viewer person object
   *
   * @member opensocial.Permission
   */
  VIEWER : 'viewer'
};


/**
 * Gets the current environment for this gadget. You can use the environment to
 * make queries such as what profile fields and surfaces are supported by this
 * container, what parameters were passed to the current gadget, and so on.
 *
 * @return {opensocial.Environment}
 *    The current <a href="opensocial.Environment.html">environment</a>
 *
 * @member opensocial
 */
opensocial.getEnvironment = function() {
  return opensocial.Container.get().getEnvironment();
};


/**
 * Creates a data request object to use for sending and fetching data from the
 * server.
 *
 * @return {opensocial.DataRequest} The
 *    <a href="opensocial.DataRequest.html">request</a> object
 * @member opensocial
 */
opensocial.newDataRequest = function() {
  return opensocial.Container.get().newDataRequest();
};


/**
 * Creates an activity object,
 * which represents an activity on the server.
 * <p>
 * <b>See also:</b>
 * <a href="#requestCreateActivity">requestCreateActivity()</a>,
 * </p>
 *
 * <p>It is only required to set one of TITLE_ID or TITLE. In addition, if you
 * are using any variables in your title or title template,
 * you must set TEMPLATE_PARAMS.</p>
 *
 * <p>Other possible fields to set are: URL, MEDIA_ITEMS, BODY_ID, BODY,
 * EXTERNAL_ID, PRIORITY, STREAM_TITLE, STREAM_URL, STREAM_SOURCE_URL,
 * and STREAM_FAVICON_URL.</p>
 *
 * <p>Containers are only required to use TITLE_ID or TITLE, and may choose to
 * ignore additional parameters.</p>
 *
 * <p>See <a href="opensocial.Activity.Field.html">Field</a>s are supported for
 * more details.</p>
 *
 * @param {Map.&lt;opensocial.Activity.Field, Object&gt;} params
 *    Parameters defining the activity.
 * @return {opensocial.Activity} The new
 *    <a href="opensocial.Activity.html">activity</a> object
 * @member opensocial
 */
opensocial.newActivity = function(params) {
  return opensocial.Container.get().newActivity(params);
};


/**
 * Creates a media item associated with an activity.
 * Represents images, movies, and audio.
 * Used when creating activities on the server.
 *
 * @param {String} mimeType
 *    <a href="opensocial.Activity.MediaItem.Type.html">MIME type</a> of the
 *    media
 * @param {String} url Where the media can be found
 * @param {Map.&lt;opensocial.Activity.MediaItem.Field, Object&gt;} opt_params
 *    Any other fields that should be set on the media item object;
 *    all of the defined
 *    <a href="opensocial.Activity.MediaItem.Field.html">Field</a>s
 *    are supported
 *
 * @return {opensocial.Activity.MediaItem} The new
 *    <a href="opensocial.Activity.MediaItem.html">media item</a> object
 * @member opensocial
 */
opensocial.newActivityMediaItem = function(mimeType, url, opt_params) {
  return opensocial.Container.get().newActivityMediaItem(mimeType,
      url, opt_params);
};


/**
 * Creates a media item associated with an activity.
 * Represents images, movies, and audio.
 * Used when creating activities on the server.
 *
 * @param {String} body The main text of the message.
 * @param {Map.&lt;opensocial.Message.Field, Object&gt;} opt_params
 *    Any other fields that should be set on the message object;
 *    all of the defined
 *    <a href="opensocial.Message.Field.html">Field</a>s
 *    are supported
 *
 * @return {opensocial.Message} The new
 *    <a href="opensocial.Message.html">message</a> object
 * @member opensocial
 */
opensocial.newMessage = function(body, opt_params) {
  return opensocial.Container.get().newMessage(body, opt_params);
};


// TODO(doll): Util function - pull up the gadgets inherits in shindig so that
// opensocial and gadgets use the same one
/** @private */
Function.prototype.inherits = function(parentCtor) {
  function tempCtor() {};
  tempCtor.prototype = parentCtor.prototype;
  this.superClass_ = parentCtor.prototype;
  this.prototype = new tempCtor();
  this.prototype.constructor = this;
};

/************** end opensocial.js ********************/

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * @fileoverview Interface for containers of people functionality.
 */


/**
 * Base interface for all containers.
 *
 * @constructor
 * @private
 */
opensocial.Container = function() {};


/**
 * The container instance.
 *
 * @type Container
 * @private
 */
opensocial.Container.container_ = null;


/**
 * Set the current container object.
 *
 * @param {opensocial.Container} container The container
 * @private
 */
opensocial.Container.setContainer = function(container) {
  opensocial.Container.container_ = container;
};


/**
 * Get the current container object.
 *
 * @return {opensocial.Container} container The current container
 * @private
 */
opensocial.Container.get = function() {
  return opensocial.Container.container_;
};


/**
 * Gets the current environment for this gadget. You can use the environment to
 * query things like what profile fields and surfaces are supported by this
 * container, what parameters were passed to the current gadget and so forth.
 *
 * @return {opensocial.Environment} The current environment
 *
 * @private
 */
opensocial.Container.prototype.getEnvironment = function() {};

/**
 * Requests the container to send a specific message to the specified users. If
 * the container does not support this method the callback will be called with a
 * opensocial.ResponseItem. The response item will have its error code set to
 * NOT_IMPLEMENTED.
 *
 * @param {Array.&lt;String&gt; | String} recipients An ID, array of IDs, or a
 *     group reference; the supported keys are VIEWER, OWNER, VIEWER_FRIENDS,
 *    OWNER_FRIENDS, or a single ID within one of those groups
 * @param {opensocial.Message} message The message to send to the specified
 *     users.
 * @param {Function} opt_callback The function to call once the request has been
 *    processed; either this callback will be called or the gadget will be
 *    reloaded from scratch. This function will be passed one parameter, an
 *    opensocial.ResponseItem. The error code will be set to reflect whether
 *    there were any problems with the request. If there was no error, the
 *    message was sent. If there was an error, you can use the response item's
 *    getErrorCode method to determine how to proceed. The data on the response
 *    item will not be set.
 *
 * @member opensocial
 * @private
 */
opensocial.Container.prototype.requestSendMessage = function(recipients,
    message, opt_callback) {
  if (opt_callback) {
    opt_callback(new opensocial.ResponseItem(
        null, null, opensocial.ResponseItem.Error.NOT_IMPLEMENTED, null));
  }
};


/**
 * Requests the container to share this gadget with the specified users. If the
 * container does not support this method the callback will be called with a
 * opensocial.ResponseItem. The response item will have its error code set to
 * NOT_IMPLEMENTED.
 *
 * @param {Array.&lt;String&gt; | String} recipients An ID, array of IDs, or a
 *     group reference; the supported keys are VIEWER, OWNER, VIEWER_FRIENDS,
 *    OWNER_FRIENDS, or a single ID within one of those groups
 * @param {opensocial.Message} reason The reason the user wants the gadget to
 *     share itself. This reason can be used by the container when prompting the
 *     user for permission to share the app. It may also be ignored.
 * @param {Function} opt_callback The function to call once the request has been
 *    processed; either this callback will be called or the gadget will be
 *    reloaded from scratch. This function will be passed one parameter, an
 *    opensocial.ResponseItem. The error code will be set to reflect whether
 *    there were any problems with the request. If there was no error, the
 *    sharing request was sent. If there was an error, you can use the response
 *    item's getErrorCode method to determine how to proceed. The data on the
 *    response item will not be set.
 *
 * @member opensocial
 * @private
 */
opensocial.Container.prototype.requestShareApp = function(recipients, reason,
    opt_callback) {
  if (opt_callback) {
    opt_callback(new opensocial.ResponseItem(
        null, null, opensocial.ResponseItem.Error.NOT_IMPLEMENTED, null));
  }
};


/**
 * Request for the container to make the specified person not a friend.
 *
 * Note: If this is the first activity that has been created for the user and
 * the request is marked as HIGH priority then this call may open a user flow
 * and navigate away from your gadget.
 *
 * @param {Activity} activity The activity to create. The only required field is
 *     title.
 * @param {CreateActivityPriority} priority The priority for this request.
 * @param {Function} opt_callback Function to call once the request has been
 *    processed.
 * @private
 */
opensocial.Container.prototype.requestCreateActivity = function(activity,
    priority, opt_callback) {
  if (opt_callback) {
    opt_callback(new opensocial.ResponseItem(
        null, null, opensocial.ResponseItem.Error.NOT_IMPLEMENTED, null));
  }
};


/**
 * Returns whether the current gadget has access to the specified
 * permission.
 *
 * @param {opensocial.Permission | String} permission The permission
 * @return {Boolean} Whether the gadget has access for the permission.
 *
 * @private
 */
opensocial.Container.prototype.hasPermission = function(permission) {
  return false;
};


/**
 * Requests the user grants access to the specified permissions.
 *
 * @param {Array.<opensocial.Permission>} permissions The permissions to request
 *    access to from the viewer
 * @param {String} reason Will be displayed to the user as the reason why these
 *    permissions are needed.
 * @param {Function} opt_callback The function to call once the request has been
 *    processed. This callback will either be called or the gadget will be
 *    reloaded from scratch
 *
 * @private
 */
opensocial.Container.prototype.requestPermission = function(permissions, reason,
    opt_callback) {
  if (opt_callback) {
    opt_callback(new opensocial.ResponseItem(
        null, null, opensocial.ResponseItem.Error.NOT_IMPLEMENTED, null));
  }
};


/**
 * Calls the callback function with a dataResponse object containing the data
 * asked for in the dataRequest object.
 *
 * @param {opensocial.DataRequest} dataRequest Specifies which data to get from
 *    the server
 * @param {Function} callback Function to call after the data is fetched
 * @private
 */
opensocial.Container.prototype.requestData = function(dataRequest, callback) {};


/**
 * Request a profile for the specified person id.
 * When processed, returns a Person object.
 *
 * @param {String} id The id of the person to fetch. Can also be standard
 *    person IDs of VIEWER and OWNER.
 * @param {Map.<opensocial.DataRequest.PeopleRequestFields, Object>} opt_params
 *    Additional params to pass to the request. This request supports
 *    PROFILE_DETAILS.
 * @return {Object} a request object
 * @private
 */
opensocial.Container.prototype.newFetchPersonRequest = function(id,
    opt_params) {};


/**
 * Used to request friends from the server.
 * When processed, returns a Collection&lt;Person&gt; object.
 *
 * @param {Array.<String> | String} idSpec An id, array of ids, or a group
 *    reference used to specify which people to fetch
 * @param {Map.<opensocial.DataRequest.PeopleRequestFields, Object>} opt_params
 *    Additional params to pass to the request. This request supports
 *    PROFILE_DETAILS, SORT_ORDER, FILTER, FIRST, and MAX.
 * @return {Object} a request object
 * @private
 */
opensocial.Container.prototype.newFetchPeopleRequest = function(idSpec,
    opt_params) {};


/**
 * Used to request app data for the given people.
 * When processed, returns a Map&lt;person id, Map&lt;String, String&gt;&gt;
 * object.
 *
 * @param {Array.<String> | String} idSpec An ID, array of IDs, or a group
 *    reference; the supported keys are VIEWER, OWNER, VIEWER_FRIENDS,
 *    OWNER_FRIENDS, or a single ID within one of those groups
 * @param {Array.<String> | String} keys The keys you want data for. This
 *     can be an array of key names, a single key name, or "*" to mean
 *     "all keys".
 * @return {Object} a request object
 * @private
 */
opensocial.Container.prototype.newFetchPersonAppDataRequest = function(idSpec,
    keys) {};


/**
 * Used to request an update of an app field for the given person.
 * When processed, does not return any data.
 *
 * @param {String} id The id of the person to update. (Right now only the
 *    special VIEWER id is allowed.)
 * @param {String} key The name of the key
 * @param {String} value The value
 * @return {Object} a request object
 * @private
 */
opensocial.Container.prototype.newUpdatePersonAppDataRequest = function(id,
    key, value) {};


/**
 * Used to request an activity stream from the server.
 *
 * When processed, returns an object whose "activities" property is a
 * Collection&lt;Activity&gt; object.
 *
 * @param {Array.<String> | String} idSpec An ID, array of IDs, or a group
 *    reference used to specify which people's activities to fetch; the
 *    supported keys are VIEWER, OWNER, VIEWER_FRIENDS, OWNER_FRIENDS, or
 *    a single ID within one of those groups.
 * @param {Map.<opensocial.DataRequest.ActivityRequestFields, Object>} opt_params
 *    Additional params to pass to the request.
 * @return {Object} a request object
 * @private
 */
opensocial.Container.prototype.newFetchActivitiesRequest = function(idSpec,
    opt_params) {};


/**
 * Creates a new collection with caja support if enabled.
 * @return {opensocial.Collection} the collection object
 * @private
 */
opensocial.Container.prototype.newCollection = function(array, opt_offset,
    opt_totalSize) {
  return new opensocial.Collection(array, opt_offset, opt_totalSize);
};


/**
 * Creates a new person with caja support if enabled.
 * @return {opensocial.Person} the person object
 * @private
 */
opensocial.Container.prototype.newPerson = function(opt_params, opt_isOwner,
    opt_isViewer) {
  return new opensocial.Person(opt_params, opt_isOwner, opt_isViewer);
};


/**
 * Get an activity object used to create activities on the server
 *
 * @param {opensocial.Activity.Template || String} title The title of an
 *     activity, a template is reccommended, but this field can also be a
 *     string.
 * @param {Map.<opensocial.Activity.Field, Object>} opt_params Any other
 *    fields that should be set on the activity object. All of the defined
 *    Fields are supported.
 * @return {opensocial.Activity} the activity object
 * @private
 */
opensocial.Container.prototype.newActivity = function(opt_params) {
  return new opensocial.Activity(opt_params);
};


/**
 * A media item associated with an activity. Represents images, movies, and
 * audio. Used when creating activities on the server
 *
 * @param {String} mimeType of the media
 * @param {String} url where the media can be found
 * @param {Map.<opensocial.Activity.MediaItem.Field, Object>} opt_params
 *    Any other fields that should be set on the media item object.
 *    All of the defined Fields are supported.
 *
 * @return {opensocial.Activity.MediaItem} the media item object
 * @private
 */
opensocial.Container.prototype.newActivityMediaItem = function(mimeType, url,
    opt_params) {
  return new opensocial.Activity.MediaItem(mimeType, url, opt_params);
};


/**
 * Creates a media item associated with an activity.
 * Represents images, movies, and audio.
 * Used when creating activities on the server.
 *
 * @param {String} body The main text of the message.
 * @param {Map.&lt;opensocial.Message.Field, Object&gt;} opt_params
 *    Any other fields that should be set on the message object;
 *    all of the defined
 *    <a href="opensocial.Message.Field.html">Field</a>s
 *    are supported
 *
 * @return {opensocial.Message} The new
 *    <a href="opensocial.Message.html">message</a> object
 * @member opensocial
 */
opensocial.Container.prototype.newMessage = function(body, opt_params) {
  return new opensocial.Message(body, opt_params);
};


/**
 * Creates a new response item with caja support if enabled.
 * @return {opensocial.ResponseItem} the response item object
 * @private
 */
opensocial.Container.prototype.newResponseItem = function(originalDataRequest,
    data, opt_errorCode, opt_errorMessage) {
  return new opensocial.ResponseItem(originalDataRequest, data, opt_errorCode,
      opt_errorMessage);
};


/**
 * Creates a new data response with caja support if enabled.
 * @return {opensocial.DataResponse} the data response object
 * @private
 */
opensocial.Container.prototype.newDataResponse = function(responseItems,
    opt_globalError) {
  return new opensocial.DataResponse(responseItems, opt_globalError);
};


/**
 * Get a data request object to use for sending and fetching data from the
 * server.
 *
 * @return {opensocial.DataRequest} the request object
 * @private
 */
opensocial.Container.prototype.newDataRequest = function() {
  return new opensocial.DataRequest();
};


/**
 * Get a new environment object.
 *
 * @return {opensocial.Environment} the environment object
 * @private
 */
opensocial.Container.prototype.newEnvironment = function(domain,
    supportedFields) {
  return new opensocial.Environment(domain, supportedFields);
};


/**
 * Returns true if the specified value is an array
 * @param {Object} val Variable to test
 * @return {boolean} Whether variable is an array
 * @private
 */
opensocial.Container.isArray = function(val) {
  return val instanceof Array;
};


/**
 * Caja Support
 */
var caja;
var ___;
var html_sanitize;

/**
 * Enable Caja support
 *
 * @type Container
 * @private
 */

// TODO(doll): As caja evolves this method should get a lot smaller
opensocial.Container.prototype.enableCaja = function() {

  ___ = window["___"];
  caja = window["caja"];
  html_sanitize = window["html_sanitize"];

  var outers = caja.copy(___.sharedOuters);

  // TODO(doll): We need to add caja allows for the gadgets namespace so that
  // this works properly. It does not belong in gadgets.
  var igOnload = window["_IG_RegisterOnloadHandler"];
  if (igOnload) {
    outers._IG_RegisterOnloadHandler = ___.simpleFunc(igOnload);
  }

  outers.emitHtml___ = function emitHtml(var_args) {
    var html = Array.prototype.slice.call(arguments, 0).join('');
    document.write(html);
  };

  outers.document = function() {};
  outers.document.getElementById = function(id) {
    var element = document.getElementById("DOM-PREFIX-" + id);
    if (element !== null) {
      ___.useSetHandler(element, 'innerHTML', function(html) {
        var temp = html_sanitize(html, null,
            function (nmtokens) {
              var tokens = nmtokens.split(/\s+/g);
              for (var i = 0; i < tokens.length; ++i) {
                if (tokens[i]) { tokens[i] = 'DOM-PREFIX-' + tokens[i]; }
              }
              return tokens.join(' ');
            });
        return this.innerHTML = temp;
      });
    }
    return element;
  };

  ___.allowCall(outers.document, 'getElementById');

  // Temporarily adding some gadgets calls to the opensocial code.
  // This should move into the gadgets js code very soon.
  outers.gadgets = gadgets;

  // Adding all of the available opensocial calls as defined in the spec
  outers.opensocial = opensocial;
  ___.allowCall(outers.opensocial, 'requestSendMessage');
  ___.allowCall(outers.opensocial, 'requestShareApp');
  ___.allowCall(outers.opensocial, 'requestCreateActivity');
  ___.allowCall(outers.opensocial, 'hasPermission');
  ___.allowCall(outers.opensocial, 'requestPermission');
  ___.allowCall(outers.opensocial, 'getEnvironment');
  ___.allowCall(outers.opensocial, 'newDataRequest');
  ___.allowCall(outers.opensocial, 'newActivity');
  ___.allowCall(outers.opensocial, 'newActivityMediaItem');
  ___.allowCall(outers.opensocial, 'newMessage');

  ___.allowCall(opensocial.Collection.prototype, 'getById');
  ___.allowCall(opensocial.Collection.prototype, 'size');
  ___.allowCall(opensocial.Collection.prototype, 'each');
  ___.allowCall(opensocial.Collection.prototype, 'asArray');
  ___.allowCall(opensocial.Collection.prototype, 'getTotalSize');
  ___.allowCall(opensocial.Collection.prototype, 'getOffset');

  // TODO(doll): Call caja method to support all array calls once it exists
  ___.allowCall(Array.prototype, 'push');
  ___.allowCall(Array.prototype, 'sort');

  ___.allowCall(opensocial.Person.prototype, 'getId');
  ___.allowCall(opensocial.Person.prototype, 'getDisplayName');
  ___.allowCall(opensocial.Person.prototype, 'getField');
  ___.allowCall(opensocial.Person.prototype, 'isViewer');
  ___.allowCall(opensocial.Person.prototype, 'isOwner');

  ___.allowCall(opensocial.Address.prototype, 'getField');
  ___.allowCall(opensocial.BodyType.prototype, 'getField');
  ___.allowCall(opensocial.Email.prototype, 'getField');
  ___.allowCall(opensocial.Name.prototype, 'getField');
  ___.allowCall(opensocial.Organization.prototype, 'getField');
  ___.allowCall(opensocial.Phone.prototype, 'getField');
  ___.allowCall(opensocial.Url.prototype, 'getField');

  ___.allowCall(opensocial.Activity.prototype, 'getId');
  ___.allowCall(opensocial.Activity.prototype, 'getField');

  ___.allowCall(opensocial.Activity.MediaItem.prototype, 'getField');

  ___.allowCall(opensocial.ResponseItem.prototype, 'hadError');
  ___.allowCall(opensocial.ResponseItem.prototype, 'getError');
  ___.allowCall(opensocial.ResponseItem.prototype, 'getOriginalDataRequest');
  ___.allowCall(opensocial.ResponseItem.prototype, 'getData');

  ___.allowCall(opensocial.DataResponse.prototype, 'hadError');
  ___.allowCall(opensocial.DataResponse.prototype, 'get');

  ___.allowCall(opensocial.DataRequest.prototype, 'getRequestObjects');
  ___.allowCall(opensocial.DataRequest.prototype, 'add');
  ___.allowCall(opensocial.DataRequest.prototype, 'send');
  ___.allowCall(opensocial.DataRequest.prototype, 'newFetchPersonRequest');
  ___.allowCall(opensocial.DataRequest.prototype, 'newFetchPeopleRequest');
  ___.allowCall(opensocial.DataRequest.prototype, 'newFetchPersonAppDataRequest');
  ___.allowCall(opensocial.DataRequest.prototype, 'newUpdatePersonAppDataRequest');
  ___.allowCall(opensocial.DataRequest.prototype, 'newFetchActivitiesRequest');

  ___.allowCall(opensocial.Environment.prototype, 'getDomain');
  ___.allowCall(opensocial.Environment.prototype, 'supportsField');

  ___.allowCall(opensocial.Enum.prototype, 'getKey');
  ___.allowCall(opensocial.Enum.prototype, 'getDisplayValue');

  ___.allowCall(opensocial.Message.prototype, 'getField');
  ___.allowCall(opensocial.Message.prototype, 'setField');

  var moduleHandler = ___.freeze({
    getOuters: ___.simpleFunc(function() { return outers; }),
    handle: ___.simpleFunc(function(newModule) { newModule(outers); })
  });

  ___.setNewModuleHandler(moduleHandler);
};

/**
 * Default taming is to return obj itself. Depending on
 * other taming decisions, it may be more appropriate to
 * return an interposed wrapper.
 * @private
 */
function plugin_tamed(obj) { return obj; }

function plugin_dispatchEvent___(thisNode, event, pluginId, handlerName) {
  return ___.getOuters(pluginId)[handlerName](plugin_tamed(thisNode),
      plugin_tamed(event));
}



/************** end container.js ********************/

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * @class
 * Representation of an activity.
 *
 * <p>Activities are rendered with a title and an optional activity body.</p>
 *
 * <p>You may set the title and body directly as strings when calling
 * opensocial.createActivity.</p>
 *
 * <p>However, it is usually beneficial to create activities using
 * Activity Templates for the title and body. Activity Templates support:</p>
 * <ul>
 *   <li>Internationalization</li>
 *   <li>Replacement variables in the message</li>
 *   <li>Activity Summaries, which are message variations used to summarize
 *     repeated activities that share something in common.</li>
 * </ul>
 *
 * <p>Activity Templates are defined as messages in the gadget specification.
 * To define messages, you create and reference message bundle XML files for
 * each locale you support.</p>
 *
 * <p>Example module spec in gadget XML:
 * <pre>
 * &lt;ModulePrefs title="ListenToThis"&gt;
 *   &lt;Locale messages="http://www.listentostuff.com/messages.xml"/&gt;
 *   &lt;Locale lang="de" messages="http://www.listentostuff.com/messages-DE.xml"/&gt;
 * &lt;/ModulePrefs&gt;
 * </pre>
 * </p>
 *
 * <p>Example message bundle:
 * <pre>
 * &lt;messagebundle&gt;
 *  &lt;msg name="LISTEN_TO_THIS_SONG"&gt;
 *     ${Subject.DisplayName} told ${Owner.DisplayName} to
 *     listen to a song!
 *  &lt;/msg&gt;
 * &lt;/messagebundle&gt;
 * </pre>
 * </p>
 *
 * <p>You can set custom key/value string pairs when posting an activity.
 * These values will be used for variable substitution in the templates.</p>
 * <p>Example JS call:
 * <pre>
 *   var owner = ...;
 *   var viewer = ...;
 *   var activity = opensocial.newActivity('LISTEN_TO_THIS_SONG',
 *    {Song: 'Do That There - (Young Einstein hoo-hoo mix)',
 *     Artist: 'Lyrics Born', Subject: viewer, Owner: owner})
 * </pre>
 * </p>
 *
 * <p> Associated message:
 * <pre>
 * &lt;msg name="LISTEN_TO_THIS_SONG"&gt;
 *     ${Subject.DisplayName} told ${Owner.DisplayName} to listen
 *     to ${Song} by ${Artist}
 * &lt;/msg&gt;
 * </pre>
 * </p>
 *
 * <p>People can also be set as values in key/value pairs when posting
 * an activity. You can then reference the following fields on a person:</p>
 * <ul>
 *  <li>${Person.DisplayName} The person's name</li>
 *  <li>${Person.Id} The user ID of the person</li>
 *  <li>${Person.ProfileUrl} The profile URL of the person</li>
 *  <li>${Person} This will show the display name, but containers may optionally
 *     provide special formatting, such as showing the name as a link</li>
 * </ul>
 *
 * <p>Users will have many activities in their activity streams, and containers
 * will not show every activity that is visible to a user. To help display
 * large numbers of activities, containers will summarize a list of activities
 * from a given source to a single entry.</p>
 *
 * <p>You can provide Activity Summaries to customize the text shown when
 * multiple activities are summarized. If no customization is provided, a
 * container may ignore your activities altogether or provide default text
 * such as "Bob changed his status message + 20 other events like this."</p>
 * <ul>
 *  <li>Activity Summaries will always summarize around a specific key in a
 *   key/value pair. This is so that the summary can say something concrete
 *   (this is clearer in the example below).</li>
 *  <li>Other variables will have synthetic "Count" variables created with
 *   the total number of items summarized.</li>
 *  <li>Message ID of the summary is the message ID of the main template + ":" +
 *   the data key</li>
 * </ul>
 *
 * <p>Example summaries:
 * <pre>
 * &lt;messagebundle&gt;
 *   &lt;msg name="LISTEN_TO_THIS_SONG:Artist"&gt;
 *     ${Subject.Count} of your friends have suggested listening to songs
 *     by ${Artist}!
 *   &lt;/msg&gt;
 *   &lt;msg name="LISTEN_TO_THIS_SONG:Song"&gt;
 *     ${Subject.Count} of your friends have suggested listening to ${Song}
 *   !&lt;/msg&gt;
 *   &lt;msg name="LISTEN_TO_THIS_SONG:Subject"&gt;
 *    ${Subject.DisplayName} has recommended ${Song.Count} songs to you.
 *   &lt;/msg&gt;
 * &lt;/messagebundle&gt;
 * </pre></p>
 *
 * <p>Activity Templates may only have the following HTML tags: &lt;b&gt;,
 * &lt;i&gt;, &lt;a&gt;, &lt;span&gt;. The container also has the option
 * to strip out these tags when rendering the activity.</p>
 *
 * <p>
 * <b>See also:</b>
 * <a href="opensocial.html#newActivity">opensocial.newActivity()</a>,
 * <a href="opensocial.html#requestCreateActivity">
 * opensocial.requestCreateActivity()</a>
 *
 * @name opensocial.Activity
 */


/**
 * Base interface for all activity objects.
 *
 * Private, see opensocial.createActivity() for usage.
 *
 * @param {Map.&lt;opensocial.Activity.Field, Object&gt;} params
 *    Parameters defining the activity.
 * @private
 * @constructor
 */
opensocial.Activity = function(params) {
  this.fields_ = params;
};


/**
 * @static
 * @class
 * All of the fields that activities can have.
 *
 * <p>It is only required to set one of TITLE_ID or TITLE. In addition, if you
 * are using any variables in your title or title template,
 * you must set TEMPLATE_PARAMS.</p>
 *
 * <p>Other possible fields to set are: URL, MEDIA_ITEMS, BODY_ID, BODY,
 * EXTERNAL_ID, PRIORITY, STREAM_TITLE, STREAM_URL, STREAM_SOURCE_URL,
 * and STREAM_FAVICON_URL.</p>
 *
 * <p>Containers are only required to use TITLE_ID or TITLE, they may ignore
 * additional parameters.</p>
 *
 * <p>
 * <b>See also:</b>
 * <a
 * href="opensocial.Activity.html#getField">opensocial.Activity.getField()</a>
 * </p>
 *
 * @name opensocial.Activity.Field
 */
opensocial.Activity.Field = {
  /**
   * <p>A string specifying the title template message ID in the gadget
   *   spec.</p>
   *
   * <p>The title is the primary text of an activity.</p>
   *
   * <p>Titles may only have the following HTML tags: &lt;b&gt; &lt;i&gt;,
   * &lt;a&gt;, &lt;span&gt;.
   * The container may ignore this formatting when rendering the activity.</p>
   *
   * @member opensocial.Activity.Field
   */
  TITLE_ID : 'titleId',

  /**
   * <p>A string specifying the primary text of an activity.</p>
   *
   * <p>Titles may only have the following HTML tags: &lt;b&gt; &lt;i&gt;,
   * &lt;a&gt;, &lt;span&gt;.
   * The container may ignore this formatting when rendering the activity.</p>
   *
   * @member opensocial.Activity.Field
   */
  TITLE : 'title',

  /**
   * <p>A map of custom keys to values associated with this activity.
   * These will be used for evaluation in templates.</p>
   *
   * <p>The data has type <code>Map&lt;String, Object&gt;</code>. The
   * object may be either a String or an opensocial.Person.</p>
   *
   * <p>When passing in a person with key PersonKey, can use the following
   * replacement variables in the template:</p>
   * <ul>
   *  <li>PersonKey.DisplayName - Display name for the person</li>
   *  <li>PersonKey.ProfileUrl. URL of the person's profile</li>
   *  <li>PersonKey.Id -  The ID of the person</li>
   *  <li>PersonKey - Container may replace with DisplayName, but may also
   *     optionally link to the user.</li>
   * </ul>
   *
   * @member opensocial.Activity.Field
   */
  TEMPLATE_PARAMS : 'templateParams',

  /**
   * A string specifying the
   * URL that represents this activity.
   * @member opensocial.Activity.Field
   */
  URL : 'url',

  /**
   * Any photos, videos, or images that should be associated
   * with the activity. Higher priority ones are higher in the list.
   * The data has type <code>Array&lt;
   * <a href="opensocial.Activity.MediaItem.html">MediaItem</a>&gt;</code>.
   * @member opensocial.Activity.Field
   */
  MEDIA_ITEMS : 'mediaItems',

  /**
   * <p>A string specifying the body template message ID in the gadget spec.</p>
   *
   * <p>The body is an optional expanded version of an activity.</p>
   *
   * <p>Bodies may only have the following HTML tags: &lt;b&gt; &lt;i&gt;,
   * &lt;a&gt;, &lt;span&gt;.
   * The container may ignore this formatting when rendering the activity.</p>
   *
   * @member opensocial.Activity.Field
   */
  BODY_ID : 'bodyId',

  /**
   * <p>A string specifying an optional expanded version of an activity.</p>
   *
   * <p>Bodies may only have the following HTML tags: &lt;b&gt; &lt;i&gt;,
   * &lt;a&gt;, &lt;span&gt;.
   * The container may ignore this formatting when rendering the activity.</p>
   *
   * @member opensocial.Activity.Field
   */
  BODY : 'body',

  /**
   * An optional string ID generated by the posting application.
   * @member opensocial.Activity.Field
   */
  EXTERNAL_ID : 'externalId',

  /**
   * A string specifing the title of the stream.
   * @member opensocial.Activity.Field
   */
  STREAM_TITLE : 'streamTitle',

  /**
   * A string specifying the stream's URL.
   * @member opensocial.Activity.Field
   */
  STREAM_URL : 'streamUrl',

  /**
   * A string specifying the stream's source URL.
   * @member opensocial.Activity.Field
   */
  STREAM_SOURCE_URL : 'streamSourceUrl',

  /**
   * A string specifying the URL for the stream's favicon.
   * @member opensocial.Activity.Field
   */
  STREAM_FAVICON_URL : 'streamFaviconUrl',

  /**
   * A number between 0 and 1 representing the relative priority of
   * this activity in relation to other activities from the same source
   * @member opensocial.Activity.Field
   */
  PRIORITY : 'priority',

  /**
   * A string ID that is permanently associated with this activity.
   * This value can not be set.
   * @member opensocial.Activity.Field
   */
  ID : 'id',

  /**
   * The string ID of the user who this activity is for.
   * This value can not be set.
   * @member opensocial.Activity.Field
   */
  USER_ID : 'userId',

  /**
   * A string specifying the application that this activity is associated with.
   * This value can not be set.
   * @member opensocial.Activity.Field
   */
  APP_ID : 'appId',

  /**
   * A string specifying the time at which this activity took place
   * in milliseconds since the epoch.
   * This value can not be set.
   * @member opensocial.Activity.Field
   */
  POSTED_TIME : 'postedTime'
};


/**
 * Gets an ID that can be permanently associated with this activity.
 *
 * @return {String} The ID
 * @member opensocial.Activity
 */
opensocial.Activity.prototype.getId = function() {
  return this.getField(opensocial.Activity.Field.ID);
};


/**
 * Gets the activity data that's associated with the specified key.
 *
 * @param {String} key The key to get data for;
 *   see the <a href="opensocial.Activity.Field.html">Field</a> class
 * for possible values
 * @return {String} The data
 * @member opensocial.Activity
 */
opensocial.Activity.prototype.getField = function(key) {
  return this.fields_[key];
};


/**
 * Sets data for this activity associated with the given key.
 *
 * @param {String} key The key to set data for
 * @param {String} data The data to set
 */
opensocial.Activity.prototype.setField = function(key, data) {
  return this.fields_[key] = data;
};


/**
 * @class
 * A media item associated with an activity.
 * Represents images, movies, and audio.
 * Create a <code>MediaItem</code> object using the
 * <a href="opensocial.html#newActivityMediaItem">
 * opensocial.newActivityMediaItem()</a> method.
 *
 * @name opensocial.Activity.MediaItem
 */

/**
 * A media item associated with an activity. Represents images, movies, and
 * audio.
 *
 * @param {String} mimeType The media's type
 * @param {String} url The media's location
 * @param {Map.<opensocial.Activity.MediaItem.Field, Object>} opt_params
 *    Any other fields that should be set on the media item object.
 *    All of the defined Fields are supported.
 * @constructor
 * @private
 */
opensocial.Activity.MediaItem = function(mimeType, url, opt_params) {
  this.fields_ = opt_params || {};
  this.fields_[opensocial.Activity.MediaItem.Field.MIME_TYPE] = mimeType;
  this.fields_[opensocial.Activity.MediaItem.Field.URL] = url;
};


/**
 * @static
 * @class
 * The possible types of media items.
 *
 * <p>
 * <b>See also:</b>
 * <a href="opensocial.Activity.MediaItem.Field.html">
 * opensocial.Activity.MediaItem.Field</a>
 * </p>
 *
 * @name opensocial.Activity.MediaItem.Type = {
 */
opensocial.Activity.MediaItem.Type = {
  /** @member opensocial.Activity.MediaItem.Type */
  IMAGE : 'image',
  /** @member opensocial.Activity.MediaItem.Type */
  VIDEO : 'video',
  /** @member opensocial.Activity.MediaItem.Type */
  AUDIO : 'audio'
}


/**
 * @static
 * @class
 * All of the fields that media items have.
 *
 * <p>
 * <b>See also:</b>
 * <a href="opensocial.Activity.MediaItem.html#getField">
 * opensocial.Activity.MediaItem.getField()</a>
 * </p>
 *
 * @name opensocial.Activity.MediaItem.Field
 */
opensocial.Activity.MediaItem.Field = {
  /**
   * The type of media, specified as a
   * <a href="opensocial.Activity.MediaItem.Type.html">
   * <code>MediaItem.Type</code></a> object.
   * @member opensocial.Activity.MediaItem.Field
   */
  TYPE : 'type',

  /**
   * The MIME type of media, specified as a String.
   * @member opensocial.Activity.MediaItem.Field
   */
  MIME_TYPE : 'mimeType',

  /**
   * A string specifying the URL where the media can be found.
   * @member opensocial.Activity.MediaItem.Field
   */
  URL : 'url'
};


/**
 * Gets the media item data that's associated with the specified key.
 *
 * @param {String} key The key to get data for; see the
 *   <a href="opensocial.Activity.MediaItem.Field.html">Field</a> class
 *   for possible values
 * @return {String} The data
 */
opensocial.Activity.MediaItem.prototype.getField = function(key) {
  return this.fields_[key];
};


/**
 * Sets data for this media item associated with the given key.
 *
 * @param {String} key The key to set data for
 * @param {String} data The data to set
 */
opensocial.Activity.MediaItem.prototype.setField = function(key, data) {
  return this.fields_[key] = data;
};



/************** end activity.js ********************/

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * @fileoverview Representation of an address.
 */


/**
 * @class
 * Base interface for all address objects.
 *
 * @name opensocial.Address
 */


/**
 * Base interface for all address objects.
 *
 * @private
 * @constructor
 */
opensocial.Address = function(opt_params) {
  this.fields_ = opt_params || {};
};


/**
 * @static
 * @class
 * All of the fields that an address has. These are the supported keys for the
 * <a href="opensocial.Address.html#getField">Address.getField()</a> method.
 *
 * @name opensocial.Address.Field
 */
opensocial.Address.Field = {
  /**
   * The address type or label. Examples: work, my favorite store, my house, etc
   * Specified as a String.
   *
   * @member opensocial.Address.Field
   */
  TYPE : 'type',

  /**
   * If the container does not have structured addresses in its data store,
   * this field will return the unstructured address that the user entered. Use
   * opensocial.getEnvironment().supportsField to see which fields are
   * supported. Specified as a String.
   *
   * @member opensocial.Address.Field
   */
  UNSTRUCTURED_ADDRESS : 'unstructuredAddress',

  /**
   * The po box of the address if there is one. Specified as a String.
   *
   * @member opensocial.Address.Field
   */
  PO_BOX : 'poBox',

  /**
   * The street address. Specified as a String.
   *
   * @member opensocial.Address.Field
   */
  STREET_ADDRESS : 'streetAddress',

  /**
   * The extended street address. Specified as a String.
   *
   * @member opensocial.Address.Field
   */
  EXTENDED_ADDRESS : 'extendedAddress',

  /**
   * The region. Specified as a String.
   *
   * @member opensocial.Address.Field
   */
  REGION : 'region',

  /**
   * The locality. Specified as a String.
   *
   * @member opensocial.Address.Field
   */
  LOCALITY : 'locality',

  /**
   * The postal code. Specified as a String.
   *
   * @member opensocial.Address.Field
   */
  POSTAL_CODE : 'postalCode',

  /**
   * The country. Specified as a String.
   *
   * @member opensocial.Address.Field
   */
  COUNTRY : 'country',

  /**
   * The latitude. Specified as a Number.
   *
   * @member opensocial.Address.Field
   */
  LATITUDE : 'latitude',

  /**
   * The longitude. Specified as a Number.
   *
   * @member opensocial.Address.Field
   */
  LONGITUDE : 'longitude'
};


/**
 * Gets data for this body type that is associated with the specified key.
 *
 * @param {String} key The key to get data for;
 *    keys are defined in <a href="opensocial.Address.Field.html"><code>
 *    Address.Field</code></a>
 * @return {String} The data
 */
opensocial.Address.prototype.getField = function(key) {
  return this.fields_[key];
};



/************** end address.js ********************/

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * @fileoverview Representation of a body type.
 */


/**
 * @class
 * Base interface for all body type objects.
 *
 * @name opensocial.BodyType
 */


/**
 * Base interface for all body type objects.
 *
 * @private
 * @constructor
 */
opensocial.BodyType = function(opt_params) {
  this.fields_ = opt_params || {};
};


/**
 * @static
 * @class
 * All of the fields that a body type has. These are the supported keys for the
 * <a href="opensocial.BodyType.html#getField">BodyType.getField()</a>
 * method.
 *
 * @name opensocial.BodyType.Field
 */
opensocial.BodyType.Field = {
  /**
   * The build of the person's body, specified as a string.
   * Not supported by all containers.
   * @member opensocial.BodyType.Field
   */
  BUILD : 'build',

  /**
   * The height of the person in meters, specified as a number.
   * Not supported by all containers.
   * @member opensocial.BodyType.Field
   */
  HEIGHT : 'height',

  /**
   * The weight of the person in kilograms, specified as a number.
   * Not supported by all containers.
   * @member opensocial.BodyType.Field
   */
  WEIGHT : 'weight',

  /**
   * The eye color of the person, specified as a string.
   * Not supported by all containers.
   * @member opensocial.BodyType.Field
   */
  EYE_COLOR : 'eyeColor',

  /**
   * The hair color of the person, specified as a string.
   * Not supported by all containers.
   * @member opensocial.BodyType.Field
   */
  HAIR_COLOR : 'hairColor'
};


/**
 * Gets data for this body type that is associated with the specified key.
 *
 * @param {String} key The key to get data for;
 *    keys are defined in <a href="opensocial.BodyType.Field.html"><code>
 *    BodyType.Field</code></a>
 * @return {String} The data
 */
opensocial.BodyType.prototype.getField = function(key) {
  return this.fields_[key];
};



/************** end bodytype.js ********************/

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * @fileoverview Collection of multiple objects with useful accessors.
 *
 * May also represent subset of a larger collection (i.e. page 1 of 10), and
 * contain information about the larger collection.
 */


/**
 * @class
 * Collection of multiple objects with useful accessors.
 * May also represent subset of a larger collection
 * (for example, page 1 of 10)
 * and contain information about the larger collection.
 *
 * @name opensocial.Collection
 */


/**
 * Create a collection.
 *
 * @private
 * @constructor
 */
opensocial.Collection = function(array, opt_offset, opt_totalSize) {
  this.array_ = array || [];
  this.offset_ = opt_offset || 0;
  this.totalSize_ = opt_totalSize || this.array_.length;
};


/**
 * Finds the entry with the given ID value, or returns null if none is found.
 * @param {String} id The ID to look for
 * @return {Object?} The data
 */
opensocial.Collection.prototype.getById = function(id) {
   // TODO(doll): A non-linear search would be better
  for (var i = 0; i < this.size(); i++) {
    var item = this.array_[i];
    if (item.getId() == id) {
      return item;
    }
  }

  return null;
};


/**
 * Gets the size of this collection,
 * which is equal to or less than the
 * total size of the result.
 * @return {Number} The size of this collection
 */
opensocial.Collection.prototype.size = function() {
  return this.array_.length;
};


/**
 * Executes the provided function once per member of the collection,
 * with each member in turn as the
 * parameter to the function.
 * @param {Function} fn The function to call with each collection entry
 */
opensocial.Collection.prototype.each = function(fn) {
  for (var i = 0; i < this.size(); i++) {
    fn(this.array_[i]);
  }
};


/**
 * Returns an array of all the objects in this collection.
 * @return {Array.&lt;Object&gt;} The values in this collection
 */
opensocial.Collection.prototype.asArray = function() {
  return this.array_;
};


/**
 * Gets the total size of the larger result set
 * that this collection belongs to.
 * @return {Number} The total size of the result
 */
opensocial.Collection.prototype.getTotalSize = function() {
  return this.totalSize_;
};


/**
 * Gets the offset of this collection within a larger result set.
 * @return {Number} The offset into the total collection
 */
opensocial.Collection.prototype.getOffset = function() {
  return this.offset_;
};



/************** end collection.js ********************/

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * @fileoverview Object used to request social information from the container.
 * This includes data for friends, profiles, app data, and activities.
 *
 * All apps that require access to people information should send a dataRequest
 * in order to receieve a dataResponse
 */


/**
 * @class
 * <p>
 * Used to request social information from the container.
 * This includes data for friends, profiles, app data, and activities.
 * All apps that require access to people information
 * should send a DataRequest.
 * </p>
 *
 * <p>
 * Here's an example of creating, initializing, sending, and handling
 * the results of a data request:
 * </p>
 *
 * <pre>function requestMe() {
  var req = opensocial.newDataRequest();
  req.add(req.newFetchPersonRequest(
            opensocial.DataRequest.PersonId.VIEWER),
          "viewer");
  req.send(handleRequestMe);
};

function handleRequestMe(data) {
  var viewer = data.get("viewer");
  if (viewer.hadError()) {
    <em>//Handle error using viewer.getError()...</em>
    return;
  }

  <em>//No error. Do something with viewer.getData()...</em>
}
</pre>
 * <p>
 * <b>See also:</b>
 * <a href="opensocial.html#newDataRequest"><code>
 * opensocial.newDataRequest()</code></a>
 * </p>
 *
 * @name opensocial.DataRequest
 */

/**
 * Do not create a DataRequest directly, instead use
 * opensocial.createDataRequest();
 *
 * @private
 * @constructor
 */
opensocial.DataRequest = function() {
  this.requestObjects_ = [];
};


/**
 * {Array.<{key: string, request:opensocial.DataRequest.BaseDataRequest}>}
 *    requestObjects An array of
 *    data requests that the container should fetch data for
 * @private
 */
opensocial.DataRequest.prototype.requestObjects_ = null;


/**
 * Get the requested objects
 *
 * @return {Array.<{key:String, request:BaseDataRequest}>}
 *    requestObjects An array of data requests that the container should fetch
 *    data for
 * @private
 */
opensocial.DataRequest.prototype.getRequestObjects = function() {
  return this.requestObjects_;
};


/**
 * Adds an item to fetch (get) or update (set) data from the server.
 * A single DataRequest object can have multiple items.
 * As a rule, each item is executed in the order it was added,
 * starting with the item that was added first.
 * However, items that can't collide might be executed in parallel.
 *
 * @param {Object} request Specifies which data to fetch or update
 * @param {String} opt_key A key to map the generated response data to
 */
opensocial.DataRequest.prototype.add = function(request, opt_key) {
  return this.requestObjects_.push({'key': opt_key, 'request': request});
};


/**
 * Sends a data request to the server in order to get a data response.
 * Although the server may optimize these requests,
 * they will always be executed
 * as though they were serial.
 *
 * @param {Function} opt_callback The function to call with the
 *   <a href="opensocial.DataResponse.html">data response</a>
 *    generated by the server
 */
opensocial.DataRequest.prototype.send = function(opt_callback) {
  var callback = opt_callback || function(){};
  opensocial.Container.get().requestData(this, callback);
};


/**
 * @static
 * @class
 * Constant person IDs available when fetching person information.
 *
 * @name opensocial.DataRequest.PersonId
 */
opensocial.DataRequest.PersonId = {
 /**
  * @member opensocial.DataRequest.PersonId
  */
  OWNER : 'OWNER',
 /**
  * @member opensocial.DataRequest.PersonId
  */
  VIEWER : 'VIEWER'
};


/**
 * @static
 * @class
 * Groups available when fetching person information.
 *
 * @name opensocial.DataRequest.Group
 */
opensocial.DataRequest.Group = {
 /**
  * @member opensocial.DataRequest.Group
  */
  OWNER_FRIENDS : 'OWNER_FRIENDS',
 /**
  * @member opensocial.DataRequest.Group
  */
  VIEWER_FRIENDS : 'VIEWER_FRIENDS'
};


/**
 * @static
 * @class
 * The sort orders available for ordering person objects.
 *
 * @name opensocial.DataRequest.SortOrder
 */
opensocial.DataRequest.SortOrder = {
  /**
   * When used will sort people by the container's definition of top friends.
   * @member opensocial.DataRequest.SortOrder
   */
  TOP_FRIENDS : 'topFriends',
  /**
   * When used will sort people alphabetically by the name field.
   *
   * @member opensocial.DataRequest.SortOrder
   */
  NAME : 'name'
};


/**
 * @static
 * @class
 * The filters available for limiting person requests.
 *
 * @name opensocial.DataRequest.FilterType
 */
opensocial.DataRequest.FilterType = {
  /**
   * Retrieves all friends.
   *
   * @member opensocial.DataRequest.FilterType
   */
  ALL : 'all',
  /**
   * Retrieves all friends with any data for this application.
   *
   * @member opensocial.DataRequest.FilterType
   */
  HAS_APP : 'hasApp'
};


/**
 * @static
 * @class
 * @name opensocial.DataRequest.PeopleRequestFields
 */
opensocial.DataRequest.PeopleRequestFields = {
  /**
   * An array of
   * <a href="opensocial.Person.Field.html">
   * <code>opensocial.Person.Field</code></a>
   * specifying what profile data to fetch
   * for each of the person objects. The server will always include
   * ID, NAME, and THUMBNAIL_URL.
   *
   * @member opensocial.DataRequest.PeopleRequestFields
   */
  PROFILE_DETAILS : 'profileDetail',

  /**
   * A sort order for the people objects; defaults to TOP_FRIENDS.
   * Possible values are defined by
   * <a href="opensocial.DataRequest.SortOrder.html">SortOrder</a>.
   *
   * @member opensocial.DataRequest.PeopleRequestFields
   */
  SORT_ORDER : 'sortOrder',

  /**
   * How to filter the people objects; defaults to ALL.
   * Possible values are defined by
   * <a href="opensocial.DataRequest.FilterType.html">FilterType</a>.
   *
   * @member opensocial.DataRequest.PeopleRequestFields
   */
  FILTER : 'filter',

  /**
   * When paginating, the index of the first item to fetch.
   * Specified as a <code>Number</code>.
   *
   * @member opensocial.DataRequest.PeopleRequestFields
   */
  FIRST : 'first',

  /**
   * The maximum number of items to fetch; defaults to 20. If set to a larger
   * number, a container may honor the request, or may limit the number to a
   * container-specified limit of at least 20.
   * Specified as a <code>Number</code>.
   *
   * @member opensocial.DataRequest.PeopleRequestFields
   */
  MAX : 'max'
};


/**
 * If the named param does not exist sets it to the default value.
 *
 * @param {Map} params Parameter map.
 * @param {String} name of the param to check
 * @param {Object} defaultValue The value to set if the param does not exist.
 * @private
 */
opensocial.DataRequest.prototype.addDefaultParam = function(params, name,
    defaultValue) {
  params[name] = params[name] || defaultValue;
};


/**
 * Adds the default profile fields to the desired array.
 *
 * @param {Map} params Parameter map.
 * @private
 */
opensocial.DataRequest.prototype.addDefaultProfileFields = function(params) {
  var fields = opensocial.DataRequest.PeopleRequestFields;
  var profileFields = params[fields.PROFILE_DETAILS] || [];
  params[fields.PROFILE_DETAILS] = profileFields.concat(
      [opensocial.Person.Field.ID, opensocial.Person.Field.NAME,
       opensocial.Person.Field.THUMBNAIL_URL]);
};


/**
 * Returns the keys object as an array.
 *
 * @param {Object} keys
 * @private
 */
opensocial.DataRequest.prototype.asArray = function(keys) {
  if (opensocial.Container.isArray(keys)) {
    return keys;
  } else {
    return [keys];
  }
};


/**
 * Creates an item to request a profile for the specified person ID.
 * When processed, returns a
 * <a href="opensocial.Person.html"><code>Person</code></a> object.
 *
 * @param {String} id The ID of the person to fetch; can be the standard
 *    <a href="opensocial.DataRequest.PersonId.html">person ID</a>
 *    of VIEWER or OWNER
 * @param {Map.&lt;opensocial.DataRequest.PeopleRequestFields, Object&gt;}
 *  opt_params
 *    Additional
 *    <a href="opensocial.DataRequest.PeopleRequestFields.html">parameters</a>
 *    to pass to the request; this request supports PROFILE_DETAILS
 * @return {Object} A request object
 */
opensocial.DataRequest.prototype.newFetchPersonRequest = function(id,
    opt_params) {
  opt_params = opt_params || {};
  var fields = opensocial.DataRequest.PeopleRequestFields;

  this.addDefaultProfileFields(opt_params);

  return opensocial.Container.get().newFetchPersonRequest(id, opt_params);
};


/**
 * Creates an item to request friends from the server.
 * When processed, returns a <a href="opensocial.Collection.html">Collection</a>
 * &lt;<a href="opensocial.Person.html">Person</a>&gt; object.
 *
 * @param {Array.&lt;String&gt; | String} idSpec An ID, array of IDs, or a group
 *    reference used to specify which people to fetch; the supported keys are
 *    VIEWER, OWNER, VIEWER_FRIENDS, OWNER_FRIENDS, or a single ID within one
 *    of those groups.
 * @param {Map.&lt;opensocial.DataRequest.PeopleRequestFields, Object&gt;}
 *  opt_params
 *    Additional
 *    <a href="opensocial.DataRequest.PeopleRequestFields.html">params</a>
 *    to pass to the request
 * @return {Object} A request object
 */
opensocial.DataRequest.prototype.newFetchPeopleRequest = function(idSpec,
    opt_params) {
  opt_params = opt_params || {};
  var fields = opensocial.DataRequest.PeopleRequestFields;

  this.addDefaultProfileFields(opt_params);

  this.addDefaultParam(opt_params, fields.SORT_ORDER,
      opensocial.DataRequest.SortOrder.TOP_FRIENDS);

  this.addDefaultParam(opt_params, fields.FILTER,
      opensocial.DataRequest.FilterType.ALL);

  this.addDefaultParam(opt_params, fields.FIRST, 0);

  this.addDefaultParam(opt_params, fields.MAX, 20);

  return opensocial.Container.get().newFetchPeopleRequest(idSpec, opt_params);
};


/**
 * Creates an item to request app data for the given people.
 * When processed, returns a Map&lt;
 * <a href="opensocial.DataRequest.PersonId.html">PersonId</a>,
 * Map&lt;String,
 * String&gt;&gt; object.
 *
 * @param {Array.&lt;String&gt; | String} idSpec An ID, array of IDs, or a group
 *    reference; the supported keys are VIEWER, OWNER, VIEWER_FRIENDS,
 *    OWNER_FRIENDS, or a single ID within one of those groups
 * @param {Array.&lt;String&gt; | String} keys The keys you want data for; this
 *     can be an array of key names, a single key name, or "*" to mean
 *     "all keys"
 * @return {Object} A request object
 */
opensocial.DataRequest.prototype.newFetchPersonAppDataRequest = function(idSpec,
    keys) {
  return opensocial.Container.get().newFetchPersonAppDataRequest(idSpec,
      this.asArray(keys));
};


/**
 * Creates an item to request an update of an app field for the given person.
 * When processed, does not return any data.
 *
 * @param {String} id The ID of the person to update; only the
 *     special <code>VIEWER</code> ID is currently allowed.
 * @param {String} key The name of the key. This may only contain alphanumeric
 *     (A-Za-z0-9) characters, underscore(_), dot(.) or dash(-).
 * @param {String} value The value
 * @return {Object} A request object
 */
opensocial.DataRequest.prototype.newUpdatePersonAppDataRequest = function(id,
    key, value) {
  return opensocial.Container.get().newUpdatePersonAppDataRequest(id, key,
      value);
};


/**
 * @static
 * @class
 * Used by
 * <a href="opensocial.DataRequest.html#newFetchActivitiesRequest">
 * <code>DataRequest.newFetchActivitiesRequest()</code></a>.
 * @name opensocial.DataRequest.ActivityRequestFields
 * @private
 */
opensocial.DataRequest.ActivityRequestFields = {
  /**
   * {String} If provided will filter all activities by this app Id.
   * @private - at the moment you can only request activities for your own app
   */
  APP_ID : 'appId'
};


/**
 * Creates an item to request an activity stream from the server.
 *
 * <p>
 * When processed, returns an object whose "activities" property is a
 * Collection&lt;Activity&gt; object.
 * </p>
 *
 * @param {Array.&lt;String&gt; | String} idSpec An ID, array of IDs, or a group
 *    reference used to specify which people's activities to fetch; the
 *    supported keys are VIEWER, OWNER, VIEWER_FRIENDS, OWNER_FRIENDS, or
 *    a single ID within one of those groups.
 * @param {Map.&lt;opensocial.DataRequest.ActivityRequestFields, Object&gt;}
 *  opt_params
 *    Additional parameters
 *    to pass to the request; not currently used
 * @return {Object} A request object
 */
opensocial.DataRequest.prototype.newFetchActivitiesRequest = function(idSpec,
    opt_params) {
  opt_params = opt_params || {};
  return opensocial.Container.get().newFetchActivitiesRequest(idSpec,
      opt_params);
};



/************** end datarequest.js ********************/

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * @fileoverview DataResponse containing information about
 * friends, contacts, profile, app data, and activities.
 *
 * Whenever a dataRequest is sent to the server it will return a dataResponse
 * object. Values from the server will be mapped to the requested keys specified
 * in the dataRequest.
 */


/**
 * @class
 * This object contains the requested server data mapped to the requested keys.
 *
 * <p>
 * <b>See also:</b>
 * <a href="opensocial.DataRequest.html">DataRequest</a>
 * </p>
 *
 * @name opensocial.DataResponse
 */

/**
 * Construct the data response.
 * This object contains the requested server data mapped to the requested keys.
 *
 * @param {Map.<String, ResponseItem>} responseItems Key/value map of data
 *    response information
 * @param {Boolean} opt_globalError Optional field indicating whether there were
 *    any errors generating this data response
 *
 * @private
 * @constructor
 */
opensocial.DataResponse = function(responseItems, opt_globalError) {
  this.responseItems_ = responseItems;
  this.globalError_ = opt_globalError;
};


/**
 * Returns true if there was an error in fetching this data from the server.
 *
 * @return {Boolean} True if there was an error; otherwise, false
 * @member opensocial.DataResponse
 */
opensocial.DataResponse.prototype.hadError = function() {
  return !!this.globalError_;
};


/**
 * Gets the ResponseItem for the requested field.
 *
 * @return {opensocial.ResponseItem} The requested
 *    <a href="opensocial.ResponseItem.html">response</a> calculated by the
 *    server
 * @member opensocial.DataResponse
 */
opensocial.DataResponse.prototype.get = function(key) {
  return this.responseItems_[key];
};



/************** end dataresponse.js ********************/

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * @fileoverview Representation of an email.
 */


/**
 * @class
 * Base interface for all email objects.
 *
 * @name opensocial.Email
 */


/**
 * Base interface for all email objects.
 *
 * @private
 * @constructor
 */
opensocial.Email = function(opt_params) {
  this.fields_ = opt_params || {};
};


/**
 * @static
 * @class
 * All of the fields that an email has. These are the supported keys for the
 * <a href="opensocial.Email.html#getField">Email.getField()</a> method.
 *
 * @name opensocial.Email.Field
 */
opensocial.Email.Field = {
  /**
   * The email type or label, specified as a String.
   * Examples: work, my favorite store, my house, etc.
   *
   * @member opensocial.Email.Field
   */
  TYPE : 'type',

  /**
   * The email address, specified as a String.
   *
   * @member opensocial.Email.Field
   */
  ADDRESS : 'address'
};


/**
 * Gets data for this body type that is associated with the specified key.
 *
 * @param {String} key The key to get data for;
 *    keys are defined in <a href="opensocial.Email.Field.html"><code>
 *    Email.Field</code></a>
 * @return {String} The data
 */
opensocial.Email.prototype.getField = function(key) {
  return this.fields_[key];
};



/************** end email.js ********************/

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * @fileoverview Representation of an enum.
 */


/**
 * @class
 * Base interface for all enum objects.
 * This class allows containers to use constants for fields that are usually
 * have a common set of values.
 * There are two main ways to use this class.
 *
 * <p>
 * If your gadget just wants to display how much of a smoker someone is,
 * it can simply use:
 * </p>
 *
 * <pre>html = "This person smokes: " + person.getField('smoker').getValue();</pre>
 *
 * <p>
 * This value field will be correctly set up by the container. This is a place
 * where the container can even localize the value for the gadget so that it
 * always shows the right thing.
 * </p>
 *
 * <p>
 * If your gadget wants to have some logic around the smoker
 * field it can use:
 * </p>
 *
 * <pre>if (person.getField('smoker').getKey() != "NO") { //gadget logic here }</pre>
 *
 * <p class="note">
 * <b>Note:</b>
 * The key may be null if the person's smoker field cannot be coerced
 * into one of the standard enum types.
 * The value, on the other hand, is never null.
 * </p>
 *
 * @name opensocial.Enum
 */


/**
 * Base interface for all enum objects.
 *
 * @private
 * @constructor
 */
opensocial.Enum = function(key, displayValue) {
  this.key = key;
  this.displayValue = displayValue;
};


/**
 * Use this for logic within your gadget. If they key is null then the value
 * does not fit in the defined enums.
 *
 * @return {String} The enum's key. This should be one of the defined enums
 *     below.
 */
opensocial.Enum.prototype.getKey = function() {
  return this.key;
};


/**
 * The value of this enum. This will be a user displayable string. If the
 * container supports localization, the string will be localized.
 *
 * @return {String} The enum's value.
 */
opensocial.Enum.prototype.getDisplayValue = function() {
  return this.displayValue;
};


/**
 * @static
 * @class
 * The enum keys used by the smoker field.
 * <p><b>See also:</b>
 * <a href="opensocial.Person.Field.html">
 * opensocial.Person.Field.Smoker</a>
 * </p>
 *
 * @name opensocial.Enum.Smoker
 */
opensocial.Enum.Smoker = {
  /** @member opensocial.Enum.Smoker */
  NO : 'NO',
  /** @member opensocial.Enum.Smoker */
  YES : 'YES',
  /** @member opensocial.Enum.Smoker */
  SOCIALLY : 'SOCIALLY',
  /** @member opensocial.Enum.Smoker */
  OCCASIONALLY : 'OCCASIONALLY',
  /** @member opensocial.Enum.Smoker */
  REGULARLY : 'REGULARLY',
  /** @member opensocial.Enum.Smoker */
  HEAVILY : 'HEAVILY',
  /** @member opensocial.Enum.Smoker */
  QUITTING : 'QUITTING',
  /** @member opensocial.Enum.Smoker */
  QUIT : 'QUIT'
};


/**
 * @static
 * @class
 * The enum keys used by the drinker field.
 * <p><b>See also:</b>
 * <a href="opensocial.Person.Field.html">
 * opensocial.Person.Field.Drinker</a>
 * </p>
 *
 * @name opensocial.Enum.Drinker
 */
opensocial.Enum.Drinker = {
  /** @member opensocial.Enum.Drinker */
  NO : 'NO',
  /** @member opensocial.Enum.Drinker */
  YES : 'YES',
  /** @member opensocial.Enum.Drinker */
  SOCIALLY : 'SOCIALLY',
  /** @member opensocial.Enum.Drinker */
  OCCASIONALLY : 'OCCASIONALLY',
  /** @member opensocial.Enum.Drinker */
  REGULARLY : 'REGULARLY',
  /** @member opensocial.Enum.Drinker */
  HEAVILY : 'HEAVILY',
  /** @member opensocial.Enum.Drinker */
  QUITTING : 'QUITTING',
  /** @member opensocial.Enum.Drinker */
  QUIT : 'QUIT'
};


/**
 * @static
 * @class
 * The enum keys used by the gender field.
 * <p><b>See also:</b>
 * <a href="opensocial.Person.Field.html">
 * opensocial.Person.Field.Gender</a>
 * </p>
 *
 * @name opensocial.Enum.Gender
 */
opensocial.Enum.Gender = {
  /** @member opensocial.Enum.Gender */
  MALE : 'MALE',
  /** @member opensocial.Enum.Gender */
  FEMALE : 'FEMALE'
};



/************** end enum.js ********************/

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * @fileoverview Representation of a environment.
 */


/**
 * @class
 * Represents the current environment for a gadget.
 *
 * <p>
 * <b>See also:</b>
 * <a href="opensocial.html#getEnvironment">opensocial.getEnvironment()</a>,
 *
 * @name opensocial.Environment
 */


/**
 * Base interface for all environment objects.
 *
 * @param {String} domain The current domain
 * @param {Map.&lt;String, Map.&lt;String, Boolean&gt;&gt;} supportedFields
 *    The fields supported by this container
 *
 * @private
 * @constructor
 */
opensocial.Environment = function(domain, supportedFields) {
  this.domain = domain;
  this.supportedFields = supportedFields;
};


/**
 * Returns the current domain &mdash;
 * for example, "orkut.com" or "myspace.com".
 *
 * @return {String} The domain
 */
opensocial.Environment.prototype.getDomain = function() {
  return this.domain;
};


/**
 * @static
 * @class
 *
 * The types of objects in this container.
 *
 * <p>
 * <b>See also:</b>
 * <a href="opensocial.Environment.html#supportsField">
 * <code>Environment.supportsField()</code></a>
 *
 * @name opensocial.Environment.ObjectType
 */
opensocial.Environment.ObjectType = {
  /**
   * @member opensocial.Environment.ObjectType
   */
  PERSON : 'person',
  /**
   * @member opensocial.Environment.ObjectType
   */
  ADDRESS : 'address',
  /**
   * @member opensocial.Environment.ObjectType
   */
  BODY_TYPE : 'bodyType',
  /**
   * @member opensocial.Environment.ObjectType
   */
  EMAIL : 'email',
  /**
   * @member opensocial.Environment.ObjectType
   */
  NAME : 'name',
  /**
   * @member opensocial.Environment.ObjectType
   */
  ORGANIZATION : 'organization',
  /**
   * @member opensocial.Environment.ObjectType
   */
  PHONE : 'phone',
  /**
   * @member opensocial.Environment.ObjectType
   */
  URL : 'url',
  /**
   * @member opensocial.Environment.ObjectType
   */
  ACTIVITY : 'activity',
  /**
   * @member opensocial.Environment.ObjectType
   */
  ACTIVITY_MEDIA_ITEM : 'activityMediaItem',
  /**
   * @member opensocial.Environment.ObjectType
   */
  MESSAGE : 'message',
  /**
   * @member opensocial.Environment.ObjectType
   */
  MESSAGE_TYPE : 'messageType',
  /**
   * @member opensocial.Environment.ObjectType
   */
  SORT_ORDER : 'sortOrder',
  /**
   * @member opensocial.Environment.ObjectType
   */
  FILTER_TYPE : 'filterType'
};


/**
 * Returns true if the specified field is supported in this container on the
 * given object type.
 *
 * @param {opensocial.Environment.ObjectType} objectType
 *    The <a href="opensocial.Environment.ObjectType.html">object type</a>
 *    to check for the field
 * @param {String} fieldName The name of the field to check for
 * @return {Boolean} True if the field is supported on the specified object type
 */
opensocial.Environment.prototype.supportsField = function(objectType,
    fieldName) {
  var supportedObjectFields = this.supportedFields[objectType] || [];
  return !!supportedObjectFields[fieldName];
};


/************** end environment.js ********************/

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * @fileoverview Representation of a message.
 */


/**
 * @class
 * Base interface for all message objects.
 *
 * <p>
 * <b>See also:</b>
 * <a href="opensocial.html#newMessage">opensocial.newMessage()</a>,
 * <a href="opensocial.html#requestSendMessage">
 * opensocial.requestSendMessage()</a>
 *
 * @name opensocial.Message
 */


/**
 * Base interface for all message objects.
 *
 * @param {String} body The main text of the message.
 * @param {Map.<opensocial.Message.Field, Object>} opt_params Any other
 *    fields that should be set on the message object. All of the defined
 *    Fields are supported.
 * @private
 * @constructor
 */
opensocial.Message = function(body, opt_params) {
  this.fields_ = opt_params || {};
  this.fields_[opensocial.Message.Field.BODY] = body;
};


/**
 * @static
 * @class
 * All of the fields that messages can have.
 *
 * <p>
 * <b>See also:</b>
 * <a
 * href="opensocial.Message.html#getField">opensocial.Message.getField()</a>
 * </p>
 *
 * @name opensocial.Message.Field
 */
opensocial.Message.Field = {
  /**
   * The title of the message, specified as an opensocial.Message.Type.
   * @member opensocial.Message.Field
   */
  TYPE : 'type',

  /**
   * The title of the message. HTML attributes are allowed and are
   * sanitized by the container.
   * @member opensocial.Message.Field
   */
  TITLE : 'title',

  /**
   * The main text of the message. HTML attributes are allowed and are
   * sanitized by the container.
   * @member opensocial.Message.Field
   */
  BODY : 'body'
};


/**
 * @static
 * @class
 * The types of messages that can be sent.
 *
 * @name opensocial.Message.Type
 */
opensocial.Message.Type = {
  /**
   * An email.
   *
   * @member opensocial.Message.Type
   */
  EMAIL : 'email',

  /**
   * A short private message.
   *
   * @member opensocial.Message.Type
   */
  NOTIFICATION : 'notification',

  /**
   * A message to a specific user that can be seen only by that user.
   *
   * @member opensocial.Message.Type
   */
  PRIVATE_MESSAGE : 'privateMessage',

  /**
   * A message to a specific user that can be seen by more than that user.
   * @member opensocial.Message.Type
   */
  PUBLIC_MESSAGE : 'publicMessage'
};


/**
 * Gets the message data that's associated with the specified key.
 *
 * @param {String} key The key to get data for;
 *   see the <a href="opensocial.Message.Field.html">Field</a> class
 * for possible values
 * @return {String} The data
 * @member opensocial.Message
 */
opensocial.Message.prototype.getField = function(key) {
  return this.fields_[key];
};


/**
 * Sets data for this message associated with the given key.
 *
 * @param {String} key The key to set data for
 * @param {String} data The data to set
 */
opensocial.Message.prototype.setField = function(key, data) {
  return this.fields_[key] = data;
};



/************** end message.js ********************/

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * @fileoverview Representation of an name.
 */


/**
 * @class
 * Base interface for all name objects.
 *
 * @name opensocial.Name
 */


/**
 * Base interface for all name objects.
 *
 * @private
 * @constructor
 */
opensocial.Name = function(opt_params) {
  this.fields_ = opt_params || {};
};


/**
 * @static
 * @class
 * All of the fields that a name has. These are the supported keys for the
 * <a href="opensocial.Name.html#getField">Name.getField()</a> method.
 *
 * @name opensocial.Name.Field
 */
opensocial.Name.Field = {
  /**
   * The family name. Specified as a String.
   *
   * @member opensocial.Name.Field
   */
  FAMILY_NAME : 'familyName',

  /**
   * The given name. Specified as a String.
   *
   * @member opensocial.Name.Field
   */
  GIVEN_NAME : 'givenName',

  /**
   * The additional name. Specified as a String.
   *
   * @member opensocial.Name.Field
   */
  ADDITIONAL_NAME : 'additionalName',

  /**
   * The honorific prefix. Specified as a String.
   *
   * @member opensocial.Name.Field
   */
  HONORIFIC_PREFIX : 'honorificPrefix',

  /**
   * The honorific suffix. Specified as a String.
   *
   * @member opensocial.Name.Field
   */
  HONORIFIC_SUFFIX : 'honorificSuffix',

  /**
   * The unstructured name. Specified as a String.
   *
   * @member opensocial.Name.Field
   */
  UNSTRUCTURED : 'unstructured'
};


/**
 * Gets data for this name that is associated with the specified key.
 *
 * @param {String} key The key to get data for;
 *    keys are defined in <a href="opensocial.Name.Field.html"><code>
 *    Name.Field</code></a>
 * @return {String} The data
 */
opensocial.Name.prototype.getField = function(key) {
  return this.fields_[key];
};



/************** end name.js ********************/

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * @fileoverview Representation of a organization.
 */


/**
 * @class
 * Base interface for all organization objects.
 *
 * @name opensocial.Organization
 */


/**
 * Base interface for all organization objects.
 *
 * @private
 * @constructor
 */
opensocial.Organization = function(opt_params) {
  this.fields_ = opt_params || {};
};


/**
 * @static
 * @class
 * All of the fields that a organization has. These are the supported keys for
 * the <a href="opensocial.Organization.html#getField">
 * Organization.getField()</a> method.
 *
 * @name opensocial.Organization.Field
 */
opensocial.Organization.Field = {
  /**
   * The name of the organization. For example, could be a school name or a job
   * company. Specified as a string.
   * Not supported by all containers.
   * @member opensocial.Organization.Field
   */
  NAME : 'name',

  /**
   * The title or role the person has in the organization, specified as a
   * string. This could be graduate student, or software engineer.
   * Not supported by all containers.
   * @member opensocial.Organization.Field
   */
  TITLE : 'title',

  /**
   * A description or notes about the person's work in the organization,
   * specified as a string. This could be the courses taken by a student, or a
   * more detailed description about a Organization role.
   * Not supported by all containers.
   * @member opensocial.Organization.Field
   */
  DESCRIPTION : 'description',

  /**
   * The field the organization is in, specified as a string. This could be the
   * degree pursued if the organization is a school.
   * Not supported by all containers.
   * @member opensocial.Organization.Field
   */
  FIELD : 'field',

  /**
   * The subfield the Organization is in, specified as a string.
   * Not supported by all containers.
   * @member opensocial.Organization.Field
   */
  SUB_FIELD : 'subField',

  /**
   * The date the person started at the organization, specified as a Date.
   * Not supported by all containers.
   * @member opensocial.Organization.Field
   */
  START_DATE : 'startDate',

  /**
   * The date the person stopped at the organization, specified as a Date.
   * A null date indicates that the person is still involved with the
   * organization.
   * Not supported by all containers.
   * @member opensocial.Organization.Field
   */
  END_DATE : 'endDate',

 /**
   * The salary the person receieves from the organization, specified as a
   * string.
   * Not supported by all containers.
   * @member opensocial.Organization.Field
   */
  SALARY : 'salary',

 /**
   * The address of the organization, specified as an opensocial.Address.
   * Not supported by all containers.
   * @member opensocial.Organization.Field
   */
  ADDRESS : 'address',

 /**
   * A webpage related to the organization, specified as a string.
   * Not supported by all containers.
   * @member opensocial.Organization.Field
   */
  WEBPAGE : 'webpage'
};


/**
 * Gets data for this body type that is associated with the specified key.
 *
 * @param {String} key The key to get data for;
 *    keys are defined in <a href="opensocial.Organization.Field.html"><code>
 *    Organization.Field</code></a>
 * @return {String} The data
 */
opensocial.Organization.prototype.getField = function(key) {
  return this.fields_[key];
};



/************** end organization.js ********************/

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * @fileoverview Representation of a person.
 */


/**
 * @class
 * Base interface for all person objects.
 *
 * @name opensocial.Person
 */


/**
 * Base interface for all person objects.
 *
 * @private
 * @constructor
 */
opensocial.Person = function(opt_params, opt_isOwner, opt_isViewer) {
  this.fields_ = opt_params || {};
  this.isOwner_ = opt_isOwner;
  this.isViewer_ = opt_isViewer;
};


/**
 * @static
 * @class
 * All of the fields that a person has. These are the supported keys for the
 * <a href="opensocial.Person.html#getField">Person.getField()</a> method.
 *
 * @name opensocial.Person.Field
 */
opensocial.Person.Field = {
  /**
   * A string ID that can be permanently associated with this person.
   * @member opensocial.Person.Field
   */
  ID : 'id',

  /**
   * A opensocial.Name object containing the person's name.
   * @member opensocial.Person.Field
   */
  NAME : 'name',

  /**
   * A String representing the person's nickname.
   * @member opensocial.Person.Field
   */
  NICKNAME : 'nickname',

  /**
   * Person's photo thumbnail URL, specified as a String.
   * This URL must be fully qualified. Relative URLs will not work in gadgets.
   * @member opensocial.Person.Field
   */
  THUMBNAIL_URL : 'thumbnailUrl',

  /**
   * Person's profile URL, specified as a String.
   * This URL must be fully qualified. Relative URLs will not work in gadgets.
   * Not supported by all containers.
   * @member opensocial.Person.Field
   */
  PROFILE_URL : 'profileUrl',

  /**
   * Person's current location, specified as an
   * <a href="opensocial.Address.html">Address</a>.
   * Not supported by all containers.
   * @member opensocial.Person.Field
   */
  CURRENT_LOCATION : 'currentLocation',

  /**
   * Addresses associated with the person, specified as an Array of
   * <a href="opensocial.Address.html">Address</a>es.
   * Not supported by all containers.
   * @member opensocial.Person.Field
   */
  ADDRESSES : 'addresses',

  /**
   * Emails associated with the person, specified as an Array of
   * <a href="opensocial.Email.html">Email</a>s.
   * Not supported by all containers.
   * @member opensocial.Person.Field
   */
  EMAILS : 'emails',

  /**
   * Phone numbers associated with the person, specified as an Array of
   * <a href="opensocial.Phone.html">Phone</a>s.
   * Not supported by all containers.
   * @member opensocial.Person.Field
   */
  PHONE_NUMBERS : 'phoneNumbers',

  /**
   * A general statement about the person, specified as a String.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  ABOUT_ME : 'aboutMe',

  /**
   * Person's status, headline or shoutout, specified as a String.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  STATUS : 'status',

  /**
   * Person's profile song, specified as an opensocial.Url.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  PROFILE_SONG : 'profileSong',

  /**
   * Person's profile video, specified as an opensocial.Url.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  PROFILE_VIDEO : 'profileVideo',

  /**
   * Person's gender, specified as an opensocial.Enum with the enum's
   * key referencing opensocial.Enum.Gender.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  GENDER : 'gender',

  /**
   * Person's sexual orientation, specified as a String.
   * Not supported by all containers.
   * @member opensocial.Person.Field
   */
  SEXUAL_ORIENTATION : 'sexualOrientation',

  /**
   * Person's relationship status, specified as a String.
   * Not supported by all containers.
   * @member opensocial.Person.Field
   */
  RELATIONSHIP_STATUS : 'relationshipStatus',

  /**
   * Person's age, specified as a number.
   * Not supported by all containers.
   * @member opensocial.Person.Field
   */
  AGE : 'age',

  /**
   * Person's date of birth, specified as a Date object.
   * Not supported by all containers.
   * @member opensocial.Person.Field
   */
  DATE_OF_BIRTH : 'dateOfBirth',

  /**
   * Person's body characteristics, specified as an opensocial.BodyType.
   * Not supported by all containers.
   * @member opensocial.Person.Field
   */
  BODY_TYPE : 'bodyType',

  /**
   * Person's ethnicity, specified as a String.
   * Not supported by all containers.
   * @member opensocial.Person.Field
   */
  ETHNICITY : 'ethnicity',

  /**
   * Person's smoking status, specified as an opensocial.Enum with the enum's
   * key referencing opensocial.Enum.Smoker.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  SMOKER : 'smoker',

  /**
   * Person's drinking status, specified as an opensocial.Enum with the enum's
   * key referencing opensocial.Enum.Drinker.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  DRINKER : 'drinker',

  /**
   * Description of the person's children, specified as a String.
   * Not supported by all containers.
   * @member opensocial.Person.Field
   */
  CHILDREN : 'children',

  /**
   * Description of the person's pets, specified as a String.
   * Not supported by all containers.
   * @member opensocial.Person.Field
   */
  PETS : 'pets',

  /**
   * Description of the person's living arrangement, specified as a String.
   * Not supported by all containers.
   * @member opensocial.Person.Field
   */
  LIVING_ARRANGEMENT : 'livingArrangement',

  /**
   * Person's time zone, specified as the difference in minutes between
   * Greenwich Mean Time (GMT) and the user's local time. See
   * Date.getTimezoneOffset() in javascript for more details on this format.
   * Not supported by all containers.
   * @member opensocial.Person.Field
   */
  TIME_ZONE : 'timeZone',

  /**
   * List of the languages that the person speaks as ISO 639-1 codes,
   * specified as an Array of Strings.
   * Not supported by all containers.
   * @member opensocial.Person.Field
   */
  LANGUAGES_SPOKEN : 'languagesSpoken',

  /**
   * Jobs the person has held, specified as an Array of
   * <a href="opensocial.Organization.html">Organization</a>s.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  JOBS : 'jobs',

  /**
   * Person's favorite jobs, or job interests and skills, specified as a String.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  JOB_INTERESTS : 'jobInterests',

  /**
   * Schools the person has attended, specified as an Array of
   * <a href="opensocial.Organization.html">Organization</a>s.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  SCHOOLS : 'schools',

  /**
   * Person's interests, hobbies or passions, specified as an Array of Strings.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  INTERESTS : 'interests',

  /**
   * URLs related to the person, their webpages, or feeds. Specified as an
   * Array of opensocial.Url.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  URLS : 'urls',

  /**
   * Person's favorite music, specified as an Array of Strings.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  MUSIC : 'music',

  /**
   * Person's favorite movies, specified as an Array of Strings.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  MOVIES : 'movies',

  /**
   * Person's favorite TV shows, specified as an Array of Strings.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  TV_SHOWS : 'tvShows',

  /**
   * Person's favorite books, specified as an Array of Strings.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  BOOKS : 'books',

  /**
   * Person's favorite activities, specified as an Array of Strings.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  ACTIVITIES : 'activities',

  /**
   * Person's favorite sports, specified as an Array of Strings.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  SPORTS : 'sports',

  /**
   * Person's favorite heroes, specified as an Array of Strings.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  HEROES : 'heroes',

  /**
   * Person's favorite quotes, specified as an Array of Strings.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  QUOTES : 'quotes',

  /**
   * Person's favorite cars, specified as an Array of Strings.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  CARS : 'cars',

  /**
   * Person's favorite food, specified as an Array of Strings.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  FOOD : 'food',

  /**
   * Person's turn ons, specified as an Array of Strings.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  TURN_ONS : 'turnOns',

  /**
   * Person's turn offs, specified as an Array of Strings.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  TURN_OFFS : 'turnOffs',

  /**
   * Arbitrary tags about the person, specified as an Array of Strings.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  TAGS : 'tags',

  /**
   * Person's comments about romance, specified as a String.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  ROMANCE : 'romance',

  /**
   * What the person is scared of, specified as a String.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  SCARED_OF : 'scaredOf',

  /**
   * Describes when the person is happiest, specified as a String.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  HAPPIEST_WHEN : 'happiestWhen',

  /**
   * Person's thoughts on fashion, specified as a String.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  FASHION : 'fashion',

  /**
   * Person's thoughts on humor, specified as a String.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  HUMOR : 'humor',

  /**
   * Person's statement about who or what they are looking for, or what they are
   * interested in meeting people for. Specified as a String.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  LOOKING_FOR : 'lookingFor',

  /**
   * Person's relgion or religious views, specified as a String.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  RELIGION : 'religion',

  /**
   * Person's political views, specified as a String.
   * Not supported by all containers.
   *
   * @member opensocial.Person.Field
   */
  POLITICAL_VIEWS : 'politicalViews'
};


/**
 * Gets an ID that can be permanently associated with this person.
 *
 * @return {String} The ID
 */
opensocial.Person.prototype.getId = function() {
  return this.getField(opensocial.Person.Field.ID);
};


var ORDERED_NAME_FIELDS_ = [
    opensocial.Name.Field.HONORIFIC_PREFIX,
    opensocial.Name.Field.GIVEN_NAME,
    opensocial.Name.Field.FAMILY_NAME,
    opensocial.Name.Field.HONORIFIC_SUFFIX,
    opensocial.Name.Field.ADDITIONAL_NAME];

/**
 * Gets a text display name for this person; guaranteed to return
 * a useful string.
 *
 * @return {String} The display name
 */
opensocial.Person.prototype.getDisplayName = function() {
  var name = this.getField(opensocial.Person.Field.NAME);
  if (name) {
    // Try unstructured field first
    var unstructured = name.getField(opensocial.Name.Field.UNSTRUCTURED);
    if (unstructured) {
      return unstructured;
    }

    // Next try to construct the name from the individual components
    var fullName = '';
    for (var i = 0; i < ORDERED_NAME_FIELDS_.length; i++) {
      var nameValue = name.getField(ORDERED_NAME_FIELDS_[i]);
      if (nameValue) {
        fullName += nameValue + ' ';
      }
    }
    return fullName.replace(/^\s+|\s+$/g, '') ;
  }

  // Finally, try the nickname field
  return this.getField(opensocial.Person.Field.NICKNAME);
};


/**
 * Gets data for this person that is associated with the specified key.
 *
 * @param {String} key The key to get data for;
 *    keys are defined in <a href="opensocial.Person.Field.html"><code>
 *    Person.Field</code></a>
 * @return {String} The data
 */
opensocial.Person.prototype.getField = function(key) {
  return this.fields_[key];
};


/**
 * Returns true if this person object represents the currently logged in user.
 *
 * @return {Boolean} True if this is the currently logged in user;
 *   otherwise, false
 */
opensocial.Person.prototype.isViewer = function() {
  return !!this.isViewer_;
};


/**
 * Returns true if this person object represents the owner of the current page.
 *
 * @return {Boolean} True if this is the owner of the page;
 *   otherwise, false
 */
opensocial.Person.prototype.isOwner = function() {
  return !!this.isOwner_;
};



/************** end person.js ********************/

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * @fileoverview Representation of an phone number.
 */


/**
 * @class
 * Base interface for all phone objects.
 *
 * @name opensocial.Phone
 */


/**
 * Base interface for all phone objects.
 *
 * @private
 * @constructor
 */
opensocial.Phone = function(opt_params) {
  this.fields_ = opt_params || {};
};


/**
 * @static
 * @class
 * All of the fields that a phone has. These are the supported keys for the
 * <a href="opensocial.Phone.html#getField">Phone.getField()</a> method.
 *
 * @name opensocial.Phone.Field
 */
opensocial.Phone.Field = {
  /**
   * The phone number type or label, specified as a String.
   * Examples: work, my favorite store, my house, etc.
   *
   * @member opensocial.Phone.Field
   */
  TYPE : 'type',

  /**
   * The phone number, specified as a String.
   *
   * @member opensocial.Phone.Field
   */
  NUMBER : 'number'
};


/**
 * Gets data for this phone that is associated with the specified key.
 *
 * @param {String} key The key to get data for;
 *    keys are defined in <a href="opensocial.Phone.Field.html"><code>
 *    Phone.Field</code></a>
 * @return {String} The data
 */
opensocial.Phone.prototype.getField = function(key) {
  return this.fields_[key];
};



/************** end phone.js ********************/

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * @fileoverview ResponseItem containing information about a specific response
 * from the server.
 */


/**
 * @class
 * Represents a response that was generated
 * by processing a data request item on the server.
 *
 * @name opensocial.ResponseItem
 */


/**
 * Represents a response that was generated by processing a data request item
 * on the server.
 *
 * @private
 * @constructor
 */
opensocial.ResponseItem = function(originalDataRequest, data,
    opt_errorCode, opt_errorMessage) {
  this.originalDataRequest_ = originalDataRequest;
  this.data_ = data;
  this.errorCode_ = opt_errorCode;
  this.errorMessage_ = opt_errorMessage;
};


/**
 * Returns true if there was an error in fetching this data from the server.
 *
 * @return {Boolean} True if there was an error; otherwise, false
 */
opensocial.ResponseItem.prototype.hadError = function() {
  return !!this.errorCode_;
};


/**
 * @static
 * @class
 *
 * Error codes that a response item can return.
 *
 * @name opensocial.ResponseItem.Error
 */
opensocial.ResponseItem.Error = {
  /**
   * This container does not support the request that was made.
   *
   * @member opensocial.ResponseItem.Error
   */
  NOT_IMPLEMENTED : 'notImplemented',

  /**
   * The gadget does not have access to the requested data.
   * To get access, use
   * <a href="opensocial.html#requestPermission">
   * opensocial.requestPermission()</a>.
   *
   * @member opensocial.ResponseItem.Error
   */
  UNAUTHORIZED : 'unauthorized',

  /**
   * The gadget can never have access to the requested data.
   *
   * @member opensocial.ResponseItem.Error
   */
  FORBIDDEN : 'forbidden',

   /**
   * The request was invalid. Example: 'max' was -1.
   *
   * @member opensocial.ResponseItem.Error
   */
  BAD_REQUEST : 'badRequest',

  /**
   * The request encountered an unexpected condition that
   * prevented it from fulfilling the request.
   *
   * @member opensocial.ResponseItem.Error
   */
  INTERNAL_ERROR : 'internalError'
};


/**
 * If the request had an error, returns the error code.
 * The error code can be container-specific
 * or one of the values defined by
 * <a href="opensocial.ResponseItem.Error.html"><code>Error</code></a>.
 *
 * @return {String} The error code, or null if no error occurred
 */
opensocial.ResponseItem.prototype.getErrorCode = function() {
  return this.errorCode_;
};


/**
 * If the request had an error, returns the error message.
 *
 * @return {String} A human-readable description of the error that occurred;
 *    can be null, even if an error occurred
 */
opensocial.ResponseItem.prototype.getErrorMessage = function() {
  return this.errorMessage_;
};


/**
 * Returns the original data request.
 *
 * @return {opensocial.DataRequest} The data request used to fetch this data
 *    response
 */
opensocial.ResponseItem.prototype.getOriginalDataRequest = function() {
  return this.originalDataRequest_;
};


/**
 * Gets the response data.
 *
 * @return {Object} The requested value calculated by the server; the type of
 *    this value is defined by the type of request that was made
 */
opensocial.ResponseItem.prototype.getData = function() {
  return this.data_;
};



/************** end responseitem.js ********************/

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * @fileoverview Representation of an url.
 */


/**
 * @class
 * Base interface for all URL objects.
 *
 * @name opensocial.Url
 */


/**
 * Base interface for all url objects.
 *
 * @private
 * @constructor
 */
opensocial.Url = function(opt_params) {
  this.fields_ = opt_params || {};
};


/**
 * @static
 * @class
 * All of the fields that a url has. These are the supported keys for the
 * <a href="opensocial.Url.html#getField">Url.getField()</a> method.
 *
 * @name opensocial.Url.Field
 */
opensocial.Url.Field = {
  /**
   * The url number type or label. Examples: work, blog feed,
   * website, etc Specified as a String.
   *
   * @member opensocial.Url.Field
   */
  TYPE : 'type',

  /**
   * The text of the link. Specified as a String.
   *
   * @member opensocial.Url.Field
   */
  LINK_TEXT : 'linkText',

  /**
   * The address the url points to. Specified as a String.
   *
   * @member opensocial.Url.Field
   */
  ADDRESS : 'address'
};


/**
 * Gets data for this URL that is associated with the specified key.
 *
 * @param {String} key The key to get data for;
 *    keys are defined in <a href="opensocial.Url.Field.html"><code>
 *    Url.Field</code></a>
 * @return {String} The data
 */
opensocial.Url.prototype.getField = function(key) {
  return this.fields_[key];
};



/************** end url.js ********************/