var g_AGIBaseFolder 		= "AGI.WebClient";
var g_AGIFrameworkSubFolder = "framework";
var g_AGILibSubFolder 		= "lib";
var g_AGICSSSubFolder 		= g_AGIFrameworkSubFolder + "/css";
var g_AGIImagesSubFolder 	= g_AGIFrameworkSubFolder + "/images";

var CApplication = 
{
	Version: '1.0',
	loadRequested: 1,
	loadComplete: 2,
  
	init : function() 
  	{
  		var elements;
  		var i;
  	
    	try 
		{  
			// fix IE background image flicker (credit: www.mister-pixel.com)
      		document.execCommand("BackgroundImageCache", false, true);
    	} 
		catch(err) 
		{
		}
	
		this.preloadMsgs 		= '';
    	this.baseHref 			= location.protocol + "//" + location.host;
    	this.loadedFiles		= {};
    	this.loadQueue			= [];    
    	this.windowIsLoaded		= false;
    	this.onLoadCallbacks	= [];
    
    	elements = document.getElementsByTagName('script');
    	for (i = 0; i < elements.length; i++) 
		{
      		if (elements[i].src)
      		{
      			var src 					= elements[i].src;
      			var slashIdx 				= src.lastIndexOf('/');
      			var path 					= src.substring(0, slashIdx + 1);
      			var filename 				= src.substring(slashIdx + 1);
      			this.loadedFiles[filename]	= this.loadComplete;
	  			var parmPos  				= filename.indexOf('?');
      	
		  		if (parmPos > 0)
        			filename = filename.substring(0, parmPos)
      			if (filename == 'agi_Application.js') 
				{
	          		this.AGIDir  			= g_AGIBaseFolder;
	          		this.jsFrameworkDir		= this.AGIDir + "/" + g_AGIFrameworkSubFolder;
	          		this.cssDir 			= this.AGIDir + "/" + g_AGICSSSubFolder;
	          		this.imgDir 			= this.AGIDir + "/" + g_AGIImagesSubFolder;   
	    		}
      		}
    	}
    	if (typeof Prototype=='undefined')
    		this.include('a-/' + g_AGILibSubFolder + '/prototype.js');
    	this.include('f-agi_framework.js');
    
    	var func = function() { CApplication.windowLoaded(); };
    	if (window.addEventListener)
      		window.addEventListener('load', func, false);
    	else if (window.attachEvent)
      		window.attachEvent('onload', func);
  },
  
  // Array entries can reference a javascript file or css stylesheet
  // Options
  // '+xxx' : dependency on module xxx  
  // 'f-xxx.js' : xxx.js is a framework js (ie in framework folder)
  // 'a-xxx.js' : xxx.js is in root folder of AGI
  moduleDependencies : 
  {
    MapView  : ['f-CSession.js', 'f-CResult.js', 'f-CTransactResult.js', 'f-CTransact.js', 'f-agi_map.js']
  },
  
  // Expects one or more module or file names
  // not reliable when used with XSLT
	loadModule : function() 
  	{
    	for (var a=0, length=arguments.length; a<length; a++) 
		{
			var name	= arguments[a];
      		var dep		= this.moduleDependencies[name];
      		
			if (dep) 
	  		{
      			for (var i=0; i < dep.length; i++)
      			{
        			if (dep[i].substring(0,1) == '+')
            			this.loadModule(dep[i].slice(1));
            		else
            			this.include(dep[i]);
      			}
      		}
			else
        		this.include(name);
      	}
  	},
  
  	include : function(filename) 
  	{  		
		if (this.loadedFiles[filename]) 
			return;
    	                		
		var ext = filename.substr(filename.lastIndexOf('.') + 1);
    	switch (ext.toLowerCase()) 
		{
      		case 'js':
        		this.loadQueue.push(filename);
        		this.loadedFiles[filename] = this.loadRequested;
        		this.checkLoadQueue();
        		return;
      		case 'css':
        		var el = document.createElement('link');
        		el.type = 'text/css';
        		el.rel	= 'stylesheet'
        		el.href	= this.cssDir+filename;
        		this.loadedFiles[filename]=this.loadComplete;
        		document.getElementsByTagName('head')[0].appendChild(el);
        	return;
		}
  	},
  
	checkLoadQueue: function() 
  	{
    	if (this.loadQueue.length == 0) 
			return;
		if (this.inProcess) 
			return;  // seems to only be required by IE, but applied to all browsers just to be safe
    	this.addScriptToDOM(this.loadQueue.shift());
  	},
  
	addScriptToDOM: function(filename) 
	{
		var js 		= document.createElement('script');
		var head	= document.getElementsByTagName('head')[0];
		var src;
		
		src = this.baseHref;
    	if (filename.substring(0,2) == 'f-')
        	src += "/" + this.jsFrameworkDir + "/" + filename.slice(2);
        else if (filename.substring(0,2) == 'a-')
        	src += "/" + this.AGIDir + "/" + filename.slice(2);
        else
    		src	+= filename;
    	
    	js.type	= 'text/javascript';
    	js.src = src;
    	
    	this.loadedFiles[filename] 	= this.loadRequested;
    	this.inProcess 				= filename;
    	
      	js.onload = js.onreadystatechange = function() 
		{
        	if (js.readyState && js.readyState != 'loaded' && js.readyState != 'complete') 
				return;
        	js.onreadystatechange = js.onload = null;
        	CApplication.includeLoaded(filename);
      	};
      	head.appendChild(js);
	},
  
  	// called after a script file has finished loading
  	includeLoaded: function(filename) 
	{
    	this.loadedFiles[filename] = this.loadComplete;
    	if (filename == this.inProcess) 
		{
      		this.inProcess = null;
      		this.checkLoadQueue();
      		this.checkIfComplete();
    	}
    },
  
	// called by the document onload event
	windowLoaded: function() 
  	{
    	this.windowIsLoaded = true;
    	this.checkLoadQueue();
    	this.checkIfComplete();
  	},
  
	checkIfComplete: function() 
	{
    	var waitingFor = this.windowIsLoaded ? '' : 'window';
    	
		for(var filename in  this.loadedFiles) 
		{
      		if (this.loadedFiles[filename] == this.loadRequested)
        		waitingFor += ' '+filename;
    	}
    	if (waitingFor.length==0) 
		{
      		while (this.onLoadCallbacks.length > 0) 
			{
        		var callback=this.onLoadCallbacks.pop();
        		if (callback) 
					callback();
      		}
    	}
  	},
  
	onLoad: function(callback) 
	{
    	this.onLoadCallbacks.push(callback);
    	this.checkIfComplete();
  	},

	// logging funtions
  	startTime : new Date(),

	timeStamp: function() 
	{
    	var stamp = new Date();
    	return (stamp.getTime() - this.startTime.getTime())+": ";
  	},
  	
  	getImageURL: function(sFileName)
  	{
  		return this.baseHref + "/" + g_AGIImagesSubFolder + "/" + sFileName;
  	},
  	
  	Create: function(oWindow)
  	{
  		if(oWindow && oWindow.Create)
  		{
	  		CBitmap._loadImages(oWindow.Create.bind(oWindow));
  		}
  	}
}

