/**
 * This class serves as the superclass for all xml-http request objects supported by
 * the <code>Environment</code>.  
 * <br><br>
 * <b>Important Notes:</b>
 * <ul>
 * <li>
 * In order to obtain a new <code>XmlHttpRequest</code> object for the platform
 * on which your application is running, do not directly create an object from classes that 
 * extend this object. directly.  Instead,
 * call the static method <code>self.Environment.getNewXmlHttpRequest</code>. 
 * </li>
 * <li>
 * Modify the method <code>Environment_init_getXmlHttpConstructor</code> (an inner method 
 * of the <code>init</code> method of the <code>Environment</code> object) to support
 * any new classes that extend this class (<code>AbstractXmlHttpRequest</code>).
 * </li>
 * <li>
 * In order to send a message, do not create a new <code>XmlHttpRequest</code> object.  Instead,
 * call the <code>send</code> method on an object of the <code>Messenger</code> datatype.
 * </li>
 * </ul>
 * <br>
 * This class serves to augment the standard <code>XmlHttpRequest</code>
 * object that is built-in to some web browsers.  It adds an i.d. and 
 * a unique <code>onreadystatechange</code> 
 * event handler method.  While 
 * this class hiearchy gives great flexibility, please note that it is actually 
 * necessitated by the immutability of the XmlHttpRequest object from
 * Microsoft(tm), which is an 'ActiveX' object.  Otherwise, we could add the properties we
 * need with a simple augmentor-method.
 * <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: AbstractXmlHttpRequest.js,v 1.5 2005/12/09 05:54:53 evedar Exp $    
 * <br>
 * @emits-event <code>onreadystatechange</code>  This event is emitted by the xml-http request object that is 
 *                                               held as a property of this object.  The event travels as 
 *                                               emitted from this object.
 * @class-prop <code>number</code> <code>intReadyState</code>  The integer value that signifies the completed 
 *                                 state of an asynchronous xml-http request.
 * @class-prop <code>number</code> <code>intUniqueNum</code>  This variable is used to create a unique serial 
 *                                 number for every object created from concrete classes of this class.
 * @object-prop <code>string</code> <code>strId</code>  The i.d. of the class.
 * @object-prop <code>number</code> <code>intSerialNumber</code> The serial number of a given object made from 
 *                                  this class.
 * @object-prop <code>string</code> <code>strRequestUri</code> The uri used by this request object. It is meant 
 *                       to point to a requested resource (for example, an xml file on a server).
 * @object-prop <code>string</code> <code>strMethod</code>  The http protocol method used to make the request.
 * @object-prop <code>boolean</code> <code>booAsynchronous</code>  Whether or not the request to be made should be
 *                                   asynchronous or not.
 * @object-prop <code>objXmlHttpRequest</code>  The xml-http request object held by instances of this class.
 * @author Team GigaToasted (Fall-2005-CMU-NASA/Google-Practicum Subteam) 
 * @version 1.0
 */

self.AbstractXmlHttpRequest.intReadyState = 4;
self.AbstractXmlHttpRequest.intUniqueNum = 0;

/**
 * Creates a new <code>AbstractXmlHttpRequest</code> object.
 */
function AbstractXmlHttpRequest() {
    // Properties:
    this.strId = "CrossBrowserXMLHttpRequest";
    this.intSerialNumber = -1;
    this.strRequestUri = "";
    this.strMethod = "get"; // Default value.
    this.booAsynchronous = true;  // Default value.
    
    // Methods:
    this.superC = AbstractXmlHttpRequest_superConstructor;
    this.send = AbstractXmlHttpRequest_send;
}


/**
 * Perform instance-specific initialization of the object instance made from the extending
 * class.    
 * <br><br><br>Details:<br><br>
 * In this method, we use <code>var</code> to capture the value of <code>strId<code> 
 * and <code>objXmlHttpRequest</code>
 * in the function closure <code>onreadystatechange<code>, below.  For some odd reason,
 * the <code>this</code> context does not work in the <code>onreadystatechange</code> method
 * (i.e., as it does work in dom event handlers).<br><br>
 * The <code>Messenger</code> object registers to listen to events from all objects of 
 * this type, so we give all objects the same <code>strId</code> value.  
 * @param pObjXmlHttpRequest <code>Object</code> The xml-http request object held by the instance.
 * @param pStrRequestUri <code>string</code> The uri pointing to the 
 *                       requested resource (for example, an xml file on a server).
 * @param pStrMethod <code>string</code> OPTIONAL, MAY BE <code>null</code> Either 'get' or 'post'. Defaults to
 *                   'get'.
 * @param pBooAsynchronous <code>boolean</code> OPTIONAL, MAY BE <code>null</code> Whether or
 *                          not the request is to be asynchronous.  Defaults to 'true'.
 */
function AbstractXmlHttpRequest_superConstructor(pObjXmlHttpRequest, pStrRequestUri, pStrMethod,  
                                                 pBooAsynchronous) {
    var objXmlHttpRequest = this.objXmlHttpRequest = pObjXmlHttpRequest, strId = this.strId,
        intArgs = arguments.length;

    this.intSerialNumber = self.AbstractXmlHttpRequest.intUniqueNum++;       

    this.strRequestUri = pStrRequestUri;
    
    if (intArgs > 2) {
        if (pStrMethod != null) {
            this.strMethod = pStrMethod;
        }
    }

    if (intArgs > 3) {
        if (pBooAsynchronous != null) {
            this.booAsynchronous = pBooAsynchronous;
        }
    }    

    this.objXmlHttpRequest.onreadystatechange = function() {
        if (objXmlHttpRequest.readyState == self.AbstractXmlHttpRequest.intReadyState) {
            self.Environment.handleEvent(strId, 'onreadystatechange', null);
        }
    }
}


/**
 * This convenience method opens and sends the xml-http request.
 * @param pObjMessage <code>Object</code>  MAY BE <code>null</code> This parameter is required by the XmlHttp 
 *                    object.
 */
function AbstractXmlHttpRequest_send(pObjMessage) {
    this.objXmlHttpRequest.open(this.strMethod, this.strRequestUri, this.booAsynchronous);
    this.objXmlHttpRequest.send(pObjMessage);
}
