/**
 * This class manages an absolutely-positioned rectangle in Gigapan Explorer
 * application that contains an html image element.  This image element is 
 * wrapped with an html <code>div</code> element, which contains an optional html <code>div</code> element.
 * This optional html <code>div</code> element holds the i.d. of the <code>ImageLayer</code> custom 
 * JavaScript image object.  It may be turned on or off by the property, 
 * <code>booTurnOnImageIds</code>.  Turn this property
 * off for production builds.
 * <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: AbstractImageLayer.js,v 1.19 2005/12/27 01:05:21 cbalz Exp $  
 * <br><br>
 * @inherits-from <code>AbstractWidget</code>  
 * @class-prop <code>INT_MAX_RELOAD_TRIES</code> The maximum number of times that an 'AbstractImageLayer' 
 *                                               type object will attempt to reload an image.
 * @object-prop <code>intNumReloadTries</code>  The maximum number of times that the current 'AbstractImageLayer' 
 *                                              type object has attempted to reload an image.
 * @object-prop <code>string</code>  <code>strImageSrc</code>  The url location of the image managed by this
 *                                   widget.
 * @object-prop <code>number</code>  <code>intZIndex</code>  The css stacking order of the image.  
 * @author Team GigaToasted (Fall-2005-CMU-NASA/Google-Practicum Subteam) 
 * @version 1.0
 * <br><br>
 */ 

// Set the prototype chain for efficient inheritance:
AbstractImageLayer.prototype = new AbstractWidget();
AbstractImageLayer.INT_MAX_RELOAD_TRIES = 10;

/**
 * Create an  <code>AbstractImageLayer</code> object.
 * @param objParent <code>Object</code>  The parent, if any, of this object.
 */
function AbstractImageLayer(objParent) {
    this.superC("abstractImageLayer", objParent);

    this.strImageSrc = "";
    this.intZIndex = 0;
    this.intNumReloadTries = 0; 

    // Methods
    this.receiveEvent = AbstractImageLayer_receiveEvent;
    this.setImageSrc = AbstractImageLayer_setImageSrc;
    this.loadImage = AbstractImageLayer_loadImage;
    this.getHtml = AbstractImageLayer_getHtml;
    this.onabortoronerror = AbstractImageLayer_onabortoronerror;   
}


/**
 * This method forces a re-load of the image pointed to by the current image source
 * (<code>this.strImageSrc</code>) property into the image document object model object.
 * @param pObjEvent  The 'onabort' event emitted by the standard web browser.
 */
function AbstractImageLayer_onabortoronerror( pObjEvent ) {
    this.getDomRef().src = "";
    this.intNumReloadTries++;
    if ( this.intNumReloadTries == ( AbstractImageLayer.INT_MAX_RELOAD_TRIES - 1 ) ) {
        this.getDomRef().onabort = null;
        this.getDomRef().onerror = null;
    } 
    this.loadImage();
    return true;
}


/**
 * This method loads the image pointed to by the current image source
 * (<code>this.strImageSrc</code>) property into the image document object model object.
 */
function AbstractImageLayer_loadImage() {
    this.getDomRef().src = this.strImageSrc;
}


/**
 * Sets the image source, which is a url to the image binary.
 * @param pStrImageSrc <code>string</code> image of this ImageLayer
 */
function AbstractImageLayer_setImageSrc(pStrImageSrc) {
   this.strImageSrc  = pStrImageSrc;
}


/**
 * Return the HTML of the object managed by the <code>AbstractImageLayer</code> widget and its child widgets. 
 * @param <code>pObjSB</code>  A string buffer object where all the strings will be added
 */
function AbstractImageLayer_getHtml(pObjSB) {
    pObjSB.append( [ "<div id='", this.strId, "_container'  class='imagelayer' >",  
                       "<img id='", this.strId, "' src='", this.strImageSrc, "' class='image' ", 
                           " onabort='self.Environment.handleEvent(this.id, \"onabort\", null);'  ", 
                           " onerror='self.Environment.handleEvent(this.id, \"onerror\", null);'  ", " />" ] );
    if (this.booTurnOnImageIds) {
        pObjSB.append( [ "<div id='", this.strId, "_visibleId' class='imagelayer_visible_id' > ", 
                           "<span id='", this.strId, "_visibleId_left' class='imagelayer_visible_id_left'>", 
                             "<- Left Edge ", this.strId, "</span> <span id='", this.strId, 
                               "_visibleId_right' class='imagelayer_visible_id_right' > Rt. Edge ->", 
                            "</span></div>" ] 
        );
    }
    pObjSB.append( [ "</div>" ] );
}


/**
 * This method receives any events that this object listens to and 
 * routes them to the proper methods. 
 * @param pStrEventSourceElementId  <code>string</code> The i.d. of the document object model from which the
 *                                  event sprang.
 * @param pStrEventType  <code>string</code> The event type of the object (e.g., 'onclick', etc).
 * @param pObjEvent  <code>Object</code> The event object itself.
 */
function AbstractImageLayer_receiveEvent( pStrEventSourceElementId, pStrEventType, pObjEvent ) { 
    switch ( pStrEventType ) {
        case "onabort" : 
            this.onabortoronerror( pObjEvent );
            break;
        case "onerror" : 
            this.onabortoronerror( pObjEvent );
            break;
        default: 
            return true;
    }
}


