/*******************************************************************************
* Copyright 2008 Rafael Marques Martins
*
* This file is part of HermesJS.
* 
* HermesJS is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* 
* HermesJS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with HermesJS; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
* 
*******************************************************************************/

/**
 * Prefix path for modules loaded from a namespace
 */
var prefixPath = window.HermesJS && HermesJS.path ? HermesJS.path : "/te/js/";

HermesJS = {};
HermesJS.path = prefixPath;

/**
 * Path for your modules.json
 */
var modulesIndex = HermesJS.path + "HermesJS/modules.json";


if( !window.XMLHttpRequest ){
	/**
	 * Defines XMLHttpRequest class when it does not exists
	 * @type Object
	 * @return XMLHttpRequest instance
	 */
	var XMLHttpRequest = function(){
		this._object = null;
		this.onreadystatechange = function(){}
		
		this._getObject = function(){
			if ( navigator.userAgent.indexOf("MSIE") >= 0 ) { 
				var strName="Msxml2.XMLHTTP";
				if ( navigator.appVersion.indexOf("MSIE 5.5") >= 0 ) {
					strName="Microsoft.XMLHTTP";
				} 
				try{ 
					objXmlHttp=new ActiveXObject(strName);
					return objXmlHttp;
				}catch( e ){ 
					alert("Error. Scripting for ActiveX might be disabled") ;
					return null;
				} 
			} 
		}
		
		this._object = this._getObject();
		
		return this._object;
	}
	
}

HermesJS._translateNamespace = function( namespace ){
    return HermesJS.path + namespace.replace(/([^\\])\./g,'$1/').replace(/\\\./g,'.') + '.js'; //]
}

/**
* Function to import a js file based in a namespace (it will be translated to a path)
* @param {String} namespace Namespace for required file
* @type void
*/
HermesJS.require = require = function( namespace ){

	if( ('|' + window.require.loadedNamespaces.join('|') + '|').indexOf( '|'+namespace+'|' ) >= 0 ) return;
	
	var oXMLHttp = new XMLHttpRequest();
	oXMLHttp.open( "GET", HermesJS._translateNamespace( namespace ), false );
	oXMLHttp.send( null );
		
	var scriptTag = document.createElement('script');
	scriptTag.type = "text/javascript";
	scriptTag.text = oXMLHttp.responseText;
	
	var is_gecko = /gecko/i.test(navigator.userAgent);
	var is_ie = /MSIE/i.test(navigator.userAgent);
	
	var headTag = document.getElementsByTagName('head')[0];

    if( is_gecko ){
		try{
            window.eval.apply( window, [ oXMLHttp.responseText ] );
		}catch( e ){
            try{
                eval( oXMLHttp.responseText.replace( /function[\s\t]*((\w|\$|_)+)[\s\t]*\(/gi, '$1 = function(' ), window );
             }catch( e2 ){
                var lineNumber = 0;
                try{ var a = null; a.call() }catch( e3 ){ lineNumber = e3.lineNumber; };
                if( e2.lineNumber != undefined ){ 
                    lineNumber = e2.lineNumber -  lineNumber + 4;
                }
                fileName = HermesJS._translateNamespace( namespace ).split( "/" ).pop();

                throw new Error( e2.message, fileName, lineNumber );
             };
		}
	}else{
        headTag.appendChild( scriptTag );
    }	

		
	window.require.loadedNamespaces.push( namespace );
	
	HermesJS._setLoaders();
}
window.require.loadedNamespaces = new Array();
window.require.loadedSources = new Array();

/**
* Generic function that will load a js ( based in modules.json ) when you uses a class or funcion that
* is not already defined. It works as a "on-demand js loader"
* @ignore
**/
HermesJS._loader = function( oModule, arrArguments, instance ){
	var arrNamespaces = oModule.namespace.split(',');
	
	for( var i = 0; i < arrNamespaces.length; i++ ){
		require( arrNamespaces[i].replace(/^[\s\t\r\n]+|[\s\t\r\n]+$/g, '') );;
	}
	
	var arrArgStrings = new Array();
	for( var i=0; i<arrArguments.length; i++ ){
		arrArgStrings.push( "arrArguments["+i+"]" );
	}

        if( eval( oModule.variable ).__isLoader ){
            throw new Error( 'Loader Error:' + oModule.name + ' was not correctly defined!' );
        }

	if( instance ){
		return eval( 'new ' + oModule.variable + '(' + arrArgStrings.join(',') + ')' );
	}
	return eval( oModule.variable + '(' + arrArgStrings.join(',') + ')' );
}

/* Calls the index of modules to pre-configure the "on-demand loading" */
var oXMLHttp = new XMLHttpRequest();
oXMLHttp.open( "GET", modulesIndex, false );
oXMLHttp.send( null );
var objModules = eval( oXMLHttp.responseText );
window.require.objModules = objModules;

/* Defines all classes and functions in Module Index as a reference to HermesJS._loader */
HermesJS._setLoaders = function(){
	for( var attr in { 'modules' : null, 'functions' : null } ){
		for( var i = 0; i < window.require.objModules[attr].length; i++ ){
			var oModule = window.require.objModules[attr][i];
			
			var loaderSource = [ 
				"	var oModule = {",
				'		name: "', oModule.name , '",',
				'		namespace: "', oModule.namespace , '",',
				"		variable: '", 'window["' + oModule.name.split('.').join( '"]["' ) + '"]' , "'",
				"	};",
				"	return HermesJS._loader.apply( window, [ oModule, arguments, ( '", attr ,"' == 'modules' ) ] );",
			].join('');
			
			var arrModuleName = oModule.name.split('.');
			
			for( var j = 0; j < arrModuleName.length - 1; j++ ){
				var moduleName = 'window["' + arrModuleName.slice( 0, j + 1 ).join( '"]["' ) + '"]';
				if( eval( "typeof(" + moduleName + ")" ) == 'undefined' ){
					eval( moduleName + ' = {}' );
                                        eval( moduleName ).__isFakeNode = true;
				};
			};
			
			oModule.variable = 'window["' + arrModuleName.join( '"]["' ) + '"]';
			if( eval( "typeof(" + oModule.variable + ")" ) == 'undefined' ){
				eval( oModule.variable + ' = new Function( loaderSource )' );
                                eval( oModule.variable ).__isLoader = true;
			};
		};
	};
};

HermesJS._setLoaders();

