// bea.wlp.disc.context
/*
 * B E A   S Y S T E M S
 *
 * Copyright (c) 2000-2008  BEA Systems, Inc.
 *
 * All Rights Reserved. Unpublished rights reserved under the copyright laws of the United States. The software
 * contained on this media is proprietary to and embodies the confidential technology of BEA Systems, Inc. The
 * possession or receipt of this information does not convey any right to disclose its contents, reproduce it, or use,
 * or license the use, for manufacture or sale, the information or anything described therein. Any use, disclosure, or
 * reproduction without BEA System's prior written permission is strictly prohibited.
 *
 * Any entity defined in this scope that is named with a leading underscore ('_') is reserved for internal use only.
 */

/**
 * @name bea.wlp.disc.context
 * @overview
 *      This module provides contextual information about the rendered Portal. When Disc is enabled for
 *      a Portal, instances of context classes are created as part of the Portal rendering process. These
 *      context classes provide information about individual Portal components such as Portlets, Pages,
 *      Layouts and Themes, as well as information about the relationship between these components. Context
 *      (i.e. instances of context objects) is provided only for visible Portal components. Information about
 *      non-visible components, such as books peer to the current book or hidden portlets, will not be
 *      available via context objects.
 *      <p/>
 *      A typical usage scenario may look something like the following:
 *      <pre>
 *          var portlet = bea.wlp.disc.context.Portlet.findByLabel("myPortlet");
 *          var title = portlet.getTitle();
 *          var mode = portlet.getWindowMode();
 *          var page = portlet.getParentPage();
 *      </pre>
 *      <p/>
 *      Disc context classes are loosely representative of server-side PresentationContext classes and
 *      generally provide similar functionality for use in client-side code. Like server-side PresentationContext
 *      objects, the lifecycle of Disc context objects is managed by Portal and application code should generally
 *      not attempt to create or destroy such objects. Furthermore, Disc context objects should be considered
 *      immutable; functions and/or properties should not be added, and existing properties should not be
 *      accessed or manipulated except via the provided APIs.
 *      <p/>
 *      In addition to creating instances of Disc context objects, enabling Disc also causes Portal to render
 *      HTML containers around standard Portal components. This container is a single HTML Element containing
 *      all markup for the corresponding component and is sometimes referred to as the "context hook".
 *      Like the context objects, the context container element itself should be considered immutable; attributes,
 *      styling, event handlers, or other similar functionality and data should not be added to the container
 *      element. Furthermore, the context container element should be considered opaque; no meaning should
 *      be inferred from the element name, individual attributes/properties or their values. All such information
 *      is subject to change without notice. The only supported operations on context container elements are
 *      standard DOM mechanisms to retrieve the container's children. Most context objects support a method
 *      to retrieve the markup associated with the context's component, and this method will return a reference
 *      to the context container element. See the <code>getMarkupElement()</code> method for more information.
 *      <p/>
 *      Application code should not hold references to Disc context objects beyond the immediate use of such
 *      objects. Dynamic updates to the HTML page may make such references stale or invalid.
 *      <p/>
 *      Disc context objects are generally not available in a valid state until the entire HTML page has been
 *      loaded. Application code should not attempt to use context objects from inline script blocks, but should
 *      instead register an "onload" handler that encapsulates interaction with context objects. For example, the
 *      following code when placed inline in a portlet JSP will not behave as expected:
 *      <pre>
 *          var portlet = bea.wlp.disc.context.Portlet.findByLabel("myPortletLabel"); // portlet will be null
 *          var title = portlet.getTitle(); // error
 *      </pre>
 *      However, if we add the same code via a <a href="http://dojotoolkit.org/">Dojo</a> (for example) onload function,
 *      the code works as expected:
 *      <pre>
 *          dojo.addOnLoad(function() {
 *              var portlet = bea.wlp.disc.context.Portlet.findByLabel("myPortletLabel");
 *              var title = portlet.getTitle();
 *          });
 *      </pre>
 */
bea.wlp.disc.Module.create("bea.wlp.disc.context", {
    include: ["_Mixin", "Base", "Window", "Layout", "Other"],
    initialize: function($) {

        bea.wlp.disc._Object.each($,

            // action for each
            function(o) {

                // Add "static" type to each class constructor
                $[o].TYPE = o;

                // Add getType() method to each context object
                $[o].inject('getType', (function(type) {
                    return function() {
                        return type;
                    };
                })(o));

                // Add toString helper function for properties
                $[o].inject('_getProps', (function(ctor) {
                    return function() {
                        var props = this.sup ? this.sup() : {};
                        if (ctor._PROPS) {
                            for (var i = 0; i < ctor._PROPS.length; i++) {
                                var name = ctor._PROPS[i];
                                if (this._props && (this._props[name] != null)) {
                                    props[name] = this._props[name];
                                }
                            }
                        }
                        return props;
                    }
                })($[o]));

                // Create property getters for each context object
                if ($[o].hasOwnProperty('_PROPS')) {
                    var names = $[o]._PROPS;
                    for (var p = 0; p < names.length; p++) {
                        var getter = 'get' + names[p].substring(0, 1).toUpperCase() + names[p].substring(1);
                        $[o].inject(getter, (function(name) {
                            return function() {
                                return this._getPropValue(name);
                            };
                        })(names[p]));
                    }
                }

                // Apply static mixins
                if ($[o].hasOwnProperty('_MIXINS')) {
                    var mixins = $[o]._MIXINS;
                    for (var m = 0; m < mixins.length; m++) {
                        $[o].inject($._Mixin[mixins[m]]);
                    }
                }
            },

            // discriminator for each
            function(o) {
                return $[o]._BEA_WLP_DISC_CONTEXT;
            }
        );
    }
});
