importPackage(Packages.de.elo.ix.client);

//@include lib_Class.js
//@include lib_sol.common.ObjectUtils.js
//@include lib_sol.common.RepoUtils.js
//@include lib_sol.common.ix.ServiceBase.js

var logger = sol.create("sol.Logger", { scope: "sol.common.ix.services.StandardTypes" });

/**
 * Standardized implementation for a types/templates service.
 *
 * @author PZ, ELO Digital Office GmbH
 * @version 1.03.000
 *
 * @eloix
 * @requires sol.common.ObjectUtils
 * @requires sol.common.JsonUtils
 * @requires sol.common.SordUtils
 * @requires sol.common.RepoUtils
 * @requires sol.common.ix.RfUtils
 * @requires sol.common.ix.ServiceBase
 */
sol.define("sol.common.ix.services.StandardTypes", {
  extend: "sol.common.ix.ServiceBase",

  /**
   * description texts are cut at this length.
   */
  maxDescLength: 70,

  /**
   * @cfg {Boolean} hideDesc (optional) Description text will be hidden.
   * @cfg {Boolean} shortenDesc (optional) Description text will be limited to 70 characters.
   * @cfg {Object} $types (optional) Configuration to retrieve the types for selection in the client.
   * @cfg {String} $types.path The path containing the templates. If `$types` is defined, this is mandatory.
   */

  initialize: function (config) {
    var me = this;

    me.$super("sol.common.ix.ServiceBase", "initialize", [config]);
  },

  /**
   * Performes the checks and retrieves the data as spezified in the configuration.
   * @returns {Object}
   */
  process: function () {
    var me = this;

    me.collectTypes();

    // TODO filtering

    return me._types;
  },

  /**
   * Collects the types and stores them to `_types`.
   */
  collectTypes: function () {
    var me = this,
      types;

    if (me.$types) {
      if (!me.$types.path) {
        throw "IllegalArgumentException: to retrieve types at least a 'path' has to be defined";
      }

      types = me.retrieveAllTypes();
      me._types = me.convertTypes(types);
    }
  },

  /**
   * @private
   * Retrieves all type Sord objects.
   * @returns {de.elo.ix.client.Sord[]}
   */
  retrieveAllTypes: function () {
    var me = this,
      searchConf, types;

    searchConf = {
      includeFolders: me.$types.includeFolders || true,
      includeDocuments: me.$types.includeDocuments || false,
      includeReferences: me.$types.includeReferences || true,
      sordZ: SordC.mbAllIndex
    };

    types = sol.common.RepoUtils.findChildren(me.$types.path, searchConf);

    return types;
  },

  /**
   * @private
   * Converts from Sords to Objects
   * @param {de.elo.ix.client.Sord[]} typeSords
   * @returns {Object[]}
   */
  convertTypes: function (typeSords) {
    var me = this;

    return sol.common.ObjectUtils.isArray(typeSords)
      ? typeSords.map(function (typeSord) {
        return me.convertType(typeSord);
      })
      : [];
  },

  /**
   * @private
   * Converts from Sords to Objects
   * @param {de.elo.ix.client.Sord} typeSord
   * @returns {Object}
   */
  convertType: function (typeSord) {
    var me = this;
    formattedSord = sol.common.ObjectFormatter.format({
      sord: {
        formatter: 'sol.common.ObjectFormatter.TemplateSord',
        data: typeSord
      }
    }).sord;

    // In the beginning we had only objId, name and desc.
    // Later we added the whole formatted TemplateSord. We're keeping those
    // three properties to keep it compatible with old ActionDefinitions
    formattedSord.objId = typeSord.id;
    formattedSord.name = typeSord.name;
    formattedSord.desc = me.hideDesc ? "" : me.getConvertedDescription(typeSord.desc + "");

    return formattedSord;
  },

  /**
   * @private
   * Converts a description
   * @param {String} description
   * @returns {String}
   */
  getConvertedDescription: function (description) {
    var me = this;

    return me.shouldShortenDescription(description)
      ? me.shortDescription(description)
      : description;
  },

  /**
   * @private
   * Determines if a description should be shorten
   * @param {StringLike} description
   * @returns {Boolean}
   */
  shouldShortenDescription: function (description) {
    var me = this;

    return me.shortenDesc && (description || "").length > me.maxDescLength;
  },

  /**
   * @private
   * shorts a description
   * @param {StringLike} description
   * @returns {String}
   */
  shortDescription: function (description) {
    var me = this;

    return (description || "").substr(0, me.maxDescLength - 3) + "...";
  }
});




/**
 * @member sol.common.ix.services.StandardTypes
 * @method RF_sol_common_service_StandardTypes
 * @static
 * @inheritdoc sol.common.ix.ServiceBase#RF_ServiceBaseName
 */
function RF_sol_common_service_StandardTypes(ec, args) {
  var config, service, result;

  logger.enter("RF_sol_common_service_StandardTypes", args);

  config = sol.common.ix.RfUtils.parseAndCheckParams(ec, arguments.callee.name, args);
  config.ci = ec.ci;
  config.user = ec.user;

  service = sol.create("sol.common.ix.services.StandardTypes", config);
  result = sol.common.ix.RfUtils.stringify(service.process());

  logger.exit("RF_sol_common_service_StandardTypes", result);

  return result;
}