1 /*
  2  * 	Copyright (C) 2012-2013 DFKI GmbH
  3  * 	Deutsches Forschungszentrum fuer Kuenstliche Intelligenz
  4  * 	German Research Center for Artificial Intelligence
  5  * 	http://www.dfki.de
  6  * 
  7  * 	Permission is hereby granted, free of charge, to any person obtaining a 
  8  * 	copy of this software and associated documentation files (the 
  9  * 	"Software"), to deal in the Software without restriction, including 
 10  * 	without limitation the rights to use, copy, modify, merge, publish, 
 11  * 	distribute, sublicense, and/or sell copies of the Software, and to 
 12  * 	permit persons to whom the Software is furnished to do so, subject to 
 13  * 	the following conditions:
 14  * 
 15  * 	The above copyright notice and this permission notice shall be included 
 16  * 	in all copies or substantial portions of the Software.
 17  * 
 18  * 	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
 19  * 	OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
 20  * 	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
 21  * 	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
 22  * 	CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
 23  * 	TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
 24  * 	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 25  */
 26 
 27 define([  'core', 'jquery'
 28         , 'commonUtils', 'module', 'engineConfig', 'controllerManager', 'presentationManager', 'logger'
 29         , 'modelManager' 
 30 	], 
 31 	/**
 32 	 * The DialogManager gives access to the most commonly used functions of
 33 	 * the framework.
 34 	 * 
 35 	 * <p>
 36 	 * On initialization, the DialogManager also creates the {@link mmir.DialogEngine}
 37 	 * and returns it as the second argument of the {@link #init}() function's callback
 38 	 * (or the Promise's triggered callbacks).
 39 	 * 
 40 	 * In addition, the DialogEngine is exported as module <code>"dialogEngine"</code> via
 41 	 * RequireJS' <code>define()</code> function.
 42 	 * 
 43 	 * @example
 44 	 * //initialization of inputManager
 45 	 * require('dialogManager').init().then( function(dialogManagerInstance, dialogEngineInstance){
 46 	 * 		//do something
 47 	 * });
 48 	 * 
 49 	 * @name mmir.DialogManager
 50 	 * @static
 51 	 * @class
 52 	 * 
 53 	 * @requires mmir.ControllerManager
 54 	 * @requires mmir.PresentationManager
 55 	 * @requires mmir.ModelManager
 56 	 * 
 57 	 * 
 58      * @requires jQuery.Deferred
 59      * @requires jQuery.extend
 60      * 
 61 	 */
 62 	function(
 63 			mmir, $, 
 64 			commonUtils, module, engineConfig, controllerManager, presentationManager, Logger
 65 ) {
 66 
 67 	//the next comment enables JSDoc2 to map all functions etc. to the correct class description
 68 	/** @scope mmir.DialogManager.prototype */
 69 	
 70 	/**
 71 	 * @private
 72 	 * @type Function
 73 	 * 
 74 	 * @see {@link mmir.DialogManager#getOnPageRenderedHandler}
 75 	 * @see {@link mmir.DialogManager#setOnPageRenderedHandler}
 76 	 * 
 77 	 * @memberOf mmir.DialogManager#
 78 	 */
 79 	var onPageRenderedFunc;
 80 	
 81 	/**
 82 	 * @memberOf mmir.DialogManager# 
 83 	 */
 84 	var _instance = {
 85 
 86 		/** @scope mmir.DialogManager.prototype */
 87 		
 88 		/** 
 89 		 * @deprecated instead: use mmir.DialogManager object directly.
 90 		 * 
 91 		 * @memberOf mmir.DialogManager.prototype
 92 		 */
 93 		getInstance : function() {
 94 			return this;
 95 		},
 96 		
 97 		/**
 98 		 * This function raises an event. 
 99 		 * 
100 		 * @function
101 		 * @param {String} eventName
102 		 * 				The name of the event which is to be raised
103 		 * @param {Object} [eventData] OPTIONAL
104 		 * 				Data belonging to the event
105 		 * @throws {Error} if this function is invoked while the internal
106 		 * 				   event/state engine (i.e. {@link mmir.DialogEngine}
107 		 * 				   is not initialized yet
108 		 * @public
109 		 */
110 		raise : function(eventName, eventData) {
111 			//NOTE the functional implementation will be set during initialization (see below #init())
112 			throw new Error('DialogEngine not initialized yet: '
113 					+'call mmir.DialogManager.init(callback) and wait for the callback.'
114 			);
115 		},
116 
117 		/**
118 		 * This function performs an action of a controller by calling
119 		 * the method {@link mmir.ControllerManager#perform} of the
120 		 * {@link mmir.ControllerManager}
121 		 * 
122 		 * @function
123 		 * @param {String}
124 		 *            ctrlName Name of the controller to which the
125 		 *            action belongs
126 		 * @param {String}
127 		 *            actionName Name of the action that should be
128 		 *            performed
129 		 * @param {Object}
130 		 *            data optional data that can be submitted to the
131 		 *            action
132 		 * @returns {Object} the return object of the performed action
133 		 * @public
134 		 */
135 		perform : function(ctrlName, actionName, data) {
136 			
137 			//@russa what is this for?
138 //			var _data = {};
139 //			_data.timestamp = new Date().getTime();
140 //			_data.ctrl = ctrlName;
141 //			_data.name = actionName;
142 //			_data.args = data;
143 			
144 			// if(logger.isDebug()) logger.debug("going to perform ('" + ctrlName + "','" + actionName + "')");//debug
145 
146 			return controllerManager.perform(ctrlName, actionName, data);
147 		},
148 
149 		/**
150 		 * This function performs an action of a helper-class for a
151 		 * controller by calling the method
152 		 * {@link mmir.ControllerManager#performHelper} of the
153 		 * {@link mmir.ControllerManager}
154 		 * 
155 		 * @function
156 		 * @param {String}
157 		 *            ctrlName Name of the controller to which the
158 		 *            helper action belongs
159 		 * @param {String}
160 		 *            helper_method_name Name of the action that should
161 		 *            be performed by the helper
162 		 * @param {Object}
163 		 *            data optional data that can be submitted to the
164 		 *            action
165 		 * @returns {Object} the return object of the performed action
166 		 * @public
167 		 */
168 		performHelper : function(ctrlName, helper_method_name, data) {
169 			
170 			if (arguments.length > 3) {
171 				
172 				return controllerManager.performHelper(
173 						ctrlName, helper_method_name, data, arguments[3]
174 				);
175 			}
176 			else {
177 				
178 				return controllerManager.performHelper(
179 						ctrlName, helper_method_name, data
180 				);
181 			}
182 		},
183 
184 		/**
185 		 * This function displays a dialog of a controller by calling
186 		 * the method {@link mmir.PresentationManager#showDialog} of the
187 		 * {@link mmir.PresentationManager}
188 		 * 
189 		 * @function
190 		 * @param {String}
191 		 *            ctrlName Name of the controller to which the
192 		 *            dialog belongs
193 		 * @param {String}
194 		 *            dialogId Id of the dialog that should be displayed
195 		 * @param {Object}
196 		 *            data Optional data that can be submitted to the
197 		 *            dialog
198 		 * @public
199 		 */
200 		showDialog : function(ctrlName, dialogId, data) {
201 			presentationManager.showDialog.apply(presentationManager, arguments);
202 		},
203 
204 		/**
205 		 * This function closes a dialog of a controller by calling the
206 		 * method {@link mmir.PresentationManager#hideCurrentDialog} of
207 		 * the {@link mmir.PresentationManager}
208 		 * 
209 		 * @function
210 		 * @public
211 		 */
212 		hideCurrentDialog : function() {
213 			presentationManager.hideCurrentDialog.apply(presentationManager, arguments);
214 		},
215 		/**
216 		 * Shows a "wait" dialog, indicating work-in-progress.
217 		 * 
218 		 * This is a shortcut for calling
219 		 * {@link mmir.PresentationManager#showWaitDialog}
220 		 * (see documentation in <code>PresentationManager</code>
221 		 *  for parameters).
222 		 * 
223 		 * @function
224 		 * 
225 		 * @public
226 		 * 
227 		 * @see mmir.PresentationManager#showWaitDialog
228 		 * @see mmir.PresentationManager#hideWaitDialog
229 		 */
230 		showWaitDialog : function(text, theme) {
231 			presentationManager.showWaitDialog.apply(presentationManager, arguments);
232 		},
233 
234 		/**
235 		 * Hides / closes the "wait" dialog.
236 		 * 
237 		 * 
238 		 * This is a shortcut for calling
239 		 * {@link mmir.PresentationManager#hideWaitDialog}
240 		 * (see documentation in <code>PresentationManager</code>
241 		 *  for parameters).
242 		 *  
243 		 * @function
244 		 * @public
245 		 * 
246 		 * @see mmir.PresentationManager#hideWaitDialog
247 		 * @see mmir.PresentationManager#showWaitDialog
248 		 */
249 		hideWaitDialog : function() {
250 			presentationManager.hideWaitDialog.apply(presentationManager, arguments);
251 		},
252 
253 		/**
254 		 * This function displays a view of a controller by calling the
255 		 * method {@link mmir.PresentationManager#renderView} of the
256 		 * {@link mmir.PresentationManager}.
257 		 * <br>
258 		 * And after rendering, the function set via #setOnPageRenderedHandler will
259 		 * called in context of the controller instance with arguments:
260 		 * <code>Controller.onPageRenderedFunc(ctrlName, viewName, data)</code>
261 		 * 
262 		 * 
263 		 * @function
264 		 * @param {String}
265 		 *            ctrlName Name of the controller to which the view
266 		 *            belongs
267 		 * @param {String}
268 		 *            viewName Name of the view that should be rendered
269 		 * @param {Object}
270 		 *            data Optional data that can be submitted to the
271 		 *            generation of the view
272 		 * @public
273 		 */
274 		render : function(ctrlName, viewName, data) {
275 			
276 			presentationManager.renderView(ctrlName, viewName, data);
277 
278 			if (typeof onPageRenderedFunc === 'function') {
279 				var ctrl = controllerManager.getController(ctrlName);
280 				onPageRenderedFunc.call(ctrl, ctrlName, viewName, data);
281 			}
282 		},
283 		/**
284 		 * Get the current on-page-rendered hook function (if it was
285 		 * set).
286 		 * 
287 		 * @function
288 		 * @param {Function}
289 		 *            the onPageRendered handler (NOTE: this may not be
290 		 *            set, i.e. <tt>undefined</tt>)
291 		 */
292 		getOnPageRenderedHandler : function() {
293 			return onPageRenderedFunc;
294 		},
295 		/**
296 		 * Set the on_page_loaded callback function.
297 		 * 
298 		 * If <code>onPageRenderedHook</code> is a function object, it
299 		 * will be executed after a view is rendered and after the
300 		 * view's controller on_page_load function(s) has/have been
301 		 * executed.
302 		 * 
303 		 * <p>
304 		 * This function will be executed after the view's
305 		 * on_page_load()-function.<br>
306 		 * The <code>onPageRenderedHook</code> function takes 3
307 		 * arguments that refer to the parameters with which the
308 		 * render-function was invoked: <br>
309 		 * <code>{String} ctrlName </code> Name of the controller to
310 		 * which the view belongs <br>
311 		 * <code>{String} viewName</code> Name of the view that should
312 		 * be rendered <br>
313 		 * <code>{Object} [data]</code> <em>Optional</em> data that
314 		 * can be submitted to the generation of the view
315 		 * 
316 		 * @function
317 		 * @param {Function}
318 		 *            onPageRenderedHook a callback function that will
319 		 *            be executed after a view was rendered i.e. after a
320 		 *            page was loaded.
321 		 */
322 		setOnPageRenderedHandler : function(onPageRenderedHook) {
323 			onPageRenderedFunc = onPageRenderedHook;
324 		}
325 		
326 	};//END: _instance = {...
327 
328 	return $.extend(true, _instance, {
329 
330 		init : function() {
331 			
332 			delete this.init;
333 			
334 			//"read" settings from requirejs' config (see mainConfig.js):
335 			var url = module.config().scxmlDoc;
336 			var mode = module.config().mode;
337 			
338 			//create a SCION engine:
339 			var engine = engineConfig(url, mode);
340 			
341 			this._log = Logger.create(module);
342 			engine._log = Logger.create(module.id+'Engine', module.config().logLevel);
343 
344 //			var _self = this;
345 
346 			return $.Deferred(function(theDeferredObj) {
347 				
348 				engine.load().done(function(_engine) {
349 					
350 					_instance.raise = function raise(){
351 						_engine.raise.apply(_engine, arguments);
352 					};
353 					
354 //					mmir.DialogEngine = _engine;
355 //					mmir.DialogEngine.gen('init', _self);
356 					delete _engine.gen;
357 					
358 					//register the DialogeEngine with requirejs as module "dialogEngine":
359 					define("dialogEngine", function(){
360 						return _engine;
361 					});
362 					//immediately load the module-definition:
363 					require(['dialogEngine'], function(){
364 						//signal end of initialization process:
365 						theDeferredObj.resolve(_instance, _engine);	
366 					});
367 				});
368 				
369 			}).promise();
370 			
371 		}//END: init()
372 
373 	});//END $.extend(...
374 
375 });//END: define(...
376