/*global define,angular*/

(function (root, factory) {
  'use strict';
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define([], function() {
      return factory(root);
    });
  } else if (typeof exports === 'object') {
      // Node. Does not work with strict CommonJS, but
      // only CommonJS-like environments that support module.exports,
      // like Node.

      module.exports = factory(root);
  } else if (typeof angular === 'object') {
    // Define an Angular JS module
    angular.module('hbpCollaboratoryAppToolkit', [])
    .factory('hbpCollaboratoryAppToolkit', ['$window', function($window) {
      return factory($window);
    }]);
  } else {
    // Browser globals (root is window)
    root.hbpCollaboratoryAppToolkit = factory(root);
  }
}(this, function factory(window) {
  'use strict';
  var eventId = 0;
  var sentMessages = {};

  /**
   * @module hbpCollaboratoryAppToolkit
   */
  function AppToolkit() { }
  AppToolkit.prototype = {
    emit: emit,
    context: context
  };

  window.addEventListener('message', function(event) {
    if(!event.data.origin) {
      return;
    }
    if(!sentMessages[event.data.origin]) {
      return;
    }
    if (event.data.eventName === 'resolved') {
      sentMessages[event.data.origin](null, event.data.data);
    } else if (event.data.eventName === 'error'){
      sentMessages[event.data.origin](event.data.data);
    }
    sentMessages[event.data.origin] = null;
  });

  function emit(name, data, callback) {
    window.parent.postMessage({
      apiVersion: 1,
      eventName: name,
      data: data,
      ticket: ++eventId
    }, '*');
    sentMessages[eventId] = callback;
  }

  var currentContext;

  /**
   * @typedef HbpCollaboratoryContext
   * @type {object}
   * @property {string} mode - the current mode, either 'run' or 'edit'
   * @property {string} ctx - the UUID of the current context
   * @property {string} state - an application defined state string
   */


  /**
   * @callback hbpCollaboratoryContextCallback
   * @param {HbpError} error - an HbpError
   * @param {HbpCollaboratoryContext} context - the context informations
   */


   /**
    * @desc
    * Asynchronously retrieve the current HBP Collaboratory Context, including
    * the mode, the ctx UUID and the application state if any.
    * @function context
    * @param  [{hbpCollaboratoryContextCallback} callback] - receiver of the call
    * @static
    */
  function context(data, callback) {
    if (typeof arguments[0] === 'function') {
      callback = data;
      data = null;
    }
    var kill = setTimeout(function() {
      callback({
        type: 'TimeoutException',
        message: 'No context can be retrieved'
      }, null);
    }, 250);

    if (data) {
      // discard context if new data should be set.
      currentContext = null;
    }

    if (currentContext) {
      // directly return context when cached.
      callback(null, currentContext);
    }

    emit('workspace.context', data, function(err, context) {
      clearTimeout(kill)
      if (err) {
        if (callback) {
          callback(err);
        }
      } else {
        currentContext = context;
        if (callback) {
          callback(null, currentContext);
        }
      }
    });
    return;
  }

  // Return a value to define the module export.
  // This example returns a functions, but the module
  // can return an object as the exported value.
  return new AppToolkit();
}));

@@ -2982,26 +2982,34 @@
 text);%0A    %7D
-%0A%0A
+ else %7B%0A  
     emit('wo
@@ -3063,16 +3063,18 @@
 %7B%0A      
+ 
+ 
 clearTim
@@ -3086,24 +3086,26 @@
 kill)%0A      
+  
 if (err) %7B%0A 
@@ -3099,24 +3099,26 @@
  if (err) %7B%0A
+  
         if (
@@ -3131,32 +3131,34 @@
 ck) %7B%0A          
+  
 callback(err);%0A 
@@ -3164,24 +3164,26 @@
         
+  
 %7D%0A      
 %7D else %7B
@@ -3170,24 +3170,26 @@
     %7D%0A      
+ 
+ 
 %7D else %7B%0A   
@@ -3181,24 +3181,26 @@
    %7D else %7B%0A
+  
         curr
@@ -3221,32 +3221,34 @@
 ontext;%0A        
+  
 if (callback) %7B%0A
@@ -3249,32 +3249,34 @@
 ck) %7B%0A          
+ 
+ 
 callback(null, c
@@ -3295,26 +3295,30 @@
 t);%0A        
-%7D%0A
+  %7D%0A  
       %7D%0A    
@@ -3321,16 +3321,18 @@
     
+  
 %7D);%0A    
 retu
@@ -3327,23 +3327,17 @@
 %7D);%0A    
-return;
+%7D
 %0A  %7D%0A%0A  

fix event emitting while also retrieving cached value.