Source: main.js

/*
 * 	Copyright (C) 2012-2013 DFKI GmbH
 * 	Deutsches Forschungszentrum fuer Kuenstliche Intelligenz
 * 	German Research Center for Artificial Intelligence
 * 	http://www.dfki.de
 * 
 * 	Permission is hereby granted, free of charge, to any person obtaining a 
 * 	copy of this software and associated documentation files (the 
 * 	"Software"), to deal in the Software without restriction, including 
 * 	without limitation the rights to use, copy, modify, merge, publish, 
 * 	distribute, sublicense, and/or sell copies of the Software, and to 
 * 	permit persons to whom the Software is furnished to do so, subject to 
 * 	the following conditions:
 * 
 * 	The above copyright notice and this permission notice shall be included 
 * 	in all copies or substantial portions of the Software.
 * 
 * 	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
 * 	OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
 * 	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
 * 	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
 * 	CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
 * 	TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
 * 	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

define(['mmirf/core', 'mmirf/env', 'mmirf/util/deferred', 'mmirf/constants', 'mmirf/commonUtils', 'mmirf/configurationManager', 'mmirf/languageManager'
     , 'mmirf/controllerManager', 'mmirf/modelManager'
     , 'mmirf/presentationManager', 'mmirf/inputManager', 'mmirf/dialogManager', 'module'
     , 'mmirf/semanticInterpreter', 'mmirf/mediaManager', 'mmirf/notificationManager'
  ],
  /**
   * Initializes the MMIR framework:
   * triggers {@link mmir.ready} when initialization has finished.
   * 
   * @class
   * @name main
   * @memberof mmir
   * @private
   * 
   * @requires require.config
   * @requires util/deferred
   * 
   */
  function(mmir, env, deferred, constants, commonUtils, configurationManager, languageManager
	 , controllerManager, modelManager
     , presentationManager, inputManager, dialogManager, module
     , semanticInterpreter, mediaManager, notificationManager
){
	/**
	 * @private 
	 * @memberOf mmir */
	var isInit = false;
	
	//export framework functions/objects:
	
	/** @memberOf mmir */
	mmir.const = constants;
	/** @memberOf mmir */
	mmir.util = commonUtils;
	/** @memberOf mmir */
	mmir.conf = configurationManager;
	/** @memberOf mmir */
	mmir.notifier = notificationManager.init();
	
	/**
	 * HELPER create a "namespace" from a package-definition (dot-separated string) from configuration
	 *        or return the global namespace, if there is not config-value
	 * @param {String|Array<String>} configuration name
	 * 
	 * @private
	 * @memberOf main
	 */
	var getContextFor = function(ctxConfigName){
		var ctxName = configurationManager.get(ctxConfigName);
		if(ctxName){
			var namespaces = ctxName.split('.');
			var ctx = window, name;
			for(var i=0, size= namespaces.length; i < size; ++i){
				name = namespaces[i];
				if(!ctx[name]){
					ctx[name] = {};
				}
				ctx = ctx[name];
			}
			return ctx;
		}
		return ctx;
	}
	
	//the context where the controller implementation can be found (default: global context, i.e. window)
	/** @memberOf main */
	var ctrlImplCtx = getContextFor('controllerContext');
	//the context where the model implementations can be found (default: global context, i.e. window)
	/** @memberOf main */
	var modelImplCtx = getContextFor('modelContext');
	
	/** 
	 * Main Initialization:
	 * initializes mmir and exports its functions/modules to (gobal) mmir namespace
	 * 
	 * @memberOf main
	 */
	var mainInit = function(){

//		console.log('dom ready');
    	
		//initialize the common-utils:
		commonUtils.init()//<- load directory structure
			
			//load plugins (if in CORDOVA environment)
			.then(function() {

				return languageManager.init().then(function(langMng){
					mmir.lang = langMng;
				});
				
			})
			// start the ControllerManager
			.then(function() {
				
				mmir.ctrl = controllerManager;				
				//NOTE: this also gathers information on which 
				//      views, layouts etc. are available
				//      -> the presentationManager depends on this information
				return controllerManager.init(ctrlImplCtx);
			})
			
			//TEST parallelized loading of independent modules:
			.then(function(){

				/** @memberOf main */
				var isMediaManagerLoaded 	= false;
				/** @memberOf main */
				var isModelsLoaded 			= false;
				/** @memberOf main */
				var isVisualsLoaded 		= false;
				/** @memberOf main */
				var isInputManagerLoaded 	= false;
				/** @memberOf main */
				var isDialogManagerLoaded 	= false;
				/** @memberOf main */
				var isSemanticsLoaded       = false;

				/** @memberOf main */
				var checkInitCompleted = function(){
					
					if(			isMediaManagerLoaded
							&&	isModelsLoaded
							&& 	isVisualsLoaded 
							&&	isInputManagerLoaded
							&&	isDialogManagerLoaded
							&&	isSemanticsLoaded
					){

						/**
						 * Additional configuration for requirejs
						 * from configuration.json:
						 *  -> if property "config" is set, apply it as requirejs-config
						 *     before signaling READY
						 *  EXAMPLE:
						 *  the following entry (in config/configuration.json) would add
						 *  the dependency information for www/appjs/test.js as module "testConf"
						 *  
						 * 	, "config": {
						 *     	"paths": {
						 *     		"testConf": "../appjs/test"
						 *     	}
						 *     }
						 * 
						 * @type PlainObject 
						 * @memberOf main
						 */
						var requireConfig = configurationManager.get('config');
						if(requireConfig){
							mmir.require = require.config(requireConfig);
						}
						
						//"give signal" that the framework is now initialized / ready
						mmir.setInitialized();
					}
				};
				
				mmir.semantic = semanticInterpreter;
				/** ID for the grammar engine/compiler to be used, if/when JSON grammar are (re-) compiled
				 * @see mmir.SemanticInterpreter#setGrammarEngine
				 * @type String 
				 * @memberOf main */
				var grammarEngine = configurationManager.get('grammarCompiler');
				if(grammarEngine){
					semanticInterpreter.setGrammarEngine(grammarEngine);
				}
				/** set synchronous/asynchronous compile-mode for grammar compilation
				 * @see mmir.SemanticInterpreter#setEngineCompileMode
				 * @type Boolean
				 * @memberOf main */
				var grammarCompileMode = configurationManager.get('grammarAsyncCompileMode');
				if(typeof grammarCompileMode !== 'undefined'){
					semanticInterpreter.setEngineCompileMode(grammarCompileMode);
				}
				
				//TODO impl. automated sync/async loading&execution for compiled grammars
//				var grammarExecMode = configurationManager.get('grammarExecMode');
//				if(typeof grammarExecMode !== 'undefined'){
//					semanticInterpreter.setGrammarExecMode(grammarExecMode);//TODO add async-loaded grammars to ignoreGrammarFiles-list (to prevent loading them in "sync-exec mode")
//				}
				
				/** list of grammar IDs which should not be loaded, even if there is a compiled grammar available:
				 * @type String
				 * @memberOf main
				 */
				var ignoreGrammarIds = configurationManager.get('ignoreGrammarFiles', void(0));

				commonUtils.loadCompiledGrammars(constants.getGeneratedGrammarsPath(), void(0), ignoreGrammarIds).then(function() {
					
					isSemanticsLoaded = true;
					checkInitCompleted();
				});

				// start the MediaManager
				mediaManager.init().then(function() {
					isMediaManagerLoaded = true;
					
					//initialize BEEP notification (after MediaManager was initialized)
					notificationManager.initBeep();
					
					mmir.media = mediaManager;
					checkInitCompleted();
				});
				
				//TODO models may access views etc. during their initialization
				//	   --> there should be a way to configure startup, so that models may only be loaded, after everything else was loaded
				modelManager.init(modelImplCtx).then(function(){
					isModelsLoaded = true;
					mmir.model = modelManager;
					checkInitCompleted();
				});
				
				presentationManager.init().then(function(){

					isVisualsLoaded = true;
		
					mmir.presentation = presentationManager;
					checkInitCompleted();
					
				}, function error(err){ console.error('Failed initializing PresentationManager: '+err); });
				//TODO handle reject/fail of the presentationManager's init-Promise!
				
				dialogManager.init().then(function(res){//_dlgMng, _dialogEngine){
					isDialogManagerLoaded = true;
					mmir.dialog = res.manager;
					mmir.dialogEngine = res.engine;
					checkInitCompleted();
				});
				
				inputManager.init().then(function(res){//_inputMng, _inputEngine){
					isInputManagerLoaded = true;
					mmir.input = res.manager;
					mmir.inputEngine  = res.engine;
					checkInitCompleted();
				});
				
			});
			

	};//END: mainInit(){...
	
	mainInit();

	return mmir;
	
});//END: define(...