api.require({
  namespace: ["sol"]
}, function () {

  /**
	 * This is a utility class for user interaction.
	 */
  sol.define("sol.common.web.ApiUtils", {
    singleton: true,
    /**
     * Finds a users workflow node based on its flowId and nodeId.
     * Since collecting tasks is expensive, the guid should be passed in order to limit search results.
     * A maximum of 100 tasks is retrieved in order to find the required node.
     *
     * @param {String} guid
     * @param {String} flowId
     * @param {String} nodeId
     * @param {Object} successFct
     * @param {Object} failureFct
     */
    getWfNode: function (guid, flowId, nodeId, successFct, failureFct) {
      var findTaskInfo = new de.elo.ix.client.FindTasksInfo();
      findTaskInfo.allUsers = false;
      findTaskInfo.inclWorkflows = true;
      findTaskInfo.objId = guid;
      findTaskInfo.highestPriority = elo.CONST.USER_TASK_PRIORITY.HIGHEST;
      findTaskInfo.lowestPriority = elo.CONST.USER_TASK_PRIORITY.LOWEST;
      findTaskInfo.sortOrder = elo.CONST.USER_TASK_SORT_ORDER.PRIORITY_DATE_NAME_INV;

      elo.IX.ix().findFirstTasks(findTaskInfo, 100, new de.elo.ix.client.AsyncCallback(function (findResult) {
        // success
        var tasks = findResult.tasks,
            task, i;
        for (i = 0; i < tasks.length; i++) {
          task = tasks[i];
          if (task.wfNode.flowId === flowId && task.wfNode.nodeId === nodeId) {
            successFct.call(this, task.wfNode);
            return;
          }
        }
        if (failureFct) {
          failureFct.call(this, "Workflow node not found.");
        }
      }, function (ex) {
        if (failureFct) {
          failureFct.call(this, ex);
        }
      }));
    },

    /**
     * Displays an info box.
     * @param {String} msg
     */
    showInfoMessage: function (msg) {
      elo.ModelRegistry.setDataInstance({
        scope: this,
        id: elo.ModelRegistry.getModelConstant("logMessage"),
        obj: {
          displayType: "window",
          type: "info",
          title: "",
          bodyTitle: msg
        }
      });
    },

    /**
     * Displays a toast/ message popup.
     * @param {String} msg
     */
    showPopupMessage: function (msg) {
      var me = this;

      elo.ModelRegistry.setDataInstance({
        scope: me,
        id: elo.ModelRegistry.getModelConstant("logMessage"),
        obj: {
          displayType: "popup",
          bodyTitle: msg
        }
      });
    }
  });
});

//# sourceURL=sol.common.web.ApiExtensions.js


api.require({
  namespace: ["sol"]
}, function () {

  var chars = [],
      pressed = false,
      timeout,
      minBarcodeLength;

  /**
   * @private
   *
   * This is an experimental class that might change in the future.
   * Don't rely on its existance.
   */
  sol.define("sol.common.web.BarcodeHandler", {
    singleton: true,

    initialize: function (config) {
      var me = this;
      me.$super("sol.Base", "initialize", arguments);

      window.addEventListener("keypress", me.handleKeyEvent);
      timeout = me.timeout;
      minBarcodeLength = me.minBarcodeLength;
    },

    /**
     * @cfg {Number} minimum amount of characters that identifies a barcode.
     */
    minBarcodeLength: 10,
    /**
     * @cfg {Number} timout in ms for the barcode sequence.
     */
    timeout: 500,

    handleKeyEvent: function (e) {
      chars.push(String.fromCharCode(e.which));
      if (pressed == false) {
        setTimeout(function () {
          if (chars.length >= minBarcodeLength) {
            var barcode = chars.join("");
            sol.common.web.BarcodeHandler.handleBarcode(barcode);
          }
          chars = [];
          pressed = false;
        }, timeout);
      }
      pressed = true;
    },
    handleBarcode: function (barcode) {
      var me = this,
          regex, guid, objId;
      me.logger.info("Barcode scanned: " + barcode);
      // if barcode was regognized in child component,
      // redirect to parent handler.
      if (api &&
          api.communication &&
          api.communication.Parent &&
          api.communication.Parent.hasParent()) {
        me.logger.info("Barcode scanned within child component. Redirect to parent.");

        // not implemented yet.

        return;
      }

      if (barcode.indexOf("elodms") == 0) {
        // handle wrong char set by some barcode readers [- equals ?ß]
        if (barcode.indexOf("elodmsÖ--") == 0) {
          barcode = barcode.replace(/[?ß]/g, "-");
        }
        regex = /[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}/i.exec(barcode);
        if (regex) {
          guid = "(" + regex[0] + ")";
          me.logger.info("Barcode contains elodms link. Goto element with GUID: " + guid);
          try {
            objId = elo.IX.ix().checkoutSord(guid, elo.CONST.SORD.mbOnlyId, elo.CONST.LOCK.NO).id;
            api.Webclient.gotoEntry(objId);
          } catch (e) {
            me.logger.info("Object not found for GUID: " + guid);
          }
        } else {
          me.logger.info("Barcode contains wrong guid format: " + guid);
        }
      } else if (sol.common.web.BarcodeRegistry.isValidBarcode(barcode)) {
        sol.common.web.BarcodeRegistry.execute(barcode);
      }
    }

  });

});


api.require({
  namespace: ["sol"]
}, function () {

  /**
   * @private
   *
   * This is an experimental class that might change in the future.
   * Don't rely on its existance.
   */
  sol.define("sol.common.web.BarcodeRegistry", {
    singleton: true,
    splitCharacter: ".",

    /**
     * @property registered barcode handlers
     * @private
     */
    registeredHandlers: {},

    /**
     * registers a new handler for incoming barcodes.
     * @param {String} identifier
     * @param {String} name name for the barcode handler
     * @param {function} handler
     */
    register: function (identifier, name, handler) {
      var me = this;
      me.logger.info(["Register handler '{1}' for identifier '{0}'.", identifier, name]);
      if (me.registeredHandlers.hasOwnProperty(identifier)) {
        me.logger.warn(["Override exisiting barcode handler for {0}.", identifier]);
      }
      me.registeredHandlers[identifier] = {
        name: name,
        handler: handler
      };
    },

    /**
     * processes and executes a barcode by its handler.
     * @param {String} barcode
     * @return {Boolean}
     */
    execute: function (barcode) {
      var me = this,
          parts,
          objId,
          identifier;

      if (!me.isValidBarcode(barcode)) {
        return false;
      }

      parts = barcode.split(me.splitCharacter);
      identifier = parts[0];
      objId = Number.parseFloat(parts[1]) || undefined;

      if (me.registeredHandlers.hasOwnProperty(identifier)
              && me.registeredHandlers[identifier].handler) {
        me.registeredHandlers[identifier].handler.call(me, identifier, objId, {
          parts: parts,
          barcode: barcode
        });
      } else {
        sol.common.web.ApiUtils.showPopupMessage("No handler found for barcode");
      }
      return true;
    },

    /**
     * checks if a given barcode is a valid source for executing actions.
     * @param {String} barcode
     * @return {Boolean}
     */
    isValidBarcode: function (barcode) {
      var me = this;
      return (barcode.indexOf(me.splitCharacter) > 0);
    }
  });
});

