text: /*
   * The MIT License
   *
   * Copyright (c) 2015, Sebastian Sdorra
   *
   * Permission is hereby granted, free of charge, to any person obtaining a copy
   * of this software and associated documentation files (the "Software"), to deal
   * in the Software without restriction, including without limitation the rights
   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   * copies of the Software, and to permit persons to whom the Software is
   * furnished to do so, subject to the following conditions:
   *
   * The above copyright notice and this permission notice shall be included in
   * all copies or substantial portions of the Software.
   *
   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   * SOFTWARE.
   */
  
  'use strict';
  
  /**
   * @ngdoc object
   * @name adf.dashboardProvider
   * @description
   *
   * The dashboardProvider can be used to register structures and widgets.
   */
  angular.module('adf.provider', ['adf.locale'])
      .provider('dashboard', function (adfLocale) {
  
          var activeLocale = adfLocale.defaultLocale;
          var locales = adfLocale.frameworkLocales;
  
          function getLocales() {
              return locales;
          }
  
          function getActiveLocale() {
              return activeLocale;
          }
  
          function translate(label) {
              var translation = locales[activeLocale][label];
              return translation ? translation : label;
          }
  
          this.setLocale = function (locale) {
              if (locales[locale]) {
                  activeLocale = locale;
              } else {
                  throw new Error('Cannot set locale: ' + locale + '. Locale is not defined.');
              }
  
              return this;
          };
          this.addLocale = function (locale, translations) {
              if (!angular.isString(locale)) {
                  throw new Error('locale must be an string');
              }
  
              if (!angular.isObject(translations)) {
                  throw new Error('translations must be an object');
              }
  
              locales[locale] = translations;
              return this;
          };
  
          var customWidgetTemplatePath = null;
  
          /**
           * @ngdoc method
           * @name adf.dashboardProvider#customWidgetTemplatePath
           * @propertyOf adf.dashboardProvider
           * @description
           *
           * Changes the container template for the widgets
           *
           * @param {string} path to the custom widget template
           *
           * @returns {Object} self
           */
          this.customWidgetTemplatePath = function (templatePath) {
              customWidgetTemplatePath = templatePath;
              return this;
          };
  
          var widgets = {};
          var widgetsPath = '';
          var structures = {};
          var messageTemplate = '<div class="alert alert-danger">{}</div>';
          var loadingTemplate = '\
        <div class="progress progress-striped active">\n\
          <div class="progress-bar" role="progressbar" style="width: 100%">\n\
            <span class="sr-only">loading ...</span>\n\
          </div>\n\
        </div>';
  
          /**
           * @ngdoc method
           * @name adf.dashboardProvider#widget
           * @methodOf adf.dashboardProvider
           * @description
           *
           * Registers a new widget.
           *
           * @param {string} name of the widget
           * @param {object} widget to be registered.
           *
           *   Object properties:
           *
           *   - `title` - `{string=}` - The title of the widget.
           *   - `description` - `{string=}` - Description of the widget.
           *   - `config` - `{object}` - Predefined widget configuration.
           *   - `controller` - `{string=|function()=}` - Controller fn that should be
           *      associated with newly created scope of the widget or the name of a
           *      {@link http://docs.angularjs.org/api/angular.Module#controller registered controller}
           *      if passed as a string.
           *   - `controllerAs` - `{string=}` - A controller alias name. If present the controller will be
           *      published to scope under the `controllerAs` name.
           *   - `template` - `{string=|function()=}` - html template as a string.
           *   - `templateUrl` - `{string=}` - path to an html template.
           *   - `reload` - `{boolean=}` - true if the widget could be reloaded. The default is false.
           *   - `resolve` - `{Object.<string, function>=}` - An optional map of dependencies which should
           *      be injected into the controller. If any of these dependencies are promises, the widget
           *      will wait for them all to be resolved or one to be rejected before the controller is
           *      instantiated.
           *      If all the promises are resolved successfully, the values of the resolved promises are
           *      injected.
           *
           *      The map object is:
           *      - `key` – `{string}`: a name of a dependency to be injected into the controller.
           *      - `factory` - `{string|function}`: If `string` then it is an alias for a service.
           *        Otherwise if function, then it is {@link http://docs.angularjs.org/api/AUTO.$injector#invoke injected}
           *        and the return value is treated as the dependency. If the result is a promise, it is
           *        resolved before its value is injected into the controller.
           *   - `edit` - `{object}` - Edit modus of the widget.
           *      - `controller` - `{string=|function()=}` - Same as above, but for the edit mode of the widget.
           *      - `template` - `{string=|function()=}` - Same as above, but for the edit mode of the widget.
           *      - `templateUrl` - `{string=}` - Same as above, but for the edit mode of the widget.
           *      - `resolve` - `{Object.<string, function>=}` - Same as above, but for the edit mode of the widget.
           *      - `reload` - {boolean} - true if the widget should be reloaded, after the edit mode is closed.
           *        Default is true.
           *
           * @returns {Object} self
           */
          this.widget = function (name, widget) {
              var w = angular.extend({reload: false}, widget);
              if (w.edit) {
                  var edit = {reload: true};
                  angular.extend(edit, w.edit);
                  w.edit = edit;
              }
              widgets[name] = w;
              return this;
          };
  
          /**
           * @ngdoc method
           * @name adf.dashboardProvider#widgetsPath
           * @methodOf adf.dashboardProvider
           * @description
           *
           * Sets the path to the directory which contains the widgets. The widgets
           * path is used for widgets with a templateUrl which contains the
           * placeholder {widgetsPath}. The placeholder is replaced with the
           * configured value, before the template is loaded, but the template is
           * cached with the unmodified templateUrl (e.g.: {widgetPath}/src/widgets).
           * The default value of widgetPaths is ''.
           *
           *
           * @param {string} path to the directory which contains the widgets
           *
           * @returns {Object} self
           */
          this.widgetsPath = function (path) {
              widgetsPath = path;
              return this;
          };
  
          /**
           * @ngdoc method
           * @name adf.dashboardProvider#structure
           * @methodOf adf.dashboardProvider
           * @description
           *
           * Registers a new structure.
           *
           * @param {string} name of the structure
           * @param {object} structure to be registered.
           *
           *   Object properties:
           *
           *   - `rows` - `{Array.<Object>}` - Rows of the dashboard structure.
           *     - `styleClass` - `{string}` - CSS Class of the row.
           *     - `columns` - `{Array.<Object>}` - Columns of the row.
           *       - `styleClass` - `{string}` - CSS Class of the column.
           *
           * @returns {Object} self
           */
          this.structure = function (name, structure) {
              structures[name] = structure;
              return this;
          };
  
          /**
           * @ngdoc method
           * @name adf.dashboardProvider#messageTemplate
           * @methodOf adf.dashboardProvider
           * @description
           *
           * Changes the template for messages.
           *
           * @param {string} template for messages.
           *
           * @returns {Object} self
           */
          this.messageTemplate = function (template) {
              messageTemplate = template;
              return this;
          };
  
          /**
           * @ngdoc method
           * @name adf.dashboardProvider#loadingTemplate
           * @methodOf adf.dashboardProvider
           * @description
           *
           * Changes the template which is displayed as
           * long as the widget resources are not resolved.
           *
           * @param {string} loading template
           *
           * @returns {Object} self
           */
          this.loadingTemplate = function (template) {
              loadingTemplate = template;
              return this;
          };
  
          /**
           * @ngdoc service
           * @name adf.dashboard
           * @description
           *
           * The dashboard holds all options, structures and widgets.
           *
           * @property {Array.<Object>} widgets Array of registered widgets.
           * @property {string} widgetsPath Default path for widgets.
           * @property {Array.<Object>} structures Array of registered structures.
           * @property {string} messageTemplate Template for messages.
           * @property {string} loadingTemplate Template for widget loading.
           *
           * @returns {Object} self
           */
          this.$get = function () {
              var cid = 0;
  
              return {
                  widgets: widgets,
                  widgetsPath: widgetsPath,
                  structures: structures,
                  messageTemplate: messageTemplate,
                  loadingTemplate: loadingTemplate,
                  setLocale: this.setLocale,
                  locales: getLocales,
                  activeLocale: getActiveLocale,
                  translate: translate,
                  customWidgetTemplatePath: customWidgetTemplatePath,
  
                  /**
                   * @ngdoc method
                   * @name adf.dashboard#id
                   * @methodOf adf.dashboard
                   * @description
                   *
                   * Creates an ongoing numeric id. The method is used to create ids for
                   * columns and widgets in the dashboard.
                   */
                  id: function () {
                      return ++cid;
                  }
              };
          };
  
      });
  