//------------------------------------------------------------------------------------------------
// JACL.js
// Copyright 2005: CodingMonk, LLC
// www.CodingMonk.com
// WebMaster@CodingMonk.com
//
// This javascript file is one part of a larger collection of javascript modules called
// CodingMonk's Javascript Application Code Library, or "JACL" for brevity.
//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
// LICENSE:
// This javascript file is licensed under the Creative Commons Attribution-ShareAlike License
// (http://creativecommons.org/licenses/by-sa/2.5/).
// 
// In summary: You are free to use, alter, transform, or build upon this source code for 
// commercial or personal use at no cost, but you must credit CodingMonk, LLC in the SOURCE 
// FORM of your derived work and may distribute the source only under a license identical to this
// one.  Note that the ShareAlike clause does not affect the way in which you distribute the 
// COMPILED FORM of works built upon this software. 
//
// To vary any of the terms of this license you must seek permission from the copyright 
// holder CodingMonk, LLC.
//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
// DESCRIPTION:
// This is the root module of JACL. It exposes functionality for including other 
// modules and automatically pulls in the logging module which it also leverages. This
// module provides JACL's primary interface object:
//
//		jacl
//
// Include it as you would a traditional javascript module by using a script tag with a fully 
// qualified src attribute: 
//
//		<script src='/jacl/jacl.js'></script>
//
// Examples:
//		jacl.use("jaclserverrequest");
//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
// Includes:	
//		JACLLog
//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
// HISTORY:
// 2005.09.05 Jim Fisher     Initial creation
// 2005.10.01 Jim Fisher     Made modifications to better support loading order.
//------------------------------------------------------------------------------------------------
if(window.jacl==null) {
	function jacl_core(){ //constructor
		//public members
		this.loadcount=0; 
		this.pageloading=1; //set to one to include page load event
		if(document.addEventListener) 
			document.addEventListener('DOMContentLoaded',function(){jacl.pageloading=0;},false);
		else
			document.onreadystatechange=function(){if(document.readyState=="complete" || document.readyState=="loaded") jacl.pageloading=0;};		
		this.modulestoload=new Array();
		this.path="";
		this.isModuleInitialized=function(obj){
		    if(obj==null) return false;
		    if(obj.__isInitialized) return obj.__isInitialized; 
		    return false;
        }
		this.markModuleInitialized=function(obj){obj.__isInitialized=true;}
		this.createModuleObject=function(existingObj,newObj){
		        if(existingObj==null && newObj==null) return new Object();
		        if(newObj==null) return existingObj;
		        if(existingObj!=null) {
                    for(property in existingObj) newObj[property]=existingObj[property];
		        }
		        return newObj;
		    };
		this.use= //method for dynamically linking other JACL modules to this page
			function(modulename){
				this.loadcount++;
				var o=document.createElement("script");
				o.src=this.path+modulename;
				if(o.src.toLowerCase().indexOf(".js")==-1)o.src+=".js";

				if(o.addEventListener) {
					o.addEventListener('load',function(){jacl.loadcount--;},false);
				}else{
					o.onreadystatechange=function(){
						if((this.readyState=="complete" || this.readyState=="loaded") && this.jaclscriptprocess!=1){
							this.jaclscriptprocess=1;
							jacl.loadcount--;
						}
					};
				}

				this.modulestoload.push(o);
				return o;
			};
		this.addPostCreationStep=function(fn){jacl._postcreationsteps.push(fn);} //register a function to be called after all JACL includes are complete (usually used by modules)
		this._postcreationsteps=new Array();	//placeholder for the post include steps
		this.appMain=null; //the final postcreation step
		this.la_h=null; //handle for the timing mechanism which calls launchApplication periodically, until everything is successfully loaded
		this.launchApplication= //called periodically to ensure that all modules requesting inclusion have actually been included successfully.  Upon completion, this calls all of the post-creation steps.
			function(){ 
				//still remaining modules to include?  then lets do that.
				while(jacl.pageloading==0 && jacl.modulestoload.length>0){
					var o=jacl.modulestoload.shift();
					document.body.appendChild(o);	
				}
				//has everything been included successfully?  Then lets call the final steps and exit
				if(jacl.modulestoload.length==0 && jacl.loadcount==0 && jacl.pageloading==0) {
					if(jacl.log==null) return;
					jacl.log.info("Launching application");
					clearInterval(jacl.la_h);
					if (jacl._postcreationsteps.length!=0 || jacl.appMain!=null) {
					    while(jacl._postcreationsteps.length>0){
						    var fn=jacl._postcreationsteps.shift();
						    fn(); //(jacl._postcreationsteps[t]());
					    }
					}
					if(jacl.appMain!=null) jacl.appMain();
					return;
				}
				//log our progress
				if(jacl.log!=null) jacl.log.info("Waiting for "+jacl.loadcount+" modules to finish loading...");
			};	
		//--------------------------------------------
		//determine library path (assumes this module was include with <script src="..."> syntax)
		var docscripts = document.getElementsByTagName("SCRIPT");
		for(t=0;t<docscripts.length;t++){
			var val=docscripts[t].src.toLowerCase();
			if(val.indexOf("jacl.js")!=-1) {
				this.path=val.substring(0,val.indexOf("jacl.js"));
				break;
			}
		}
	}
	jacl=new jacl_core();
	jacl.use("jacllog");	//pull in the logging module automatically
	jacl.la_h=setInterval(jacl.launchApplication,10);//poll at regular intervals until we are done loading all modules
}

