1 /**
  2  * TAO API interface.
  3  * Provides functions to manage the communication with a TAO context from an XHTML item.
  4  * 
  5  * @author CRP Henri Tudor - TAO Team - {@link http://www.tao.lu}
  6  * @license GPLv2  http://www.opensource.org/licenses/gpl-2.0.php
  7  * @package taoItems
  8  * @requires jquery >= 1.4.0 {@link http://www.jquery.com}
  9  */
 10 
 11 
 12 /**
 13  * instanciate the TaoStack object
 14  */
 15 var taoStack = new TaoStack();
 16 
 17 var root_url = root_url || '';
 18 
 19   ////////////////////
 20  // TAO  variables //
 21 ////////////////////
 22 
 23 
 24 
 25 /**
 26  * Get the endorsment of the item
 27  * 
 28  * @function
 29  * @returns {boolean}
 30  */
 31 function getEndorsment(){
 32 	return taoStack.getTaoVar(URI.ENDORSMENT);
 33 }
 34 
 35 /**
 36  * Set the endorsment of the item
 37  * 
 38  * @function
 39  * @param {boolean} endorsment
 40  */
 41 function setEndorsment(endorsment){
 42 	taoStack.setTaoVar(URI.ENDORSMENT, (endorsment === true));
 43 }
 44 
 45 /**
 46  * Get the score of the item 
 47  * 
 48  * @function
 49  * @returns {String|Number}
 50  */
 51 function getScore(){
 52 	return taoStack.getTaoVar(URI.SCORE);
 53 }
 54 
 55 /**
 56  * Set the final score of the item
 57  * 
 58  * @function
 59  * @param {String|Number} score
 60  */
 61 function setScore(score){
 62 	if(isScalar(score)){
 63 		if(typeof(score) == 'boolean'){
 64 			(score === true) ? score = 1 : score = 0;
 65 		}
 66 		taoStack.setTaoVar(URI.SCORE, score);
 67 	}
 68 }
 69 
 70 /**
 71  * get the score range if defined
 72  * 
 73  * @function
 74  * @returns {Object} with <b>min</b> and <b>max</b> attributes
 75  */
 76 function getScoreRange(){
 77 	return {
 78 		'min': taoStack.getTaoVar(URI.SCORE_MIN),
 79 		'max': taoStack.getTaoVar(URI.SCORE_MAX)
 80 	};
 81 }
 82 
 83 /**
 84  * Set the score range. 
 85  * It will be used to calculate the endorsment from the score.
 86  * 
 87  * @function
 88  * @param {String|Number} max
 89  * @param {String|Number} [min = 0]
 90  */
 91 function setScoreRange(max, min){
 92 	if(max != undefined){
 93 		if(min == undefined){
 94 			min = 0;
 95 		}
 96 		taoStack.setTaoVar(URI.SCORE_MIN, min);
 97 		taoStack.setTaoVar(URI.SCORE_MAX, max);
 98 	}
 99 }
