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

//@include lib_Class.js
//@include lib_sol.common.ix.FunctionBase.js

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

/**
 * Changes the color of an archive element.
 *
 * Additionally the old color can be saved to a map field, from where is can be restored later
 *
 *     { color: "red", save: "OLD_COLOR" }
 *     { color: "blue", restore: "OLD_COLOR" }
 *
 * `save` and `restore` are both optional, but if `restore` is defined, it always wins over `color`.
 * If there is no color found in the map field `OLD_COLOR` the `color` will be used as fallback.
 *
 * # As workflow node
 *
 * `ObjId` is set based on the element that the workflow is attached to.
 * Following configuration should be applied to the comments field.
 *
 *     {
 *       "color": "blue"
 *     }
 *
 * # As IX function call
 *
 * In addition to the workflow node configuration the objId must be passed.
 *
 *     sol.common.IxUtils.execute("RF_sol_function_ChangeColor", {
 *       objId: "4711",
 *       color: "blue"
 *     });
 *
 * @author Pascal Zipfel, ELO Digital Office GmbH
 * @version 1.06.000
 *
 * @eloix
 *
 * @requires  sol.Logger
 * @requires  sol.common.JsonUtils
 * @requires  sol.common.WfUtils
 * @requires  sol.common.ix.RfUtils
 * @requires  sol.common.ix.FunctionBase
 *
 */
sol.define("sol.common.ix.functions.ChangeColor", {
  extend: "sol.common.ix.FunctionBase",

  requiredConfig: ["objId"],

  /**
   * @cfg {String} objId (required)
   */

  /**
   * @cfg {String} color Tries to find a color which was defined in ELO
   */

  /**
   * @cfg {String} save Saves the old color to a map field
   */

  /**
   * @cfg {String} restore Restores the old color from a map filed
   */

  /**
   * @private
   * @property {de.elo.ix.client.ColorData[]} colorCache
   */

  initialize: function (config) {
    var me = this;
    me.$super("sol.common.ix.FunctionBase", "initialize", [config]);
  },

  /**
   * Changes the color of the element.
   */
  process: function () {
    var me = this,
        sord, oldColorId, newColorId, lookupColor, lookedupColor;

    sord = ixConnect.ix().checkoutSord(me.objId, SordC.mbMin, LockC.NO);
    oldColorId = sord.kind;
    newColorId = 0;
    lookupColor = me.restoreFromMap() || me.color;

    if (lookupColor) {
      lookedupColor = me.getColor(lookupColor);
      if (lookedupColor) {
        newColorId = lookedupColor.id;
      }
    }

    if (oldColorId != newColorId) {
      sord.kind = newColorId;
      ixConnect.ix().checkinSord(sord, SordC.mbMin, LockC.NO);
      me.logger.info(["changed object color from '{0}' to '{1}'", oldColorId, newColorId]);
    }

    me.saveToMap(me.getColor(oldColorId));
  },

  /**
   * @private
   * @return {de.elo.ix.client.ColorData[]} colorCache
   */
  getColors: function () {
    var me = this;
    if (!me.colorCache) {
      me.colorCache = ixConnect.ix().checkoutColors(LockC.NO);
    }
    return me.colorCache;
  },

  /**
   * @private
   * @param {String|Number} color Name or ID of the color
   * @return {de.elo.ix.client.ColorData}
   */
  getColor: function (color) {
    var me = this,
        colors = me.getColors(),
        ignoreCase = !!color.toUpperCase,
        result = null;
    colors.some(function (c) {
      var hit = ((c.id == color) || ((ignoreCase) ? (c.name.toUpperCase() == color.toUpperCase()) : (c.name == color)));
      if (hit) {
        result = c;
      }
      return hit;
    });
    return result;
  },

  /**
   * @private
   * @return {String}
   */
  restoreFromMap: function () {
    var me = this,
        color = null,
        mapdata;
    if (me.restore) {
      try {
        mapdata = ixConnect.ix().checkoutMap(MapDomainC.DOMAIN_SORD, me.objId, [me.restore], LockC.NO);
        if (!mapdata || !mapdata.items || (mapdata.items.length <= 0)) {
          throw "no map entry found";
        }
        color = mapdata.items[0].value;
        me.logger.debug(["restore color '{0}' from map", color]);
        ixConnect.ix().checkinMap(MapDomainC.DOMAIN_SORD, me.objId, me.objId, [new KeyValue(me.restore, null)], LockC.NO);
      } catch (ex) {
        me.logger.warn(["could not restore color from map field '{0}'", me.restore], ex);
      }
    }
    return color;
  },

  /**
   * @private
   * @param {String} color
   */
  saveToMap: function (color) {
    var me = this;
    if (me.save && color) {
      try {
        ixConnect.ix().checkinMap(MapDomainC.DOMAIN_SORD, me.objId, me.objId, [new KeyValue(me.save, color.name)], LockC.NO);
        me.logger.debug(["saved color to map field '{0}' -> '{1}'", color, me.save]);
      } catch (ex) {
        me.logger.warn(["could not save color to map field '{0}'", me.restore], ex);
      }
    }
  }
});


/**
 * @member sol.common.ix.functions.ChangeColor
 * @static
 * @inheritdoc sol.common.ix.FunctionBase#onEnterNode
 */
function onEnterNode(clInfo, userId, wFDiagram, nodeId) {
  logger.enter("onEnterNode_ChangeColor", { flowId: wFDiagram.id, nodeId: nodeId });
  var params = sol.common.WfUtils.parseAndCheckParams(wFDiagram, nodeId),
      module;

  params.objId = wFDiagram.objId;
  module = sol.create("sol.common.ix.functions.ChangeColor", params);

  module.process();

  logger.exit("onEnterNode_ChangeColor");
}


/**
 * @member sol.common.ix.functions.ChangeColor
 * @static
 * @inheritdoc sol.common.ix.FunctionBase#onExitNode
 */
function onExitNode(clInfo, userId, wFDiagram, nodeId) {
  logger.enter("onExitNode_ChangeColor", { flowId: wFDiagram.id, nodeId: nodeId });
  var params = sol.common.WfUtils.parseAndCheckParams(wFDiagram, nodeId),
      module;

  params.objId = wFDiagram.objId;
  module = sol.create("sol.common.ix.functions.ChangeColor", params);

  module.process();

  logger.exit("onExitNode_ChangeColor");
}


/**
 * @member sol.common.ix.functions.ChangeColor
 * @method RF_sol_function_ChangeColor
 * @static
 * @inheritdoc sol.common.ix.FunctionBase#RF_FunctionName
 */
function RF_sol_function_ChangeColor(iXSEContext, args) {
  logger.enter("RF_sol_function_ChangeColor", args);
  var params = sol.common.ix.RfUtils.parseAndCheckParams(iXSEContext, arguments.callee.name, args, "objId"),
      module = sol.create("sol.common.ix.functions.ChangeColor", params);

  module.process();

  logger.exit("RF_sol_function_ChangeColor");
}