/**
 * This file defines the AbstractWidget class. <br>
 * This class is the superclass of all widgets.
 * <br><br> 
 * <a href="mailto:ehudsons@andrew.cmu.edu">Ellen Hudson-Snyder</a>, 
 * <a href="mailto:evedar@andrew.cmu.edu">Elvin Vedar</a>,
 * <a href="mailto:cbalz@andrew.cmu.edu">Christopher M. Balz</a>.
 * <br><br>CVS Version Info:<br>
 *  $Id: AbstractWidget.js,v 1.8 2005/11/08 08:08:55 evedar Exp $
 * <br><br>
 * @class-prop <code>number</code> <code>intUniqueNum  A number that is incremented every time a widget is created,
 *                                 allowing the assignment of unique identification to any widget.
 * @class-prop <code>Object</code>  <code>hshWidgets</code>    A hash containing all instantiated widget objects,
 *                                  keyed by widget i.d.
 * @object-prop <code>Object</code>  <code>gloScope</code>  A cached reference to 'self.gloScope'.  This is cached
 *                                   for efficiency, to avoid having the JavaScript interpreter search the
 *                                   prototype chain for 'self.GloScope'.
 * @object-prop <code>string</code>  <code>strObjType</code>   The application type of objects made from this
 *                                   class.
 * @object-prop <code>string</code>  <code>strId</code>  The i.d. of the widget
 * @object-prop <code>Object</code>  <code>objParent</code>  A reference to the widget's parent widget.
 * @object-prop <code>string</code>  <code>strHtml</code>  The HTML that represents the widget object.
 * @object-prop <code>Array</code>  <code>arrData</code>  The data held by the widget.
 * @object-prop <code>Object</code>  <code>domRef</code>  The reference the widget holds to a given object in the
 *                                   web browser's document object model -- a dom object.
 * @object-prop <code>Array</code>  <code>arrDomRefs</code>  An array of references to given document object model 
 *                                  (dom) objects. 
 * @object-prop <code>Array</code>  <code>arrChildren</code>  An array of references to the widget's child widgets.
 * @author Team GigaToasted (Fall-2005-CMU-NASA/Google-Practicum Subteam) 
 * @version 1.0
 */


AbstractWidget.intUniqueNum = 0;


AbstractWidget.hshWidgets = {}; 

/**
 *  Create an AbstractWidget object. <br>
 *  See the constructor-helper-method, 'AbstractWidget_superConstructor', for the 
 *  object property assignments.
 */
function AbstractWidget() {
    this.strObjType = "widget";
    // Primitive properties and shared objects (see 'this.superC' for the rest):
    this.strId = "";
    this.strHtml = "";
    this.gloScope = self.gloScope; // Cache a reference for performance.
    // Methods:
    this.superC           = AbstractWidget_superConstructor;
    this.cleanDomRefs     = AbstractWidget_cleanDomRefs;
    this.setDomRef        = AbstractWidget_setDomRef;
    this.getDomRef        = AbstractWidget_getDomRef;    
    this.getHtml          = AbstractWidget_getHtml;
    this.getData          = AbstractWidget_getData;
    this.receiveEvent     = AbstractWidget_receiveEvent;
}


/**
 * Complete the job of making an abstract widget.<br>
 * This is the object-method superConstructor ('.superC') for this class.  
 * It is the segment of the class definition's constructor that 
 * bestows unique copies of objects upon inheriting classes, completing the job
 * of effectively simulating class-based inheritance in JavaScript.
 * @param strId  <code>string</code> The i.d. of the widget; must be the same as its dom object, if any.
 * @param objParent  <code>Object</code> The parent of the widget, if any.
 */
function AbstractWidget_superConstructor(strId, objParent) {
    this.strId = strId;
    AbstractWidget.intUniqueNum += 1; // Increment the static counter.   

    /*-
     * To support the event architecture, 
     * load all widgets into a hash upon their creation.
     */
    if (typeof AbstractWidget.hshWidgets[strId] != "undefined") {
        alert("Warning: creating a widget with a non-unique i.d.: " + strId);
    }
    AbstractWidget.hshWidgets[strId] = this; 

    // Other object assignments:
    this.domRef             = null;
    this.objParent          = null;
    this.objParent          = objParent;
    this.arrDomRefs         = [];
    this.arrData            = [];
    this.arrChildren        = [];
}



/**
 * This method caches a reference to the dom object managed by the 
 * widget.  
 */
function AbstractWidget_setDomRef() {
    this.domObj = window.document.getElementById(this.strId);
}



/**
 * This method either returns the cached reference to the dom object
 * managed by the widget, initializing the reference if it is null.
 * @return <code>Object</code>  A reference to a dom object
 */
function AbstractWidget_getDomRef() {
    if (this.domObj == null) {
        this.setDomRef();
    }
    return this.domObj;
}


/**
 * Return the (non-presentation) data of this widget.  
 * @return <code>Array</code>  The array of data elements managed by this widget.
 */
function AbstractWidget_getData() {
    return this.arrData;
}



/**
 * Return the HTML of the object managed by the widget and its child widgets.    
 * @return <code>string</code>  A string representing the HTML of the  object managed by the widget and its child
 *                              widgets.
 */
function AbstractWidget_getHtml() {
    return this.strHtml;
}


/**
 * This method receives any broadcast events from the event architecture.<br><br>
 * See the JavaScriptDoc on 'GloScope.handleEvent' 
 * for details on the event architecture.
 * <br><br>
 * @param pStrEventSourceElementId  <code>string</code> The i.d. of the element that emitted the event.
 * @param pStrEventType  <code>string</code> The type of event.
 * @param pObjEvent  <code>Object</code> The actual event object.
 */
function AbstractWidget_receiveEvent(pStrEventSourceElementId, pStrEventType, pObjEvent) {
    alert("Widget '" + this.strId + "' received event of type '" + pStrEventType + "' from '" + 
          pStrEventSourceElementId);
}


/**
 * Set all references to the dom to null.  This is important
 * so that the user's browser may free memory taken up by the 
 * application's use of the dom.
 */
function AbstractWidget_cleanDomRefs() { 
    this.domRef = null;
    this.arrDomRefs = null; // Set widgets have this property.
}


