// Java includes
importPackage(Packages.de.elo.ix.client);

// JavaScript includes
//@include lib_Class.js

/**
 * Utility functions for counter.
 *
 * All counter-names will be normalized, by transforming them to upper case and replacing `&` with `__`.
 *
 *     // Generate the next record id for filing plan reference 1202.22
 *     var nextRecordId = sol.common.CounterUtils.incCounter('RECORDS-FP.1202.22', 1);
 *
 * @author Pascal Zipfel, ELO Digital Office GmbH
 * @version 1.04.002
 *
 * @elojc
 * @eloas
 * @eloix
 */
sol.define("sol.common.CounterUtils", {
  singleton: true,

  /**
   * Returns the next value of a counter, or creates a new one.
   * @param {String} name The name of the counter
   * @param {Number} [defaultValue=1] (optional) The default value of the counter, if a new one is created
   * @return {Number} The counter value
   */
  incCounter: function (name, defaultValue) {
    var me = this,
        _result;
    me.logger.enter("incCounter", arguments);

    defaultValue = defaultValue || 1;

    if (!this.exists(name)) {
      this.create(name, defaultValue);
    }
    _result = this.getValue(name);
    me.logger.exit("incCounter", _result);
    return _result;
  },

  /**
   * Creates a new counter or updates an existing one.
   *
   * Be carefull, if counter already exists, it will be overwritten.
   * You might want to use {@link sol.common.CounterUtils#incCounter} instead.
   *
   * @param {String} name The name of the counter
   * @param {Number} [value=1] (optional) The initial counter value
   */
  create: function (name, value) {
    var me = this,
        info;
    me.logger.enter("create", arguments);

    info = new CounterInfo();
    info.name = this.normalizeName(name);
    info.value = value || 1;

    ixConnect.ix().checkinCounters([info], LockC.NO);
    me.logger.exit("create");
  },

  /**
   * Checks if a counter exists without modifying it.
   * @param {String} name
   * @return {Boolean}
   */
  exists: function (name) {
    var me = this,
        infos, exists, _result;
    me.logger.enter("exists", arguments);

    exists = false;
    try {
      name = this.normalizeName(name);
      infos = ixConnect.ix().checkoutCounters([name], false, LockC.NO);

      if (infos && infos.length > 0) {
        exists = true;
      }
    } catch (ex) {
      exists = false;
    }
    _result = exists;
    me.logger.exit("exists", _result);
    return _result;
  },

  /**
   * Retrives the value of a counter.
   *
   * If not spezified differently, it will automatically increment the counter.
   *
   * @param {String} name
   * @param {Boolean} noInc (optional) If `true`, the counter will NOT be incremented (use carefully)
   * @return {Number} The value of the counter
   * @throws Throws an exception, if counter does not exist
   */
  getValue: function (name, noInc) {
    var increment, infos;

    increment = !noInc;
    name = this.normalizeName(name);
    infos = ixConnect.ix().checkoutCounters([name], increment, LockC.NO);

    if (!infos || infos.length <= 0) {
      throw "Counter does not exist";
    }
    return infos[0].value;
  },

  /**
   * @private
   * Performes the normalization on the counter name converts to upper case and replace `&`.
   * @param {String} name
   * @return {String} The normalized name
   */
  normalizeName: function (name) {
    name = String(name);
    if (name.length > CounterInfoC.lnName) {
      throw "Counter name is too long (>" + CounterInfoC.lnName + " chars): " + name;
    }
    return name.toUpperCase().replace(/\&/g, "__");
  }

});