api.require({
  namespace: ["sol"],
  locales: ["sol.common.client.ActionHandler"]
}, function (locales) {

  /**
   * This class provides helper functions for executing complex actions.
   *
   * @elojc
   * @requires sol.common.web.ActionHandler
   */
  sol.define("sol.common.web.ActionHelper", {
    singleton: true,

    executeSimpleAction: function (objId, cfg) {
      var me = this,
          cfgObject;

      elo.helpers.Console.info("[sol.common.web.ActionHelper] executing advanced action on objId: " + objId, cfg);

      if (!cfg || !cfg.fct) {
        throw "executing a simple action requires mandatory config properties.";
      }

      cfgObject = (cfg.cfgTemplate) ? me.getConfigObject(cfg.cfgTemplate, me.initActionCfg(objId)) : {};

      sol.common.web.ActionHandler.execute(
        cfg.fct,
        cfgObject
      );
    },

    /**
     * Helps in executing advanced actions that include precondition checks and
     * different object types.
     *
     * Advanced action configurations are handled in the following order:
     *
     * 1.  select types (optional)
     * 2.  check preconditions (type selection possible if returned by check) (optional)
     * 3.  select target (optional)
     * 4.  execute action (IX/ AS) (required)
     *
     * Please note that step 1 and 2 can be used for selecting types. If a special function
     * is used for type selection (Step 1), the user selection is overriden if a second
     * type selection is handled by step 2.
     *
     *     {
     *       preconditions: {
     *         fct: 'RF_sol_contact_service_CheckContactPreconditions',
     *       },
     *       fct: 'RF_sol_contact_action_CreateContact',
     *       cfgTemplate: '{
     *              "parentId": "{{objId}}",
     *              "contactType": "{{type.name}},
     *              "templateId": "{{type.objId}}
     *       }',
     *       locale: {
     *           errorDlgTitle: locale['sol.contact.client.contact.create.dialog.error.title'],
     *           typesDlgTitle: locale['sol.contact.client.contact.create.dialog.title'],
     *           typesDlgHeader: locale['sol.contact.client.contact.create.dialog.header'],
     *           typesDlgText: locale['sol.contact.client.contact.create.dialog.text'],
     *           typesDlgNoTypes: locale['sol.contact.client.contact.create.msg.notype'],
     *
     *           targetDlgTitle: locale['sol.contact.client.contact.create.dialog.title'],
     *           targetDlgHeader: locale['sol.contact.client.contact.create.dialog.header'],
     *           targetDlgText: locale['sol.contact.client.contact.create.dialog.text'],
     *       }
     *     }
     *
     * @param {String} objId
     * @param {Object} cfg
     */
    executeAdvancedAction: function (objId, cfg) {
      var me = this,
          actionCfg = me.initActionCfg(objId),
          handler_selectTypes, handler_preconditions, handler_selectTarget, handler_executeAction;

      elo.helpers.Console.info("[sol.common.web.ActionHelper] executing advanced action on objId: " + objId, cfg);

      if (!cfg || !cfg.fct || !cfg.cfgTemplate) {
        throw "executing an advanced action requires mandatory config properties.";
      }

      actionCfg.buttonName = cfg.buttonName;

      // asynchronous calls require synchonisation between ajax responses.
      // therefore several handlers are linked.
      handler_selectTypes = function (objId, cfg, actionCfg) {
        if (cfg.selectType && cfg.selectType.fct) {
          // action requires precondition checks
          me.handleTypeSelection(objId, cfg, actionCfg, function (objId, cfg, actionCfg) {
            // preconditions handled
            handler_preconditions(objId, cfg, actionCfg);
          });
        } else {
          handler_preconditions(objId, cfg, actionCfg);
        }
      };
      handler_preconditions = function (objId, cfg, actionCfg) {
        if (cfg.preconditions && cfg.preconditions.fct) {
          // action requires precondition checks
          me.handlePrecondition(objId, cfg, actionCfg, function (objId, cfg, actionCfg) {
            // preconditions handled
            handler_selectTarget(objId, cfg, actionCfg);
          });
        } else {
          handler_selectTarget(objId, cfg, actionCfg);
        }
      };
      handler_selectTarget = function (objId, cfg, actionCfg) {
        if (cfg.selectTree) {
          me.handleTreeSelection(objId, cfg, actionCfg, function (objId, cfg, actionCfg) {
            handler_executeAction(objId, cfg, actionCfg);
          });
        } else {
          handler_executeAction(objId, cfg, actionCfg);
        }
      };
      handler_executeAction = function (objId, cfg, actionCfg) {
        me.handleExecuteAction(objId, cfg, actionCfg);
      };

      // call first handler
      handler_selectTypes(objId, cfg, actionCfg);
    },

    /**
     * @private
     * handles precondition checks for advanced actions.
     * @param {String} objId
     * @param {Object} cfg
     * @param {Object} actionCfg
     * @param {Object} readyFct
     */
    handlePrecondition: function (objId, cfg, actionCfg, readyFct) {
      var me = this;

      sol.common.IxUtils.execute(cfg.preconditions.fct, {
        targetId: objId
      }, function (checkResult) {
        // sucess
        elo.helpers.Console.info("[sol.common.web.ActionHelper] prepare action successful.", checkResult);

        if (checkResult.valid !== true) {
          elo.helpers.Console.info("[sol.common.web.ActionHelper] prepare action returned invalid result. Cancel execution.");
          api.Webclient.alert(cfg.locale.errorDlgTitle || locales["sol.common.client.ActionHandler.errordlg.title"], checkResult.msg);
          return;
        }

        if (checkResult.targetId && checkResult.targetId != objId) {
          elo.helpers.Console.info("[sol.common.web.ActionHelper] changed objId by preconditions to: " + checkResult.targetId);
          objId = checkResult.targetId;
        }

        actionCfg.objId = objId;
        actionCfg.preconditions = checkResult;

        if (checkResult.types && checkResult.types.length >= 0) {
          me.handleSimpleActionTypes(checkResult.types, objId, cfg, actionCfg, function (objId, cfg, actionCfg) {
            // call ready
            readyFct(objId, cfg, actionCfg);
          });
        } else {
          // call ready
          readyFct(objId, cfg, actionCfg);
        }
      }, function (error) {
        elo.helpers.Console.error("[sol.common.web.ActionHelper] prepare action returned an unexpected error.", error);
        api.Webclient.alert(cfg.locale.errorDlgTitle || locales["sol.common.client.ActionHandler.errordlg.title"], error.msg + ": " + error.details);
      });
    },

    /**
     * @private
     * handles simple selection of different types.
     * @param {String} types
     * @param {String} objId
     * @param {Object} cfg
     * @param {Object} actionCfg
     * @param {Object} readyFct
     */
    handleSimpleActionTypes: function (types, objId, cfg, actionCfg, readyFct) {
      var choices, type, i;

      if (types && types.length > 1) {
        choices = [];
        for (i = 0; i < types.length; i++) {
          type = types[i];
          choices.push({ title: type.name, text: type.desc, data: type });
        }

        elo.helpers.Console.info("[sol.common.web.ActionHelper] prepare action returned multiple type choices.", choices);
        api.Webclient.showCommandLinkDialog(
          cfg.locale.typesDlgTitle,
          cfg.locale.typesDlgHeader,
          cfg.locale.typesDlgText,
          choices,
          function (choice) { // selected type
            actionCfg.type = choice.data;
            // call ready
            readyFct(objId, cfg, actionCfg);
          }, function () { // clicked cancel
            elo.helpers.Console.info("[sol.common.web.ActionHelper] closed file selection dialog. cancel execution.");
          }
        );
      } else if (types && types.length > 0) {
        actionCfg.type = types[0];
        // call ready
        readyFct(objId, cfg, actionCfg);
      } else {
        api.Webclient.alert(cfg.locale.typesDlgTitle || locales["sol.common.client.ActionHandler.errordlg.title"], cfg.locale.typesDlgNoTypes);
      }
    },

    handleTypeSelection: function (objId, cfg, actionCfg, readyFct) {
      var me = this,
          typeServiceCfg = {};

      if (cfg.selectType && cfg.selectType.cfgTemplate) {
        typeServiceCfg = me.getConfigObject(cfg.selectType.cfgTemplate, actionCfg);
      }

      sol.common.IxUtils.execute(cfg.selectType.fct, typeServiceCfg, function (types) {
        // sucess
        me.handleSimpleActionTypes(types, objId, cfg, actionCfg, readyFct);
      }, function (error) {
        elo.helpers.Console.error("[sol.common.web.ActionHelper] prepare action returned an unexpected error.", error);
        api.Webclient.alert(cfg.locale.errorDlgTitle || locales["sol.common.client.ActionHandler.errordlg.title"], error.msg + ": " + error.details);
      });
    },

    handleTreeSelection: function (objId, cfg, actionCfg, readyFct) {
      var me = this,
          rootId = 1;

      if (cfg.selectTree.root) {
        rootId = elo.IX.ix().checkoutSord(cfg.selectTree.root, elo.CONST.SORD.mbOnlyId, elo.CONST.LOCK.NO).id;
      } else if (cfg.selectTree.rootFromCfgFile && cfg.selectTree.rootFromCfgProperty) {
        sol.common.IxUtils.execute("RF_sol_common_service_GetConfig", {
          objId: cfg.selectTree.rootFromCfgFile
        }, function (cfgResult) {
          // set root id and recall handleTreeSelection
          try {
            cfg.selectTree.root = me.getConfigObject(cfg.selectTree.rootFromCfgProperty, cfgResult);
            me.handleTreeSelection(objId, cfg, actionCfg, readyFct);
          } catch (msg) {
            api.Webclient.alert(locales["sol.common.client.ActionHandler.errordlg.title"], "Invalid configuration for tree selection. rootFromCfgProperty should return a valid json object. " + msg);
          }
        }, function (err) {
          //console.error(o);
        });
        return;
      }

      elo.helpers.Console.info("[sol.common.web.ActionHelper] action requires target selection. Using root: " + rootId);

      api.Webclient.showTreeSelectDialog(
        cfg.locale.treeDlgTitle || "",
        cfg.locale.treeDlgHeader || "",
        rootId,
        cfg.locale.treeDlgRootName || "..",
        function (selection) {
          // selected target
          actionCfg.tree = {
            name: selection.name,
            objId: selection.id
          };
          // call ready
          readyFct(objId, cfg, actionCfg);
        },
        function () {
          // canceled
        }
      );
    },

    prepareCfgObj: function (cfgTemplate, actionCfg) {
      var cfgObj, regex, objIdReplacement;

      cfgTemplate = cfgTemplate.replace(/\\{{/g, "{{");
      if (cfgTemplate.indexOf("\"{{objId}}\"") > -1) {
        regex = new RegExp("\"{{objId}}\"", "g");
        objIdReplacement = (actionCfg.objId) ? "\"" + actionCfg.objId + "\"" : null;
      } else {
        regex = new RegExp("{{objId}}", "g");
        objIdReplacement = (actionCfg.objId) ? actionCfg.objId : null;
      }
      cfgTemplate = cfgTemplate.replace(regex, objIdReplacement);

      cfgObj = cfgTemplate ? JSON.parse(cfgTemplate) : {};

      cfgObj.$templating = { $type: actionCfg.type, $tree: actionCfg.tree, $preconditions: actionCfg.preconditions };

      return cfgObj;
    },

    /**
     * @private
     * handles the final execution of the action.
     * @param {String} objId
     * @param {Object} cfg
     * @param {Object} actionCfg
     */
    handleExecuteAction: function (objId, cfg, actionCfg) {
      var me = this, cfgObj;

      cfgObj = me.prepareCfgObj(cfg.cfgTemplate, actionCfg); // render objId and setup serverside templating data

      switch (cfg.type) {
        case "AS":
          sol.common.web.ActionHandler.executeAs(cfg.solution, cfg.fct, cfgObj);
          break;
        default:
          sol.common.web.ActionHandler.execute(cfg.fct, cfgObj);
      }
    },

    initActionCfg: function (objId) {
      var actionCfg = { objId: objId };
      return actionCfg;
    },

    getConfigObject: function (cfgTemplate, data) {
      var str = Handlebars.compile(cfgTemplate)(data);
      return JSON.parse(str);
    }

  });


  /**
   * This class provides utility functions to call IX or AS functions and handle the response in a standardized way.
   *
   * @eloweb
   * @requires sol.common.IxUtils
   */
  sol.define("sol.common.web.ActionHandler", {
    singleton: true,

    /**
     * Executes a IX registered function and handles the response in a standardized way.
     *
     * If spezial handling is needed a custom callback can be spezified as parameter.
     * This callback get's the result Object of the registered function as only parameter.
     *
     * @param {String} registeredFunctionName
     * @param {Object} params (optional) The configuration object which will be send to the registered function
     * @param {Function} callback (optional) Should not be used anymore
     * @param {String} loadingMessage (optional) Message that is displayed while performing async operations.
     */
    execute: function (registeredFunctionName, params, callback, loadingMessage) {
      var me = this;

      me.showLoadingIndicator(loadingMessage);
      sol.common.IxUtils.execute(registeredFunctionName, params, function (resultObj) {
        if (callback && Object.prototype.toString.call(callback) === "[object Function]") {
          me.logger.warn("Use of 'callback' parameter is depricated and therefore not recommended.");
          callback.call(me, resultObj);
          me.hideLoadingIndicator();
          return;
        }
        if (resultObj) {
          me.handleEvents(resultObj.events);
          // loading indicator is hidden by event handler
        } else {
          me.hideLoadingIndicator();
        }
      }, function (err) {
        me.hideLoadingIndicator();
        // error
        var msg = "";
        if (err && err.msg) {
          msg = err.msg;
        }
        api.Webclient.alert(locales["sol.common.client.ActionHandler.errordlg.title.unexpected"], msg);
      });
    },

    executeAs: function (solutionName, asRuleName, params, callback, loadingMessage) {
      var me = this;

      me.showLoadingIndicator(loadingMessage);
      sol.common.IxUtils.execute("RF_sol_common_service_ExecuteAsAction", {
        solution: solutionName,
        action: asRuleName,
        config: params,
        connParams: {
          language: elo.IX.getLoginResult().clientInfo.language
        }
      }, function (resultObj) {
        if (resultObj && resultObj.content) {
          try {
            resultObj = JSON.parse(resultObj.content);
          } catch (ex) {
            if (!resultObj.events) {
              console.error(resultObj);
              me.hideLoadingIndicator();
              api.Webclient.alert(locales["sol.common.client.ActionHandler.errordlg.title.unexpected"], locales["sol.common.client.ActionHandler.errordlg.msg.unexpected"]);
              return;
            }
          }
        }
        if (resultObj && resultObj.events && resultObj.events.length > 0 && resultObj.events[0].ID && resultObj.events[0].ID === "ERROR") {
          // handle IX Exceptions
          console.error(resultObj);
          me.hideLoadingIndicator();
          if (resultObj.events[0].obj && resultObj.events[0].obj.msg) {
            var error = resultObj.events[0].obj.msg;
            api.Webclient.alert(locales["sol.common.client.ActionHandler.errordlg.title.unexpected"], error);
          }
          return;
        }
        if (callback && Object.prototype.toString.call(callback) === "[object Function]") {
          me.logger.warn("Use of 'callback' parameter is depricated and therefore not recommended.");
          callback.call(me, resultObj);
          me.hideLoadingIndicator();
          return;
        }
        if (resultObj && resultObj.events) {
          me.handleEvents(resultObj.events);
          // loading indicator is hidden by event handler
        } else {
          me.hideLoadingIndicator();
        }
      }, function (err) {
        // error
        api.Webclient.alert(locales["sol.common.client.ActionHandler.errordlg.title.unexpected"], locales["sol.common.client.ActionHandler.errordlg.msg.unexpected"]);
        console.error(err);
        me.hideLoadingIndicator();
      });
    },

    /**
     * @private
     * Handler for events passed by an Action. This function is called recursively for all events since event
     * handlers might perform async operations.
     * @param {Object} events
     * @param {Object} context
     */
    handleEvents: function (events, context) {
      var me = this,
          eventTypes = sol.common.IxUtils.CONST.EVENT_TYPES,
          event, handler;

      context = context || { dirtySord: true, dirtyWfStatus: true };

      if (events && events.length > 0) {
        event = events.shift();

        if (!me.checkExecution(event, context)) {
          me.handleEvents(events, context);
          return;
        }

        switch (event.ID) {
          case eventTypes.REFRESH:
            handler = sol.create("sol.common.web.ActionHandler.Refresh");
            me.hideLoadingIndicator();
            break;
          case eventTypes.GOTO:
            handler = sol.create("sol.common.web.ActionHandler.Goto");
            me.hideLoadingIndicator();
            break;
          case eventTypes.DIALOG:
            handler = sol.create("sol.common.web.ActionHandler.Dialog", {
              actionHandler: me,
              hideLoadingIndicator: me.hideLoadingIndicator
            });
            // loading indicator is hidden by Action Handler
            break;
          case eventTypes.ACTION:
            handler = sol.create("sol.common.web.ActionHandler.Action", {
              actionHandler: me,
              hideLoadingIndicator: me.hideLoadingIndicator
            });
            // loading indicator is hidden by Action Handler
            break;
          case eventTypes.FEEDBACK:
            handler = sol.create("sol.common.web.ActionHandler.Feedback");
            me.hideLoadingIndicator();
            break;
          case eventTypes.ERROR:
            handler = sol.create("sol.common.web.ActionHandler.Error");
            me.hideLoadingIndicator();
            break;
          default:
        }

        if (handler && me.isFunction(handler.execute)) {
          handler.execute(event, context, function () {
            me.handleEvents(events, context);
          });
        } else {
          me.logger.warn(["No handler for event of type '{0}'", event.ID]);
        }
      } else {
        me.hideLoadingIndicator();
      }
    },

    /**
     * @private
     * @param {Object} event
     * @param {Object} context
     * @return {Boolean}
     */
    checkExecution: function (event, context) {
      var me = this,
          checkValue, mapitems;

      if (event.ON) {
        if (context.dirtySord && event.ON.objId) {
          context.sord = elo.IX.ix().checkoutSord(event.ON.objId, elo.CONST.SORD.mbAllIndex, elo.CONST.LOCK.NO);
          context.dirtySord = false;
        }

        if (context.dirtyWfStatus && event.ON.flowId) {
          context.wfStatus = sol.common.IxUtils.execute("RF_sol_common_service_GetWorkflowMetadata", { flowId: event.ON.flowId }).status;
          context.dirtyWfStatus = false;
        }

        switch (event.ON.type) {
          case "WF_STATUS":
            checkValue = context.wfStatus;
            break;
          case "GRP":
            checkValue = context.sord.getLineByGroup(event.ON.key);
            break;
          case "SORD":
            checkValue = context.sord[event.ON.key];
            break;
          case "MAP":
            mapitems = elo.IX.ix().checkoutMap(elo.CONST.MAP_CONFIG.DOMAIN_SORD, event.ON.objId, [event.ON.key], elo.CONST.LOCK.NO).items;
            if (mapitems && mapitems.length === 1) {
              checkValue = mapitems[0].value;
            }
            break;
          default:
            me.logger.warn(["event defines non existing ON.type={0}, ON condition will be ignored", event.ON.type]);
            return true;
        }

        return checkValue == event.ON.value;
      }
      return true;
    },

    /**
     * @private
     * @param {Object} obj
     * @return {Object}
     */
    isFunction: function (obj) {
      return obj && Object.prototype.toString.call(obj) === "[object Function]";
    },

    showLoadingIndicator: function (text) {
      var me = this;
      me.loadingIndicator = Ext.MessageBox.show({
        msg: text || "Loading...",
        //modal: false,
        width: 300,
        wait: true,
        waitConfig: { interval: 200 }
      });
    },

    hideLoadingIndicator: function () {
      var me = this;
      if (me.loadingIndicator) {
        me.loadingIndicator.hide();
      }
    }


  });

  sol.define("sol.common.web.ActionHandler.Refresh", {
    tryCheckoutTimes: 100,

    execute: function (event, context, callback) {
      var eventConfig;

      if (event.ID !== sol.common.IxUtils.CONST.EVENT_TYPES.REFRESH) {
        throw "'sol.common.jc.ActionHandler.REFRESH' can only handle '" + sol.common.IxUtils.CONST.EVENT_TYPES.REFRESH + "' events, but event-ID was '" + event.ID + "'";
      }

      if (event.obj) {
        eventConfig = event.obj;

        if (eventConfig.objId) {
          window.setTimeout(function () {
            api.Webclient.refreshView();
            callback.call(this);
          }, 1);
        }
      }
    }
  });

  sol.define("sol.common.web.ActionHandler.Goto", {
    tryCheckoutTimes: 100,

    execute: function (event, context, callback) {
      var me = this,
          eventConfig;

      if (event.ID !== sol.common.IxUtils.CONST.EVENT_TYPES.GOTO) {
        throw "'sol.common.jc.ActionHandler.GOTO' can only handle '" + sol.common.IxUtils.CONST.EVENT_TYPES.GOTO + "' events, but event-ID was '" + event.ID + "'";
      }

      if (event.obj) {
        eventConfig = event.obj;

        if (eventConfig.flowId && eventConfig.nodeId) {
          window.setTimeout(function () {
            // internal Web Client access
            api.Webclient.gotoTask({ flowId: Number(eventConfig.flowId), nodeId: Number(eventConfig.nodeId) });
            callback.call(this);
          }, 1);
        } else if (eventConfig.objId) {
          window.setTimeout(function () {
            // internal Web Client access
            api.Webclient.gotoEntry(Number(eventConfig.objId));
            if (eventConfig.checkout) {
              me.checkoutSord(eventConfig.objId, 0);
            }
            callback.call(this);
          }, 1);
        }
      }
    },

    checkoutSord: function (objId, times) {
      var me = this,
          sord;

      // internal Web Client access
      sord = elo.ModelRegistry.getDataInstance(elo.MainCtrl.modelNames.selectedSord);

      if (sord && Object.prototype.toString.call(sord) === "[object Array]") {
        sord = sord[0];
      }

      if (sord && sord.get && String(sord.get("id")) === String(objId)) {
        elo.EventRegistry.callBusEvent("BTN_EDITINOFFICE");
      } else if (times < me.tryCheckoutTimes) {
        window.setTimeout(function () {
          me.checkoutSord(objId, times + 1);
        }, 50);
      } else {
        console.error("Checkout document failed.");
      }
    }
  });

  sol.define("sol.common.web.ActionHandler.Dialog", {

    execute: function (event, context, callback) {
      var me = this,
          eventConfig;

      if (event.ID !== sol.common.IxUtils.CONST.EVENT_TYPES.DIALOG) {
        throw "'sol.common.web.ActionHandler.DIALOG' can only handle '" + sol.common.IxUtils.CONST.EVENT_TYPES.DIALOG + "' events, but event-ID was '" + event.ID + "'";
      }

      context.dirtySord = true;
      context.dirtyWfStatus = true;

      if (event.obj) {
        eventConfig = event.obj;
        if (eventConfig.url) {
          if (me.hideLoadingIndicator) {
            // prevent background flickering
            Ext.suspendLayouts();
            me.hideLoadingIndicator.call(me.actionHandler);
            Ext.resumeLayouts();
          }

          me.registerOpenWindow(event.obj.flowId, event.obj.nodeId);
          api.Webclient.showAppDialog(eventConfig.title || "", {
            url: eventConfig.url,
            doneHandler: function () {
              me.unregisterOpenWindow();
              callback.call(this);
            },
            closeHandler: function () {
              me.closeForm(event.obj.flowId, event.obj.nodeId);
              me.unregisterOpenWindow();
              callback.call(this);
            }
          });
        } else if (eventConfig.flowId && eventConfig.nodeId) {
          Ext.suspendLayouts();
          me.hideLoadingIndicator.call(me.actionHandler);

          event.obj.flowId = Number(event.obj.flowId);
          event.obj.nodeId = Number(event.obj.nodeId);

          me.registerOpenWindow(event.obj.flowId, event.obj.nodeId);
          api.Webclient.showAppDialog(eventConfig.title || "", {
            flowId: event.obj.flowId,
            nodeId: event.obj.nodeId,
            doneHandler: function () {
              me.unregisterOpenWindow();
              callback.call(this);
            },
            closeHandler: function () {
              me.closeForm(event.obj.flowId, event.obj.nodeId);
              me.unregisterOpenWindow();
              callback.call(this);
            }
          });
          Ext.resumeLayouts();
        } else {
          if (me.hideLoadingIndicator) {
            me.hideLoadingIndicator.call(me.actionHandler);
          }
          callback.call(me);
        }
      }
    },

    registerOpenWindow: function (flowId, nodeId) {
      var me = this;
      me.originalonunload = window.onbeforeunload;
      me.flowId = flowId;
      me.nodeId = nodeId;
      window.onbeforeunload = function () {
        me.closeForm(me.flowId, me.nodeId);
        if (me.originalonunload) {
          me.originalonunload();
        }
      };
      me.registeredWindow = true;
    },

    unregisterOpenWindow: function () {
      var me = this;
      if (me.registeredWindow) {
        window.onbeforeunload = me.originalonunload;
        me.flowId = null;
        me.nodeId = null;
        me.registeredWindow = false;
      }
    },

    /**
     * Aborts the current form if the user clicks cancel or reloads the page.
     * @param {Number} flowId
     * @param {Number} nodeId
     */
    closeForm: function (flowId, nodeId) {
      var me = this;
      if (me.registeredWindow && me.flowId && me.nodeId) {
        sol.common.IxUtils.execute("RF_sol_common_service_ActionCancelForm", {
          flowId: flowId, nodeId: nodeId
        }, function () {
          console.info("sol.common.client.ActionHandler: Closed open process.");
        }, function (error) {
          console.error("sol.common.client.ActionHandler: Closing open process failed.", error);
        });
      }
    }
  });

  sol.define("sol.common.web.ActionHandler.Error", {

    execute: function (event, context, callback) {
      var eventConfig;

      if (event.ID !== sol.common.IxUtils.CONST.EVENT_TYPES.ERROR) {
        throw "'sol.common.web.ActionHandler.ERROR' can only handle '" + sol.common.IxUtils.CONST.EVENT_TYPES.ERROR + "' events, but event-ID was '" + event.ID + "'";
      }

      if (event.obj) {
        eventConfig = event.obj;
        api.Webclient.alert(locales["sol.common.client.ActionHandler.errordlg.title"], eventConfig.msg);
      }

      callback.call(this);
    }
  });

  sol.define("sol.common.web.ActionHandler.Feedback", {

    execute: function (event, context, callback) {
      var eventConfig;

      if (event.ID !== sol.common.IxUtils.CONST.EVENT_TYPES.FEEDBACK) {
        throw "'sol.common.web.ActionHandler.FEEDBACK' can only handle '" + sol.common.IxUtils.CONST.EVENT_TYPES.FEEDBACK + "' events, but event-ID was '" + event.ID + "'";
      }

      setTimeout(function () {
        if (event.obj) {
          eventConfig = event.obj;
          if (eventConfig.permanent === true) {
            sol.common.web.ApiUtils.showInfoMessage(eventConfig.msg);
          } else {
            sol.common.web.ApiUtils.showPopupMessage(eventConfig.msg);
          }
        }
        callback.call(this);
      }, 0);
    }
  });

  sol.define("sol.common.web.ActionHandler.Action", {
    execute: function (event, context, callback) {
      if (event.ID !== sol.common.IxUtils.CONST.EVENT_TYPES.ACTION) {
        throw "'sol.common.web.ActionHandler.ACTION' can only handle '" + sol.common.IxUtils.CONST.EVENT_TYPES.ACTION + "' events, but event-ID was '" + event.ID + "'";
      }

      context.dirtySord = true;
      context.dirtyWfStatus = true;

      if (event.COMPONENT === sol.common.IxUtils.CONST.COMPONENTS.IX) {
        sol.common.web.ActionHandler.execute(event.obj.registeredFunction, event.obj.params);
      } else if (event.COMPONENT === sol.common.IxUtils.CONST.COMPONENTS.AS) {
        sol.common.web.ActionHandler.executeAs(event.obj.solution, event.obj.directRule, event.obj.params, null, "");
      }

      callback.call(this);
    }
  });

});

api.require({
  namespace: ["sol", "sol.common.web.BarcodeRegistry"],
  promise: new Promise(function (resolve, reject) {
    var any;
    try {
      any = new de.elo.ix.client.Any();
      any.type = elo.CONST.ANY.TYPE_STRING;
      any.stringValue = "{}";
      api.Webclient.getIXConnection().ix().executeRegisteredFunction("RF_sol_common_services_ActionDefinitionCollector", any, new de.elo.ix.client.AsyncCallback(function (successAnyResult) {
        // sucess
        sol.$actionDefinitionsLoaded = true;
        sol.$actionDefinitionCollectorResult = successAnyResult;
        resolve();
      }, function (ex) {
        // failure
        console.error("[sol.common.web.ActionDefinitionUtils] loading ribbon definition failed (async failure callback): " + ex);
        reject();
      }));
    } catch (e) {
      console.error("[sol.common.web.ActionDefinitionUtils] loading ribbon definition failed (promise error): " + e);
      reject();
    }
  })
}, function () {

  /**
   * This class loads ELO Business Solutions action definitions and creates the ribbon, button groups and buttons.
   *
   * This class is automatically called during client startup.
   *
   * @requires sol.common.IxUtils
   */
  sol.define("sol.common.web.ActionDefinitionUtils", {
    singleton: true,

    TAB_CONST: {
      HOME: { name: "START" },
      DOCUMENT: { name: "EXTENDED" },
      ARCHIVE: {},
      VIEW: { name: "VIEW" },
      WORKFLOW: { name: "TASK" },
      INTRAY: {},
      SEARCH: { name: "SEARCH" }
    },

    TAB_CONST_20: {
      HOME: { name: "START" },
      DOCUMENT: { name: "DOCUMENT" },
      ARCHIVE: {},
      VIEW: { name: "VIEW" },
      WORKFLOW: { name: "TASK" },
      INTRAY: {},
      SEARCH: { name: "SEARCH" },
      NEW: { name: "NEW" },
      OUTPUT: { name: "OUTPUT" },
      ORGANIZE: { name: "MANAGEMENT" }
    },

    // this is a mapping between the ELO20 JavaClient and WebClient band names
    // within an action you can use the JavaClient name - it will map it to the WebClient band name
    BAND_MAPPING_20: {
      NEW: {
        INSERT: "NEW_INSERT",
        START: "NEW_CREATETASK"
      },
      OUTPUT: {
         SEND: "OUTPUT_SEND",
         SAVE: "OUTPUT_SAVE",
         EXTERN: "OUTPUT_EXTERNALCONNECTION",
         PRINT: "OUTPUT_PRINT"
      },
      VIEW: {
        NAVIGATION: "VIEW_NAVIGATION",
        REFRESH: "VIEW_REFRESH",
        FUNCTIONALAREAS: "VIEW_REGIONS",
        VIEWPANELMODES_PREVIEW: "VIEW_VIEWPANELMODES_PREVIEW"
      },
      ORGANIZE: {
        STRUCTURE: "MANAGEMENT_STRUCTURE",
        PROPERTIES: "MANAGEMENT_PROPERTIES",
        OVERVIEWS: "MANAGEMENT_OVERVIEW",
        DELETE: "MANAGEMENT_DELETE"
      },
      SEARCH: {
        RESULT: "SEARCH_RESULT",
        FAVORITES: "SEARCH_FAVORITE",
        FILTERS: "SEARCH_FILTER",
        SEARCHAREA: "SEARCH_INDEX"
      },
      DOCUMENT: {
        VERSIONS: "DOCUMENT_VERSION",
        ATTACHMENT: "DOCUMENT_ATTACHMENT",
        NOTES: "DOCUMENT_NOTES",
      },
      WORKFLOW: {
        EDIT: "TASK_EDIT",
        VIEW: "TASK_SETTINGS"
      }
    },

    STD_ICONS: {
      small: "sol-scriptbutton16",
      smallHighRes: "sol-scriptbutton16-200",
      big: "sol-scriptbutton32",
      bigHighRes: "sol-scriptbutton32-200"
    },

    /**
	   * Initializes ribbon buttons, groups and tabs for ELO Business Solutions.
	   * @param {Object} contect. The current script scope.
	   */
    initializeRibbon: function () {
      var me = this,
          any, anyResult, result;

      try {
        if (sol.$actionDefinitionsLoaded === true) {
          // use result of promise in current WebClient versions
          anyResult = sol.$actionDefinitionCollectorResult;
        } else {
          // force synchronous call -> fallback in case promises are not supoorted in WebClient version
          any = new de.elo.ix.client.Any();
          any.type = elo.CONST.ANY.TYPE_STRING;
          any.stringValue = "{}";
          anyResult = api.Webclient.getIXConnection().ix().executeRegisteredFunction("RF_sol_common_services_ActionDefinitionCollector", any);
        }

        result = JSON.parse((anyResult && anyResult.stringValue) ? String(anyResult.stringValue) : "{}");

        if (result && result.definitions) {
          me.wcVersion20OrLater = (elo && elo.data && elo.data.server && elo.data.server.webclientVersion) ? sol.common.IxUtils.checkVersion(elo.data.server.webclientVersion, "20.00.000") : false;
          me.TAB_CONST = (me.wcVersion20OrLater === true) ? me.TAB_CONST_20 : me.TAB_CONST;
          me.buildRibbonFromDefinition(result.definitions);
        }
      } catch (e) {
        console.error("[sol.common.web.ActionDefinitionUtils] loading ribbon definition failed: " + e);
      }
    },

    /**
     * Builds the web client ribbon based on ribbon button/ group/ tab definitions given by RF_sol_common_services_ActionDefinitionCollector.
     * @private
     * @param {Object[]} defs action/ ribbon definition
     */
    buildRibbonFromDefinition: function (defs) {
      var me = this,
          i, j, k, def, localDef, group, button, tab, webclientStdTab, iconNames, webclientStdGroup, groupName,
          dynRibbon = {
            _buttons: {},
            buttons: [],
            _groups: {},
            groups: [],
            _tabs: {},
            tabs: []
          },
          groupsForStandardRibbons = [],
          addedGroupsForStandardRibbons = {},
          handler = function (def, objId) {
            switch (def.type) {
              case "ADVANCED_ACTION":
                sol.common.web.ActionHelper.executeAdvancedAction(objId, def.action);
                break;
              case "SIMPLE_ACTION":
                sol.common.web.ActionHelper.executeSimpleAction(objId, def.action);
                break;
              default:
                console.error("No handler found for ribbon definition", def);
            }
          },
          getLineByGroup = function (sord, fieldName) {
            var fieldIdx, objKeys = sord.get("objKeys");
            if (sord === null || objKeys === undefined) {
              return null;
            }
            for (fieldIdx = 0; fieldIdx < objKeys.length; fieldIdx += 1) {
              if (objKeys[fieldIdx].name === fieldName && objKeys[fieldIdx].data && objKeys[fieldIdx].data.length > 0) {
                return objKeys[fieldIdx].data[0];
              }
            }
            return null;
          },
          checkAccess = function (sord, access, targetName) {
            var solType, conditions, fieldValue, visible = false;
            if (!sord) {
              return false;
            }
            if ((access.document !== true || access.folder !== true) && ((access.document === true && sord.isFolder()) || (access.folder === true && !sord.isFolder()))) {
              return false;
            }
            if (!access.solTypes || (access.solTypes.length <= 0)) {
              return true;
            }

            solType = getLineByGroup(sord, "SOL_TYPE");

            if (solType && solType != "" && access.solTypes.indexOf(solType) !== -1) {
              conditions = access.conditions;
              if (conditions && Array.isArray(conditions)) {
                // we're checking if one of our filter criterias is not
                // true. This is when our some-function returns true 
                // (and we're inverting this for the 'visible' variable) 
                visible = !conditions.some(function (condition) {
                  if (condition.key && condition.value) {
                    fieldValue = getLineByGroup(sord, condition.key);
                    if (!fieldValue) {
                      console.warn("Button/Tab access check failed. Condition Field %s does not exist in mask of clicked object %s. %s", condition.key, sord.data.name, targetName);
                      return true;
                    }
                    return fieldValue != condition.value;
                  } else {
                    console.error("Button/Tab access check failed. Bad condition configuration. %s", targetName);
                    return true;
                  }
                });
              } else {
                visible = true;
              }
            }

            return visible;
          },
          btnAccess = function (state) {
            var access = this.access, targetName = this.targetName;
            if (!access || (!access.document && !access.folder && !access.multi && (!access.solTypes || access.solTypes.length <= 0))) {
              return true; // nothing set, button will always be enabled
            }
            if (!state.sord && !state.sords) {
              return false; // nothing selected
            }
            // check single access
            if (access.multi !== true) {
              return checkAccess(state.sord, access, targetName);
            }
            // check multi select
            if (state.sords) {
              return !state.sords.some(function (sord) {
                return !checkAccess(sord, access, targetName);
              });
            }
            return true;
          },
          btnHandler = function (state) {
            var def = this.def, objId = null;

            // we need to pass the buttonName to our action to allow
            // for some button-specific filtering in our type selection
            def.action.buttonName = this.name;
            
            if (state.hasSord()) {
              objId = state.getSord().get("id");
            } else if (state.sords && (state.sords.length > 0)) {
              objId = state.sords.map(function (sord) {
                return sord.get("id");
              });
            }
            handler(def, objId);
          };
      for (i = 0; i < defs.length; i++) {
        def = defs[i];

        // legacy action definition - just one ribbon definition instead of an array
        if (def.ribbon) {
          def.ribbons = [def.ribbon];
        }
  
        if (def.ribbons) {
          for (j = 0; j < def.ribbons.length; j++) {
            rib = def.ribbons[j];

            if (rib && rib.button && rib.ribbonTab && rib.buttongroup) {
              iconNames = me.getIconNames(rib.button);

              // create web client ribbon button
              if (!dynRibbon._buttons[rib.button.name]) {
                dynRibbon._buttons[rib.button.name] = new api.Button({
                  name: rib.button.name,
                  def: {
                    type: def.type,
                    action: def.action
                  },
                  access: btnAccess.bind({ access: rib.button.access, targetName: rib.button.name }),
                  handler: btnHandler,
                  text: rib.button.text,
                  splitText: rib.button.splitText,
                  tooltipTitle: "<span class='title'>" + rib.button.text + "</span>",
                  tooltipText: "<p>" + rib.button.tooltipText + "</p>",
                  bigIconCls: iconNames.bigIcon,
                  smallIconCls: iconNames.smallIcon,
                  position: rib.button.position,
                  asTile: !!rib.button.asTile,
                  iconName: iconNames.tileIcon
                });
                me.logger.info("registered button: " + rib.button.name);
                dynRibbon.buttons.push(dynRibbon._buttons[rib.button.name]);  
              }
              
              webclientStdTab = me.TAB_CONST[rib.ribbonTab.name];

              // read ribbon tab if new
              if (!webclientStdTab && !dynRibbon._tabs[rib.ribbonTab.name]) {
                me.logger.info("new ribbon tab: " + rib.ribbonTab.name);
                dynRibbon._tabs[rib.ribbonTab.name] = {
                  cfg: rib.ribbonTab,
                  name: rib.ribbonTab.name,
                  text: rib.ribbonTab.text,
                  position: rib.ribbonTab.position,
                  access: rib.ribbonTab.access,
                  groups: [], // group names
                  _groups: [] // group definitions
                };
                dynRibbon.tabs.push(dynRibbon._tabs[rib.ribbonTab.name]);
              }

              // read ribbon group if new
              if (!dynRibbon._groups[rib.buttongroup.name]) {
                me.logger.info("new button group: " + rib.buttongroup.name);

                try {
                  webclientStdGroup = me.BAND_MAPPING_20[rib.ribbonTab.name.toUpperCase()][rib.buttongroup.name.toUpperCase()];
                } catch(e) {
                  webclientStdGroup = undefined;
                }

                dynRibbon._groups[rib.buttongroup.name] = {
                  cfg: rib.buttongroup,
                  name: rib.buttongroup.name,
                  text: rib.buttongroup.text,
                  mode: rib.buttongroup.mode,
                  buttons: [], // button names
                  _buttons: [], // button definitions,
                  webClientStdGroup: webclientStdGroup
                };
                dynRibbon.groups.push(dynRibbon._groups[rib.buttongroup.name]);

                if (dynRibbon._tabs[rib.ribbonTab.name]) {
                  // is dynamic tab
                  dynRibbon._tabs[rib.ribbonTab.name]._groups.push();
                  dynRibbon._tabs[rib.ribbonTab.name]._groups.push(dynRibbon._groups[rib.buttongroup.name]);
                } else if (webclientStdTab && webclientStdTab.name && !webclientStdGroup) {
                  // expect web client tab
                  groupsForStandardRibbons.push({
                    def: rib,
                    stdTab: webclientStdTab
                  });
                }
              }

              // register button in group
              if (dynRibbon._groups[rib.buttongroup.name] && !dynRibbon._groups[rib.buttongroup.name].webclientStdGroup) {
                // is dynamic group
                dynRibbon._groups[rib.buttongroup.name]._buttons.push({
                  def: rib,
                  btn: dynRibbon._buttons[rib.button.name]
                });
              } else {
                // expect web client group
                //         api.Registry.addRibbonButton(rib.button.name, rib.buttongroup.name, rib.button.position);
              }
            }
          }
        }

        // register barcode handlers
        if (def.barcode && def.barcode.identifier) {
          localDef = def;
          sol.common.web.BarcodeRegistry.register(def.barcode.identifier, def.action.fct,
            function (identifier, objId, data) {
              handler(localDef, objId);
            });
        }
      }

      // register groups
      for (j = 0; j < dynRibbon.groups.length; j++) {
        group = dynRibbon.groups[j];
        group._buttons = group._buttons.sort(function (a, b) {
          return a.def.button.position > b.def.button.position ? 1 : -1;
        });

        groupName = group.webClientStdGroup ? group.webClientStdGroup : group.name;

        // add buttons to group
        for (k = 0; k < group._buttons.length; k++) {
          button = group._buttons[k];

          if (me.wcVersion20OrLater === true) {
            // BS-855 separate button registration needed for default pinned state
            api.Registry.addRibbonButton(button.def.button.name, groupName, button.def.button.position * 100, !!button.def.button.pinned);
          } else {
            group.buttons.push(button.def.button.name);
          }
        }

        me.logger.info("registered button group: " + group.name);

        if (!me.wcVersion20OrLater || !group.webClientStdGroup) {
          group._group = new api.ButtonGroup(group);
        }
      }

      for (j = 0; j < groupsForStandardRibbons.length; j++) {
        var grpForStdtTab = groupsForStandardRibbons[j];
        if (grpForStdtTab.def && grpForStdtTab.stdTab && !addedGroupsForStandardRibbons[grpForStdtTab.def.buttongroup.name]) {
          addedGroupsForStandardRibbons[grpForStdtTab.def.buttongroup.name] = true;
          api.Registry.addButtonGroup(grpForStdtTab.def.buttongroup.name, grpForStdtTab.stdTab.name, grpForStdtTab.def.buttongroup.position * 100);
        }
      }

      // register tabs
      for (j = 0; j < dynRibbon.tabs.length; j++) {
        tab = dynRibbon.tabs[j];
        tab._groups = tab._groups.sort(function (a, b) {
          return a.cfg.position > b.cfg.position ? 1 : -1;
        });

        // add groups to tabs
        for (k = 0; k < tab._groups.length; k++) {
          group = tab._groups[k];
          tab.groups.push(group.name);
        }

        me.logger.info("registered tab: " + tab.name);
        if (tab.access && (me.wcVersion20OrLater === true)) {
          tab.visibilityFct = btnAccess.bind({ access: tab.access, targetName: tab.name });
        }
        tab._tab = new api.RibbonTab(tab);
        api.Registry.addRibbonTab(tab.name, tab.position * 100);
      }
    },

    getIconNames: function (buttonDef) {
      var me = this,
          webButtonDef, dpi, bigIcon, smallIcon, tileIcon;

      if (buttonDef.iconName && (me.wcVersion20OrLater === true)) {
        bigIcon = smallIcon = tileIcon = buttonDef.iconName;
      } else {
        webButtonDef = buttonDef.web;
        dpi = (elo && elo.data && elo.data.dpi) ? elo.data.dpi : 100;
        if (dpi > 150) {
          bigIcon = (webButtonDef && webButtonDef.bigIconHighRes) ? webButtonDef.bigIconHighRes : me.STD_ICONS.bigHighRes;
          smallIcon = (webButtonDef && webButtonDef.smallIconHighRes) ? webButtonDef.smallIconHighRes : me.STD_ICONS.smallHighRes;
        } else {
          bigIcon = (webButtonDef && webButtonDef.bigIcon) ? webButtonDef.bigIcon : me.STD_ICONS.big;
          smallIcon = (webButtonDef && webButtonDef.smallIcon) ? webButtonDef.smallIcon : me.STD_ICONS.small;
        }
        tileIcon = (webButtonDef && webButtonDef.iconName) ? webButtonDef.iconName : "";
      }

      return {
        bigIcon: bigIcon,
        smallIcon: smallIcon,
        tileIcon: tileIcon
      };
    }

  });

  sol.common.web.ActionDefinitionUtils.initializeRibbon();
});

//# sourceURL=sol.common.web.js