100 
101 /**
102  * Get the values answered by the subject 
103  * 
104  * @function
105  * @returns {Object}
106  */
107 function getAnsweredValues(){
108 	return taoStack.getTaoVar(URI.ANSWERED_VALUES);
109 }
110 
111 /**
112  * Set the values answered by the subject.
113  * If the item contains a free text field, 
114  * you can record here the complete response. 
115  * 
116  * @function
117  * @param {Object} values
118  */
119 function setAnsweredValues(values){
120 	taoStack.setTaoVar(URI.ANSWERED_VALUES, values);
121 }
122 
123 /**
124  * Get the data of the user currently doing the item  (the subject)
125  * 
126  * @function
127  * @returns {Object} all the data related to the subject
128  */
129 function getSubject(){
130 	return taoStack.getTaoVar(URI.SUBJECT);
131 }
132 
133 /**
134  * Get the login of the subject
135  * 
136  * @function
137  * @returns {String} the subject's login
138  */
139 function getSubjectLogin(){
140 	var subject = getSubject();
141 	return (subject) ? subject[URI.SUBJETC_LOGIN] : '';
142 }
143 
144 /**
145  * Get the name of the subject (firstname and lastname)
146  * 
147  * @function
148  * @returns {Object} the subject's name
149  */
150 function getSubjectName(){
151 	var subject = getSubject();
152 	if(subject){
153 		return subject[URI.SUBJETC_FIRSTNAME] + ' ' + subject[URI.SUBJETC_LASTNAME];
154 	}
155 	return '';
156 }
157 
158 /**
159  * Get the current item's informations 
160  * 
161  * @function
162  * @returns {Object} the item's data (uri, label)
163  */
164 function getItem(){
165 	return taoStack.getTaoVar(URI.ITEM);
166 }
167 
168 
169 /**
170  * Get the informations of the currently running test 
171  * 
172  * @function
173  * @returns {Object} the test's data (uri, label)
174  */
175 function getTest(){
176 	return taoStack.getTaoVar(URI.TEST);
177 }
178 
179 /**
180  * Get the informations of the current delivery
181  * 
182  * @function
183  * @returns {Object} the delivery's data (uri, label)
184  */
185 function getDelivery(){
186 	return taoStack.getTaoVar(URI.DELIVERY);
187 }
188 
189 
190   //////////////////////
191  // User's variables //
192 //////////////////////
193 
194 /**
195  * This function enables you to create and edit custom variables: the <i>user's variables</i>
196  * The variable is identified by a key you have chosen.
197  * This variable will be saved temporarly into the taoApi.
198  * When you call the <code>push()</code> function, the <i>user's variables</i> are sent to the server.
199  * It's a way to record some data other than the results and the events.
200  * 
201  * @function
202  * @param {String} key to identify of the variable
203  * @param {String|number|boolean} the value of the variable
204  */
205 function setUserVar(key, value){
206 	taoStack.setUserVar(key, value);
207 }
208 
209 /**
210  * Get a previously defined user's variable.
211  * 
212  * @function
213  * @param {String} key the key of the variable you want to retrieve
214  * @returns {String|number|boolean}
215  */
216 function getUserVar(key){
217 	return taoStack.getUserVar(key);
218 }
219 
220 
221   /////////////
222  // STATES  //
223 /////////////
224 
225 if(typeof(finish) != 'function'){
226 
227 	
228 	/**
229 	 * Define the item's state as finished.
230 	 * This state can have some consequences.
231 	 * 
232 	 * @function
233 	 */
234 	function finish(){
235 		$(window).trigger(STATE.ITEM.PRE_FINISHED);
236 		$(window).trigger(STATE.ITEM.FINISHED);
237 		$(window).trigger(STATE.ITEM.POST_FINISHED);
238 	}
239 	
240 	/**
241 	 * Add a callback that will be executed on finish state.
242 	 * 
243 	 * @function
244 	 * @param {function} callback
245 	 */
246 	function onFinish(callback){
247 		$(window).bind(STATE.ITEM.FINISHED, callback);
248 	}
249 	
250 	/**
251 	 * Add a callback that will be executed on finish but before the other callbacks  
252 	 * 
253 	 * @function
254 	 * @param {function} callback
255 	 */
256 	function beforeFinish(callback){
257 		$(window).bind(STATE.ITEM.PRE_FINISHED, callback);
258 	}
259 	
260 	/**
261 	 * Add a callback that will be executed on finish but after the other callbacks  
262 	 * 
263 	 * @function
264 	 * @param {function} callback
265 	 */
266 	function afterFinish(callback){
267 		$(window).bind(STATE.ITEM.POST_FINISHED, callback);
268 	}
269 
270 }
271 
272   //////////////////////////////
273  // INTERFACE COMMUNICATION  //
274 //////////////////////////////
275 
276 /**
277  * Get the communication token (this token is sent at each communication)
278  * 
279  * @function
280  * @returns {String} the token
281  */
282 function getToken(){
283 	return taoStack.dataStore.token;
284 }
285 
286 /**
287  * This fuction enables you to set up the data the item need.
288  * You can retrieve this data from either a remote or a manual source.
289  * <b>If you don't need to change the default values, don't call this function.</b>
290  * 
291  * @function
292  * 
293  * @param {Object} environment <i>set to null if you want to keep all the default values</i>
294  * @param {String} [environment.type = "async"] the datasource type <b>(manual|sync|async)</b> 
295  * @param {String} [environment.url = "/taoDelivery/ResultDelivery/initialize"] the url of the server where the data are sent 
296  * @param {Object} [environment.params] the additional parameters to send with the data
297  * 
298  * @param {Object} settings <i>set to null if you want to keep all the default values</i>
299  * @param {String} [settings.format = "json"] the data format. <i>Only json is supported in the current version</i> 
300  * @param {String} [settings.method = "post"] HTTP method to push the data <b>(get|post)</b>
301  */
302 function initDataSource(environment, settings){
303 	taoStack.initDataSource(environment, settings, null);
304 }
305 
306 /**
307  * This function is a convenience method to add directly the datasource 
308  * by writing the data in the source object (JSON) .
309  *   
310  * @function
311  * @param {Object} source
312  */
313 function initManualDataSource(source){
314 	taoStack.initDataSource({type: 'manual'}, null, source);
315 }
316 
317 
318 /**
319  * Initialize the push communication.
320  * <b>If you don't need to change the default values, don't call this function.</b>
321  * 
322  * @function
323  * 
324  * @param {Object} environment <i>set to null if you want to keep all the default values</i>
325  * @param {String} [environment.url = "/taoDelivery/ResultDelivery/save"] the url of the server where the data are sent 
326  * @param {Object} [environment.params] the additional parameters to send with the data
327  * 
328  * @param {Object} settings <i>set to null if you want to keep all the default values</i>
329  * @param {String} [settings.format = "json"] the data format. <i>Only json is supported in the current version</i> 
330  * @param {String} [settings.method = "post"] HTTP method to push the data <b>(get|post)</b>
331  * @param {boolean}[settings.async = true]	if the request is asynchronous
332  * @param {boolean}[settings.clearAfter= true]	if the variables stacks are cleared once the push is done
333  */
334 function initPush(environment, settings){
335 	taoStack.initPush(environment, settings);
336 }
337 
338 
339 /**
340  * This method enables you to push the data to the server.
341  * 
342  * @function
343  */
344 function push(){
345 	taoStack.push();
346 }
347 
348 /*
349  * By default, the variables are pushed when the item is finished
350  */
351 beforeFinish(push);
352 
353 
354 
355 /////////////
356 // EVENTS  //
357 /////////////
358 
359 /**
360 * instanciate the EventTracer object
361 * @type EventTracer
362 */
363 var eventTracer = new EventTracer();
364 
365 /**
366 * Log the an <i>eventType</i> bound on <i>elementName</i> by sending the <i>data</i>.
367 * 
368 * @function
369 * @param {String} elementName an HTML tag name
370 * @param {String} eventType a JS User Events
371 * @param {mixed} data any data strucuture you want to trace
372 */
373 function logEvent(elementName, eventType, data){
374 	eventTracer.feedTrace(elementName, eventType, new Date().getTime(), data);
375 }
376 
377 /**
378 * Log the a <i>eventName</i> by sending the <i>data</i>
379 * 
380 * @function
381 * @param {String} eventName the name of the custom event
382 * @param {mixed} data 
383 */
384 function logCustomEvent(eventName, data){
385 	eventTracer.feedTrace('BUSINESS', eventName, new Date().getTime(), data);
386 }
387 
388 /**
389  * Initialize the interfaces communication for the events logging.
390  * The source service defines where and how we retrieve the list of events to catch
391  * The destination service defines where and how we send the catched events 
392  * 
393  * @function
394  * 
395  * @param {Object} source 
396  * @param {String} [source.type = "sync"] the type of source <b>(sync|manual)</b>
397  * @param {Object} [source.data] For the <i>manual</i> source type, set direclty the events list in the data 
398  * @param {String} [source.url = "/taoDelivery/ResultDelivery/getEvents"] For the <i>sync</i> source type, the URL of the remote service
399  * @param {Object} [source.params] the parameters to send to the sync service
400  * @param {String} [source.format = "json"] the data format. <i>Only json is supported in the current version</i> 
401  * @param {String} [source.method = "post"] HTTP method of the sync service <b>(get|post)</b>
402  * 
403  * @param {Object} destination
404  * @param {String} [destination.url = "/taoDelivery/ResultDelivery/traceEvents"] the URL of the remote service
405  * @param {Object} [destination.params] the common parameters to send to the service
406  * @param {String} [destination.format = "json"] the data format. <i>Only json is supported in the current version</i> 
407  * @param {String} [destination.method = "post"] HTTP method of the service <b>(get|post)</b>
408  */
409 function initEventServices(source, destination){
410 	
411 	extendedParams = {params: {token: getToken()}}; 
412 	
413 	eventTracer.initSourceService($.extend(true, source, extendedParams));
414 	
415 	eventTracer.initDestinationService($.extend(true, destination, extendedParams));
416 }
417 
418 /*
419  * By default, all the events are sent  when the item is finished
420  */
421 beforeFinish(function(){
422 	eventTracer.sendAllFeedTrace_now();
423 });
424