/**
 * This class serves as the container for all non-application-specific infrastructure for the application.  
 * <br><br>--------<br>
 * <b>Special Note:</b> 
 * At the end of this file, an important assignment is made. 
 * Through this assignment of an anonymous function 
 * to the <code>window.onload</code> event handler,
 * the <code>Environment</code> object itself is created when the 
 * application and its associated files have fully loaded on the client 
 * (web browser).
 * <br>--------<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: Environment.js,v 1.16 2005/12/09 05:54:53 evedar Exp $    
 * @object-prop: <code>gloScope</code>  A cached reference to <code>self.GloScope</code>.  This is cached 
 *                                      for efficiency, to avoid having the JavaScript interpreter search 
 *                                      the prototype chain for <code>self.GloScope</code>.
 * @class-prop: <code>objXmlHttpRequest</code>  A customized xml-http request object.  
 *                                              Use this object to perform all client-server communications. 
 * @class-prop: <code>CrossBrowserXmlHttpRequest</code>  A copy of the constructor to create an xml-http 
 *                                                       request object on any platform.  The 
 *                                                       <code>self.Environment.getNewXmlHttpRequest</code> convenience
 *                                                       method may be called in order to get a new
 *                                                       <code>XmlHttpRequest</code> object for the current platform.
 * @class-prop <code>priObjIs</code>  An object that tells us what the platform (machine/operating 
 *                                 system/web browser) <b>is</b> that we are running on.  It should be accessed 
 *                                 from <code>self.gloScope</code> or references to that object, since it represents 
 *                                 platform-specific information as 
 *                                 opposed to the core infrastructure for the application.  
 * @class-method: <code>handleEvent</code>   Handle events of interest to the application.
 * @class-method: <code>getNewXmlHttpRequest</code>  Returns a new xml-http request object.
 * @author Team GigaToasted (Fall-2005-CMU-NASA/Google-Practicum Subteam) 
 * @version 1.0
 */

self.Environment.priObjIs = null;

self.Environment.handleEvent = Environment_handleEvent;
self.Environment.CrossBrowserXmlHttpRequest = null;
self.Environment.getNewXmlHttpRequest = Environment_getNewXmlHttpRequest;

/**
 * Create an <code>Environment</code> object.  This object represents the
 * customized, application-agnostic environment that the 
 * implemented JavaScript application runs in.  It does *not* represent the machine/operating sytem/browser
 * platform that the application is running on.  Rather, it is a container for all that is specific to
 * support of the implemented JavaScript application, such as event handling and the setting of 
 * any variables that are global to the application.
 */
function Environment() {
    this.init = Environment_init;
    this.init();
}


/**
 * This method broadcasts events to all interested objects.  See the JavaScriptDoc on 'GloScope.handleEvent' 
 * for details on the event architecture.
 * @param pStrEventSourceElementId  <code>string</code>  The i.d. of the document object model element, or an equivalent object
 *                                          (such as a custom js object that manages other, true dom objects)
 *                                          from which the event will come.
 * @param pStrEventType <code>string</code>  The type of event to be broadcast.
 * @param pObjEvent  <code>object</code>  The actual event object, if any (may safely be <code>null</code>).
 * @return <code>true</code>  <code>boolean</code>  This is important to allow any document object model events 
 *                                                 to continue to 'live'.
 *                                     Note that a custom event handler on a document object model (dom) element
 *                                     may still return <code>false</code> if the dom effects and further dom life of the 
 *                                     event is to be cancelled.
 */
function Environment_handleEvent(pStrEventSourceElementId, pStrEventType, pObjEvent) {
    var objNode = self.GloScope.hshListenerRegistry[ pStrEventSourceElementId ][ pStrEventType ].objListeners.objHead,
        objListener;

    do {
        objListener = objNode.anyData;
        objListener.receiveEvent(pStrEventSourceElementId, pStrEventType, pObjEvent);
        objNode = objNode.objNext;
    } while (objNode);
    return true;
}


/**
 * This static method creates a mew xml-http request object on any supportive web browser.
 * @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'.
 * @param pBooAsynchronous <code>boolean</code> OPTIONAL, MAY BE <code>null</code> Whether or
 *                          not the request is to be asynchronous.
 * @returns <code>object</code>  A mew xml-http request object.
 */
function Environment_getNewXmlHttpRequest(pStrRequestUri, pStrMethod, pBooAsynchronous) { 
    return new self.Environment.CrossBrowserXmlHttpRequest(pStrRequestUri, pStrMethod, pBooAsynchronous); 
}


/**
 * This method initializes the custom JavaScript environment in which the 
 * application will run.  This eventually creates the specific application controller object.
 */
function Environment_init() {
    self.Environment.priObjIs = new Is();
    this.gloScope = self.gloScope; 
    
    /**
     * This inner method sets the constructor for creating the xml-http 
     * communications object on any platform.  Although the translation into object-oriented 
     * format is unique to the Gigapan Explorer application, parts of this method code were
     * used, with permission, from Wrox, Inc. (http://wrox.com).
     * 
     * @return <code>function</code>  An xml-http object constructor.  Note that the specific type of the object
     *                                created varies across platforms.
     */
     function Environment_init_getXmlHttpConstructor() {

         // Deal with possibility of Microsoft(tm) platform and its requirements for 'xml-http':
         if (self.Environment.priObjIs.ie && !window.ActiveXObject) {
                 alert("ActiveX is not installed on your system and Gigapan cannot properly initalize. " +
                       " \n\n To avoid this problem, you can install ActiveX or you can use the Firefox " +
                       "web browser from \n http://mozilla.org instead of the web browser " + 
                       " that you are currently using.");               
                 return (function() { alert("Gigapan has not properly initialized.  Try the Firefox " + 
                                            "browser from Mozilla.org or install ActiveX to avoid this problem."); 
                 });
         } else if (typeof XMLHttpRequest == "undefined") {                              
             var arrSignatures = [ "MSXML2.XMLHTTP.5.0", "MSXML2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", 
                                   "MSXML2.XMLHTTP", "Microsoft.XMLHTTP" ];
             
             for (var i=0; i < arrSignatures.length; i++) {
                 try {                         
                     new ActiveXObject(arrSignatures[i]); // This will either work or throw an exception.  
                     MSXmlHttpRequest.strSignature = arrSignatures[i];
                     return MSXmlHttpRequest;  // Return that closure as the constructor to use.                         
                 } catch (oError) {
                     // Ignore; try the next signature.
                 }
             }                           
             alert("MSXML is not installed on your system and Gigapan cannot properly initalize. " +
                   " \n\n To avoid this problem, you could use the Firefox " +
                   "web browser from \n http://mozilla.org instead of the web browser " + 
                   " that you are currently using.");               
         }
         
         // Don't have to deal with Microsoft(tm) platform and requirements for 'xml-http':
         return StandardXmlHttpRequest;         
     }

     self.Environment.CrossBrowserXmlHttpRequest = Environment_init_getXmlHttpConstructor();
     /*-
      * We lose the prototype chain from the above return if we do not "reset" it here.
      * This is because functions are passed by value, not by reference.  This only happens
      * at the initialization of the application, so the performance impact is insignificant.
      */
     self.Environment.CrossBrowserXmlHttpRequest.prototype = new AbstractXmlHttpRequest();

     this.gloScope.init(self.Environment.priObjIs);
}


// See notes above, in file header JavaScriptDoc:
window.onload = function() { 
    new Environment(); 
};
