/*  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */

/*
 * This source code implements specifications defined by the Java
 * Community Process. In order to remain compliant with the specification
 * DO NOT add / change / or delete method signatures!
 */

/**
 * @fileOverview
 * This module provides the implementation for the Pluto portlet hub.
 * <p>
 * 
 * @author Scott Nicklous
 * @copyright IBM Corp., 2014
 */
var portlet = portlet || {};

(function () {
   'use strict';

   var isInitialized = false,

   /**
    * The object holding the portlet data for each portlet on the page along with
    * mapping information for public render paramters. 
    * The portlet data is indexed by portlet ID.
    * @property   {PortletData} {string}  
    *    The object holds one portlet data object for each portlet. The string
    *    property name is the portlet ID.
    * @property   {prpMap} {"<groupIndex>" : {"pid" : "<prpName>"}}  
    * @private
    */
   pageState = {},
   
   /**
    * Flag specifying whether history is to be processed (true if browser supports HTML5 session history APIs)
    * @property   {boolean} doHistory
    * @private
    */
    doHistory = (window.history && window.history.pushState),
   
   /**
    * Callback function provided to the portlet hub to allow the the implementation
    * to initiate an unsolicited portlet state update for an array of portlet IDs.
    * @param   {string[]}  pid      An array of portlet IDs
    * @returns {void}
    * @function
    * @private
    */
   updateWhenIdle,
   
   
   /**
    * Determines if the specified portlet ID is present.
    * @param   {string}    pid      The portlet ID
    * @returns {boolean}            true if the portlet ID can be found
    * @function
    * @private
    */
   isValidId = function (pid) {
      var id;
      for (id in pageState.portlets) {
         if (pageState.portlets.hasOwnProperty(id)) {
            if (pid === id) {
               return true;
            }
         }
      }
      return false;
   },

   /**
    * get the available portlet IDs in an array 
    */
   getIds = function () {
      var id, ids = [];
      for (id in pageState.portlets) {
         if (pageState.portlets.hasOwnProperty(id)) {
            ids.push(id);
         }
      }
      return ids;
   },
      
   /**
    * gets parameter value
    */
   getParmVal = function (pid, name) {
      return pageState.portlets[pid].state.parameters[name];
   },

   /**
    * Compares the values of two parameters and returns true if they are equal
    *
    * @param {string[]} parm1 First parameter
    * @param {string[]} parm2 2nd parameter
    * @returns {boolean} true if the new parm value is equal to the current value
    * @private
    */
   _isParmEqual = function(parm1, parm2) {
      var ii;

      // The values are either string arrays or undefined.

      if ((parm1 === undefined) && (parm2 === undefined)) {
         return true;
      }
      
      if ((parm1 === undefined) || (parm2 === undefined)) {
         return false;
      }
      
      if (parm1.length !== parm2.length) {
         return false;
      }
      
      
      for (ii = parm1.length - 1; ii >= 0; ii--) {
         if (parm1[ii] !== parm2[ii]) {
            return false;
         }
      }

      return true;
   },
   
   
   /**
    * Returns true if input state differs from the current page state.
    * Throws exception if input state is malformed.
    */
   stateChanged = function (nstate, pid) {
      var ostate, pname, nparm, oparm, result = false;
      
      ostate = pageState.portlets[pid].state;
      
      if (!nstate.portletMode || !nstate.windowState || !nstate.parameters) {
         throw new Error ("Error decoding state: " + nstate);
      }
      
      if (nstate.portletMode !== ostate.portletMode) {
         result = true;
      } else {
         if (nstate.windowState !== ostate.windowState) {
            result = true;
         } else {
            
            // Has a parameter changed or been added?
            for (pname in nstate.parameters) {
               if (nstate.parameters.hasOwnProperty(pname)) {
                  nparm = nstate.parameters[pname];
                  oparm = ostate.parameters[pname];
                  if (!_isParmEqual(nparm, oparm)) {
                     result = true;
                  }
               }
            }
            
            // make sure no parameter was deleted
            for (pname in ostate.parameters) {
               if (ostate.parameters.hasOwnProperty(pname)) {
                  if (!nstate.parameters[pname]) {
                     result = true;
                  }
               }
            }
         }
      }
      
      return result;
   },

   /**
    * Compares the values of the named parameter in the new portlet state
    * with the values of that parameter in the current state.
    *
    * @param      {string}       pid      The portlet ID
    * @param      {PortletState} state    The new portlet state
    * @param      {string}       name     The parameter name to check
    * @returns    {boolean}               true if the new parm value is different
    *                                     from the current value
    * @private
    */
   isParmInStateEqual = function (pid, state, name) {
      var newVal = state.parameters[name], oldVal = getParmVal(pid, name);

      return _isParmEqual(newVal, oldVal);
   },
      
   /**
    * gets defeined PRPs for the portlet
    */
   getPRPNames = function (pid) {
      return pageState.portlets[pid].pubParms;
   },
   
   /**
    * function for checking if the parameter is public
    */
   isPRP = function (pid, name) {
      var prp, result = false, prps = pageState.portlets[pid].pubParms;
      for (prp in prps) {
         if (prps.hasOwnProperty(prp)) {
            if (name === prp) {
               result = true;
            }
         }
      }
      return result;
   },


   /**
    * Gets the updated public parameters for the given portlet
    * ID and new portlet state.
    * Returns an object whose properties are the gruop indexes of the
    * updated public parameters. The values are the new public
    * parameter values.
    *
    * @param      {string}       pid      The portlet ID
    * @param      {PortletState} state    The new portlet state
    * @returns    {object}                object containing the updated PRPs
    * @private
    */
   getUpdatedPRPs = function (pid, state) {
      var prps = {}, prpNames = getPRPNames(pid), name, group;

      for (name in prpNames) {
         if (prpNames.hasOwnProperty(name)) {
            if (isParmInStateEqual(pid, state, name) === false) {
               group = prpNames[name];
               prps[group] = state.parameters[name];
            }
         }
      }

      return prps;
   },

      
   /**
    * Returns a deep-copy clone of the input portlet state object.
    * Used to provide the portlet client with a copy of the current 
    * state data rather than a reference to the live state itself.
    * 
    * @param      {PortletState} state    The portlet state object to check
    * @returns    {PortletState}          Clone of the input portlet state
    * @private
    */
   cloneState = function (aState) {
      var newParams = {},
      newState = {
            portletMode : aState.portletMode,
            windowState : aState.windowState,
            parameters : newParams
      }, key, oldParams = aState.parameters;
   
      for (key in oldParams) {
         if (oldParams.hasOwnProperty(key)) {
            newParams[key] = oldParams[key].slice(0);
         }
      }
   
      return newState;
   },

   /**
    * Get allowed window states for portlet
    */
   getAllowedWS = function (pid) {
      return pageState.portlets[pid].allowedWS.slice(0);
   },
   
   /**
    * Get allowed portlet modes for portlet
    */
   getAllowedPM = function (pid) {
      return pageState.portlets[pid].allowedPM.slice(0);
   },
   
   
   /**
    * gets render data for the portlet
    */
   getRenderData = function (pid) {
      return pageState.portlets[pid].renderData;
   },
         
   /**
    * gets state for the portlet
    */
   getState = function (pid) {
      return pageState.portlets[pid].state;
   },
   
   /**
    * Function to encode url tokens as Pluto likes it
    */
   plutoEncode = function (istr) {
      var ENCODINGS = {
            "_" :  "0x1",
            "." :  "0x2",
            "/" :  "0x3",
            "\r" : "0x4",
            "\n" : "0x5",
            "<" :  "0x6",
            ">" :  "0x7",
            " " :  "0x8",
            "#" :  "0x9",
            "?" :  "0xa",
            "\\" : "0xb",
            "%" :  "0xc",
            "|" :  "%7C"
                      }, ii, ostr = "";
      
      for (ii=0; ii < istr.length; ii++) {
         if (ENCODINGS[istr.charAt(ii)]) {
            ostr += ENCODINGS[istr.charAt(ii)];
         } else {
            ostr += istr.charAt(ii);
         }
      }

      return ostr;
   },
   
   
   // Constants used for URL Encoding/Decoding (copied from Pluto impl code)  ----------

   PREFIX = "__",
   DELIM = "_",
   PORTLET_ID = "pd",
   ACTION = "ac",
   RESOURCE = "rs",
   RESOURCE_ID = "ri",
   CACHE_LEVEL = "cl",
   RENDER_PARAM = "rp",
   PRIVATE_RENDER_PARAM = "pr",
   PUBLIC_RENDER_PARAM = "sp",
   WINDOW_STATE = "ws",
   PORTLET_MODE = "pm",
   VALUE_DELIM = "0x0",

   AJAX_ACTION = "aa",              // new for portlet spec 3
   PARTIAL_ACTION = "pa",           // new for portlet spec 3
   
   pidMap = {},
   
   /**
    * Set up the portlet ID mapping table for URL generation
    */
   getPidMap = function () {
      var pid, pids = getIds(), ii, urlmap = "";
      
      pidMap = {};
      for (ii = 0; ii < pids.length; ii++) {
         pid = pids[ii];
         pidMap[pid] = ii;
         urlmap += "/" + PREFIX + PORTLET_ID;
         urlmap += plutoEncode(pageState.portlets[pid].urlpid);
         urlmap += DELIM + ii;
      }
      
      return urlmap;
   },

   
   /**
    * Helper for generating parameter strings for the URL
    */
   genParmString = function (pid, name, type, group) {
      var vals, jj, sep, str = "", wid = "", grpstr = "";
      vals = pageState.portlets[pid].state.parameters[name];
      
      // If encoding a render parameter, insert the pid in Pluto internal form 
      // as opposed to namespace form -
      
      if (type === RENDER_PARAM || type === PUBLIC_RENDER_PARAM) {
         wid = pidMap[pid];
      }
      
      if (type === PUBLIC_RENDER_PARAM) {
         grpstr = DELIM + plutoEncode(group);
      }
      
      // If values are present, encode the multivalued parameter string
      
      if (vals) {
         sep = VALUE_DELIM;
         str += "/" + PREFIX + type + wid + grpstr + DELIM + encodeURIComponent(name);
         for (jj=0; jj < vals.length; jj++) {
            str += sep + encodeURIComponent(vals[jj]);
         }
      }
      return str;
   },
   
   
   /**
    * Helper for generating portlet mode & window state strings for the URL
    */
   genPMWSString = function (pid) {
      var pm = pageState.portlets[pid].state.portletMode, 
          ws = pageState.portlets[pid].state.windowState, 
          wid = pidMap[pid], str = "";

      str += "/" + PREFIX + PORTLET_MODE + wid + DELIM + encodeURIComponent(pm);
      str += "/" + PREFIX + WINDOW_STATE + wid + DELIM + encodeURIComponent(ws);

      return str;
   },
   
   
   /**
    * Returns a URL of the specified type.
    * 
    * @param   {string}    type     The URL type
    * @param   {string}    pid      The portlet ID
    * @param   {PortletParameters}    parms      
    *                Additional parameters. May be <code>null</code>
    * @param   {string}    cache    Cacheability. Must be present if 
    *                type = "RESOURCE". May be <code>null</code> 
    * @private 
    */
   getUrl = function (type, pid, parms, cache) {
   
      var url = portlet.impl.getUrlBase(), ca = 'cacheLevelPage', parm, isAction = false,
          sep = "", name, names, vals, ii, str, id, ids, tpid, prpstrings, group;
          
      url += getPidMap();
       
      // If target portlet not defined for render URL, set it to null
      if ((type === "RENDER") && pid === undefined) {
         pid = null;
      }

      // First add the appropriate window identifier according to URL type.
      // Note that no special window ID is added to a RENDER URL. 
      
      if (type === "RESOURCE") {
         // If generating resource URL, add resource window & cacheability
         url += "/" + PREFIX + RESOURCE + pidMap[pid];
         if (cache) {
            ca = cache;
         }
         url += "/" + PREFIX + CACHE_LEVEL + plutoEncode(ca);
      } else if (type === "ACTION") {
         // Add Ajax Action window
         isAction = true;
         url += "/" + PREFIX + AJAX_ACTION + pidMap[pid];
      } else if (type === "PARTIAL_ACTION") {
         // Add Partial Action window
         isAction = true;
         url += "/" + PREFIX + PARTIAL_ACTION + pidMap[pid];
      }
      
      // Now add the state to the URL, taking into account cacheability if
      // we're dealing with a resource URL. 

      // Put the private & public parameters on the URL if cacheability != FULL
      if ((type !== "RESOURCE") || (ca !== "cacheLevelFull")) {

         // If cacheability = PAGE, add the state for the non-target portlets
         if ((type !== "RESOURCE") || (ca === "cacheLevelPage")) {

            ids = getIds();
            for (ii = 0; ii < ids.length; ii++) {
               id = ids[ii];
               if (id !== pid) {  // only for non-target portlets
                  url += genPMWSString(id);  // portlet mode & window state
                  str = "";
                  names = pageState.portlets[id].state.parameters;
                  for (name in names) {
                     // Public render parameters are encoded separately
                     if (names.hasOwnProperty(name) && !isPRP(id, name)) {
                        str += genParmString(id, name, RENDER_PARAM);
                     }
                  }
                  url += str;
               }
            }

         }

         // add the state for the target portlet for on-action urls.
         // (Action URLs have only action parameters in the query string)
         // (for a render URL, pid can be null)
         if (!isAction && pid !== null) {
            url += genPMWSString(pid);  // portlet mode & window state
            str = "";
            names = pageState.portlets[pid].state.parameters;
            for (name in names) {
               // Public render parameters are encoded separately
               if (names.hasOwnProperty(name) && !isPRP(pid, name)) {
                  str += genParmString(pid, name, PRIVATE_RENDER_PARAM);
               }
            }
            url += str;
         }

         // Add the public render parameters for all portlets

         str = "";
         prpstrings = {};
         for (group in pageState.prpMap) {
            if (pageState.prpMap.hasOwnProperty(group)) {
               for (tpid in pageState.prpMap[group]) {
                  if (pageState.prpMap[group].hasOwnProperty(tpid)) {
                     name = pageState.prpMap[group][tpid];
                     // only need to add parameter once, since it is shared
                     if (!prpstrings.hasOwnProperty(group)) {
                        prpstrings[group] = genParmString(tpid, name, PUBLIC_RENDER_PARAM, group);
                        str += prpstrings[group];
                     }
                  }
               }
            }
         }
         url += str;

      }

      // Encode resource or action parameters as query string
      if (parms) {
         str = ""; sep = "?";
         for (parm in parms) {
            if (parms.hasOwnProperty(parm)) {
               vals = parms[parm];
               for (ii=0; ii < vals.length; ii++) {
                  str += sep + encodeURIComponent(parm) + "=" + encodeURIComponent(vals[ii]);
                  sep = "&";
               }
            }
         }
         url += str;
      }

      // Use Promise to allow for potential server communication - 
      return new Promise(function (resolve) {
         resolve(url);
      });
   },
   
   /**
    * Called when the page state has been updated to allow the
    * browser history to be taken care of.
    * @param      {boolean} replace    replace the state rather than pushing
    */
   updateHistory = function (replace) {
      if (doHistory) {
         getUrl('RENDER', null, {}).then(function (url) {
            var token = JSON.stringify(pageState);
            console.log("Updating history. URL =" + url + ", token length =" + token.length 
               + ", token 30 chars =" + token.substring(0,30));
            if (replace) {
               history.replaceState(token, "");
            } else {
               history.pushState(token, "", url);
            }
         });
      }
   },
   
   /**
    * sets state for the portlet. returns
    * array of IDs for portlets that were affected by the change, 
    * taking into account the public render parameters.
    */
   setState = function (pid, state) {
      var prps = getUpdatedPRPs(pid, state), group, tpid, upids = [], newVal, prpName, groupMap;
         
      // For each updated PRP group for the
      // initiating portlet, update that PRP in the other portlets.
      for (group in prps) {
         if (prps.hasOwnProperty(group)) {
      
            newVal = prps[group];
            
            // access the PRP map to get the affected portlets
            groupMap = pageState.prpMap[group];
            for (tpid in groupMap) {
               if (groupMap.hasOwnProperty(tpid) && (tpid !== pid)) {
                  prpName = groupMap[tpid];
                  
                  if (newVal === undefined) {
                     delete pageState.portlets[tpid].state.parameters[prpName];
                  } else {
                     pageState.portlets[tpid].state.parameters[prpName] = newVal.slice(0);
                  }
                  upids.push(tpid);
                  
               }
            }
         }
      }
      
      // update state for the initiating portlet
      pageState.portlets[pid].state = state;
      upids.push(pid);
      
      updateHistory();

      
      // Use Promise to allow for potential server communication - 
      return new Promise(function (resolve, reject) {
         var simval = '';
         if (pid === 'SimulateCommError' && state.parameters.SimulateError !== undefined) {
            simval = state.parameters.SimulateError[0];
         }

         // reject promise of an error is to be simulated
         if (simval === 'reject') {
            reject(new Error("Simulated error occurred when setting state!"));
         } else {
            resolve(upids);
         }
      });
   },

   
   // decodes the update strings. The update string is 
   // a JSON object containing the entire page state. This decoder 
   // returns an object containing the state for portlets whose 
   // state has changed as compared to the current page state.
   decodeUpdateString = function (ustr) {
      var states = {}, ostate, nstate, pid, ps, npids = 0, cpids = 0;
      
      console.log("Decoding string: >>" + ustr + "<<");

      ps = JSON.parse(ustr);
      for (pid in ps.portlets) {
         if (ps.portlets.hasOwnProperty(pid)) {
            npids++;
            nstate = ps.portlets[pid].state;
            ostate = pageState.portlets[pid].state;
            
            if (!nstate || !ostate) {
               throw new Error ("Invalid update string. ostate=" + ostate + ", nstate=" + nstate);
            }
            
            if (stateChanged(nstate, pid)) {
               states[pid] = cloneState(nstate);
               cpids++;
            }
         }
      }
      
      console.log("decoded state for " + npids + " portlets. # changed = " + cpids);
      
      return states;
   },

      
   /**
    * updates page state from string and returns array of portlet IDs
    * to be updated.
    * 
    * @param   {string}    ustr     The 
    * @param   {string}    pid      The portlet ID
    * @private 
    */
   updatePageStateFromString = function (ustr, pid) {
      var states, tpid, state, upids = [], stateUpdated = false;

      states = decodeUpdateString(ustr);

      // Update states and collect IDs of affected portlets. 
      for (tpid in states) {
         if (states.hasOwnProperty(tpid)) {
            state = states[tpid];
            pageState.portlets[tpid].state = state;
            upids.push(tpid);
            stateUpdated = true;
         }
      }
      
      // pid will be null or undefined when called from onpopstate routine.
      // In that case, don't update history.
      if (stateUpdated && pid) {
         updateHistory();
      }

      return upids;
   },
   
   
   /**
    * Update page state passed in after partial action. The list of 
    * ID's of updated portlets is passed back through a promise in order
    * to decouple the layers.
    * 
    * @param   {string}    ustr     The 
    * @param   {string}    pid      The portlet ID
    * @private 
    */
   updatePageState = function (ustr, pid) {
            
      // Use Promise to allow for potential server communication - 
      return new Promise(function (resolve, reject) {
         var upids;
               
         try {
            upids = updatePageStateFromString(ustr, pid);
            resolve(upids);
         } catch (e) {
            reject(new Error("Partial Action Action decode status: " + e.message));
         }
      });

   },
   
   /**
    * function to extract data from form and encode it as an 'application/x-www-form-urlencoded' string
    * 
    * @param   {HTMLFormElement}  form    Form to be submitted
    * @private 
    */
   encodeFormAsString = function (form) {
      var fstr = "", parm, parms = [], ii, jj, el, name, val, tag, type;
      for (ii = 0; ii < form.elements.length; ii++) {
         el = form.elements[ii];
         name = el.name;
         val = el.value;
         tag = el.nodeName.toUpperCase();
         if (tag === 'INPUT') {
            type = el.type.toUpperCase();
         } else {
            type = "";
         }
         // we don't support file type with enctype = 'application/x-www-form-urlencoded' (hub checks for this case)
         if (name && !el.disabled && (type !== 'FILE')) {
            if ((tag === 'SELECT') && (el.multiple === true)) {
               // multiple select boxes need to be handled differently
               for (jj = 0; jj < el.options.length; jj++) {
                  if (el.options[jj].checked) {
                     val = el.options[jj].value;
                     parm = encodeURIComponent(name) + '=' + encodeURIComponent(val);
                     parms.push(parm);
                  }
               }
            } else {
               if (((type !== 'CHECKBOX') && (type !== 'RADIO')) || (el.checked === true)) {
                  parm = encodeURIComponent(name) + '=' + encodeURIComponent(val);
                  parms.push(parm);
               }
            }
         }
      }
      fstr = parms.join('&');
      return fstr;
   },

      
   /**
    * performs the actual action.
    * 
    * @param   {string}    pid      The portlet ID
    * @param   {PortletParameters}    parms      
    *                Additional parameters. May be <code>null</code>
    * @param   {HTMLFormElement}    Form to be submitted
    *                               May be <code>null</code> 
    * @private 
    */
   executeAction = function (pid, parms, element) {

      console.log("impl: executing action. parms=" + parms + ", element=" + element);

      // create & return promise to caller. 

      return new Promise(function (resolve, reject) {

         // get the ajax action URL. The Pluto impl creates the URL in JS
         // therefore no error handling 
         getUrl("ACTION", pid, parms).then(function (url) {
            var xhr, upids, fd, method = 'POST', enctype, fstr;

            console.log("ajax action URL: " + url);
            
            xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function () {
               if (xhr.readyState === 4) {
                  if (xhr.status === 200) {
                     try {
                        upids = updatePageStateFromString(xhr.responseText, pid);
                        resolve(upids);
                     } catch (e) {
                        reject(new Error("Ajax Action decode status: " + e.message));
                     }
                  } else {
                     reject(new Error("Ajax Action xhr status: " + xhr.statusText));
                  }
               }
            };
            
            if (element) {
               enctype = element.enctype;
               if (enctype === 'multipart\/form-data') {
                  // multipart/form-data is always POSTed using FormData 
                  fd = new FormData(element);
                  console.log("ajax action: POST using FormData object: " + fd);
                  xhr.open(method, url, true);
                  xhr.send(fd);
               } else {
                  // has to be 'application\/x-www-form-urlencoded', as the hub does not support text/plain
                  method = element.method ? element.method.toUpperCase() : 'GET';      // may be GET or POST; GET is default
                  fstr = encodeFormAsString(element);
                  console.log("ajax action: " + method + " using urlencoded form data: " + fstr);
                  if (method === 'GET') {   
                     // send form data as part of URL
                     if (url.indexOf('?') >= 0) {
                        url += '&' + fstr;
                     } else {
                        url += '?' + fstr;
                     }
                     xhr.open(method, url, true);
                     xhr.send();
                  } else {
                     // has to be post, since we only support GET & POST
                     xhr.open(method, url, true);
                     xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                     xhr.setRequestHeader('Content-Length', fstr.length);
                     xhr.send(fstr);
                  }
               }
            } else {
               xhr.open(method, url, true);
               console.log("ajax action: POST using URL with parameters");
               xhr.send();
            }
         });
            
      });

   };
   
   /**
    * Handler for history event that is fired when the back button is pressed.
    */
   if (doHistory) {
      window.addEventListener('popstate', function (ev) {
         if (ev.state) {
            console.log("onpopstate fired. State = " + ev.state.substr(0, 30) + " ...<more>");
            updateWhenIdle().then(function (doUpdate) {
               var upids = updatePageStateFromString(ev.state);
               doUpdate(upids);
            });
         }
      });
   }

   
   /**
    * Register a portlet. The impl is passed the portlet ID for the portlet.
    * The impl must retrieve the information for the portlet in an appropriate
    * manner. It must return a Promise that is fulfilled when data for the 
    * portlet becomes available and is rejected if an error occurs or if the
    * portlet ID is invalid.
    * 
    * @param   {string}    pid      Portlet ID
    * 
    * @returns {Promise}            fulfilled when data is available
    * 
    * @function
    * @private
    */
   portlet.impl = portlet.impl || {};
   portlet.impl.register = function (pid, updateFunction) {

      // take care of moc data initialization      
      if (!isInitialized) {
         pageState = portlet.impl.getInitData();
         updateHistory(true);
         isInitialized = true;
      }
      
      updateWhenIdle = updateFunction;

      // stubs for accessing data for this portlet
      var stubs = {
   
         /**
          * Get allowed window states for portlet
          */
         getAllowedWS : function () {return getAllowedWS(pid);},
   
         /**
          * Get allowed portlet modes for portlet
          */
         getAllowedPM : function () {return getAllowedPM(pid);},
   
         /**
          * Get render data for portlet, if any
          */
         getRenderData : function () {return getRenderData(pid);},
   
         /**
          * Get current portlet state
          */
         getState : function () {return getState(pid);},
   
         /**
          * Set new portlet state. Returns promise fullfilled with an array of
          * IDs of portlets whose state have been modified.
          */
         setState : function (state) {return setState(pid, state);},
   
         /**
          * Perform the Ajax action request
          */
         executeAction : function (parms, element) {return executeAction(pid, parms, element);},
   
         /**
          * Get a URL of the specified type - resource or partial action
          */
         getUrl : function (type, parms, cache) {return getUrl(type, pid, parms, cache);},
   
         /**
          * Decode the update string returned by the partial action request.
          * Returns array of IDs of portlets to be updated.
          */
         decodeUpdateString : function (ustr) {return updatePageState(ustr, pid);}
   
      };            
      
      return new Promise(
         function(resolve, reject) {
            
            // verify the input pid 
            if (isValidId(pid)) {
               
               switch(pid) {
               case 'SimulateLongWait':
                  window.setTimeout(function () {resolve(stubs);}, 500);
                  break;
               case 'SimulateError':
                  window.setTimeout(function () {reject(new Error("Bad error happened!"));}, 100);
                  break;
               default:
                  window.setTimeout(function () {resolve(stubs);}, 10);
               }
               
            } else {
               reject(new Error("Invalid portlet ID: " + pid));
            }
         }
      );
   };
   
   // Expose some internal functions for test purposes - 
   
   portlet.test = {
      getIds : getIds
   }; 
   
}());
