/**
   * Copies a user preference group. Call with fromUserLoginId, userPrefGroupTypeId and optional
   * userPrefLoginId. If userPrefLoginId isn't specified, then the currently logged-in user's
   * userLoginId will be used.
   *
   * @param ctx The DispatchContext that this service is operating in.
   * @param context Map containing the input arguments.
   * @return Map with the result of the service, the output parameters.
   */
  public static Map<String, Object> copyUserPreferenceGroup(
      DispatchContext ctx, Map<String, ?> context) {
    Delegator delegator = ctx.getDelegator();
    Locale locale = (Locale) context.get("locale");

    String userLoginId = PreferenceWorker.getUserLoginId(context, false);
    String fromUserLoginId = (String) context.get("fromUserLoginId");
    String userPrefGroupTypeId = (String) context.get("userPrefGroupTypeId");
    if (UtilValidate.isEmpty(userLoginId)
        || UtilValidate.isEmpty(userPrefGroupTypeId)
        || UtilValidate.isEmpty(fromUserLoginId)) {
      return ServiceUtil.returnError(
          UtilProperties.getMessage(resource, "copyPreference.invalidArgument", locale));
    }

    try {
      Map<String, String> fieldMap =
          UtilMisc.toMap(
              "userLoginId", fromUserLoginId, "userPrefGroupTypeId", userPrefGroupTypeId);
      List<GenericValue> resultList = delegator.findByAnd("UserPreference", fieldMap);
      if (resultList != null) {
        for (GenericValue preference : resultList) {
          preference.set("userLoginId", userLoginId);
        }
        delegator.storeAll(resultList);
      }
    } catch (GenericEntityException e) {
      Debug.logWarning(e.getMessage(), module);
      return ServiceUtil.returnError(
          UtilProperties.getMessage(
              resource, "copyPreference.writeFailure", new Object[] {e.getMessage()}, locale));
    }

    return ServiceUtil.returnSuccess();
  }
  /**
   * Retrieves a group of user preferences from persistent storage. Call with userPrefGroupTypeId
   * and optional userPrefLoginId. If userPrefLoginId isn't specified, then the currently logged-in
   * user's userLoginId will be used. The retrieved preferences group is contained in the
   * <b>userPrefMap</b> element.
   *
   * @param ctx The DispatchContext that this service is operating in.
   * @param context Map containing the input arguments.
   * @return Map with the result of the service, the output parameters.
   */
  public static Map<String, Object> getUserPreferenceGroup(
      DispatchContext ctx, Map<String, ?> context) {
    Locale locale = (Locale) context.get("locale");
    if (!PreferenceWorker.isValidGetId(ctx, context)) {
      return ServiceUtil.returnError(
          UtilProperties.getMessage(resource, "getPreference.permissionError", locale));
    }
    Delegator delegator = ctx.getDelegator();

    String userPrefGroupTypeId = (String) context.get("userPrefGroupTypeId");
    if (UtilValidate.isEmpty(userPrefGroupTypeId)) {
      return ServiceUtil.returnError(
          UtilProperties.getMessage(resource, "getPreference.invalidArgument", locale));
    }
    String userLoginId = PreferenceWorker.getUserLoginId(context, true);

    Map<String, Object> userPrefMap = null;
    try {
      Map<String, String> fieldMap =
          UtilMisc.toMap("userLoginId", "_NA_", "userPrefGroupTypeId", userPrefGroupTypeId);
      userPrefMap =
          PreferenceWorker.createUserPrefMap(delegator.findByAnd("UserPreference", fieldMap));
      fieldMap.put("userLoginId", userLoginId);
      userPrefMap.putAll(
          PreferenceWorker.createUserPrefMap(delegator.findByAnd("UserPreference", fieldMap)));
    } catch (GenericEntityException e) {
      Debug.logWarning(e.getMessage(), module);
      return ServiceUtil.returnError(
          UtilProperties.getMessage(
              resource, "getPreference.readFailure", new Object[] {e.getMessage()}, locale));
    } catch (GeneralException e) {
      Debug.logWarning(e.getMessage(), module);
      return ServiceUtil.returnError(
          UtilProperties.getMessage(
              resource, "getPreference.readFailure", new Object[] {e.getMessage()}, locale));
    }
    // for the 'DEFAULT' values find the related values in general properties and if found use
    // those.
    Iterator it = userPrefMap.entrySet().iterator();
    Map generalProperties = UtilProperties.getProperties("general");
    while (it.hasNext()) {
      Map.Entry pairs = (Map.Entry) it.next();
      if ("DEFAULT".equals(pairs.getValue())) {
        if (UtilValidate.isNotEmpty(generalProperties.get(pairs.getKey()))) {
          userPrefMap.put((String) pairs.getKey(), generalProperties.get(pairs.getKey()));
        }
      }
    }

    Map<String, Object> result = ServiceUtil.returnSuccess();
    result.put("userPrefMap", userPrefMap);
    return result;
  }
  /**
   * Retrieves a single user preference from persistent storage. Call with userPrefTypeId and
   * optional userPrefLoginId. If userPrefLoginId isn't specified, then the currently logged-in
   * user's userLoginId will be used. The retrieved preference is contained in the
   * <b>userPrefMap</b> element.
   *
   * @param ctx The DispatchContext that this service is operating in.
   * @param context Map containing the input arguments.
   * @return Map with the result of the service, the output parameters.
   */
  public static Map<String, Object> getUserPreference(DispatchContext ctx, Map<String, ?> context) {
    Locale locale = (Locale) context.get("locale");
    if (!PreferenceWorker.isValidGetId(ctx, context)) {
      return ServiceUtil.returnError(
          UtilProperties.getMessage(resource, "getPreference.permissionError", locale));
    }
    Delegator delegator = ctx.getDelegator();

    String userPrefTypeId = (String) context.get("userPrefTypeId");
    if (UtilValidate.isEmpty(userPrefTypeId)) {
      return ServiceUtil.returnError(
          UtilProperties.getMessage(resource, "getPreference.invalidArgument", locale));
    }
    String userLoginId = PreferenceWorker.getUserLoginId(context, true);
    Map<String, String> fieldMap =
        UtilMisc.toMap("userLoginId", userLoginId, "userPrefTypeId", userPrefTypeId);
    String userPrefGroupTypeId = (String) context.get("userPrefGroupTypeId");
    if (UtilValidate.isNotEmpty(userPrefGroupTypeId)) {
      fieldMap.put("userPrefGroupTypeId", userPrefGroupTypeId);
    }

    Map<String, Object> userPrefMap = null;
    try {
      GenericValue preference =
          EntityUtil.getFirst(delegator.findByAnd("UserPreference", fieldMap));
      if (preference != null) {
        userPrefMap = PreferenceWorker.createUserPrefMap(preference);
      }
    } catch (GenericEntityException e) {
      Debug.logWarning(e.getMessage(), module);
      return ServiceUtil.returnError(
          UtilProperties.getMessage(
              resource, "getPreference.readFailure", new Object[] {e.getMessage()}, locale));
    } catch (GeneralException e) {
      Debug.logWarning(e.getMessage(), module);
      return ServiceUtil.returnError(
          UtilProperties.getMessage(
              resource, "getPreference.readFailure", new Object[] {e.getMessage()}, locale));
    }

    Map<String, Object> result = ServiceUtil.returnSuccess();
    result.put("userPrefMap", userPrefMap);
    if (userPrefMap != null) {
      // Put the value in the result Map too, makes access easier for calling methods.
      Object userPrefValue = userPrefMap.get(userPrefTypeId);
      if (userPrefValue != null) {
        result.put("userPrefValue", userPrefValue);
      }
    }
    return result;
  }
  /**
   * Stores a user preference group in persistent storage. Call with userPrefMap,
   * userPrefGroupTypeId and optional userPrefLoginId. If userPrefLoginId isn't specified, then the
   * currently logged-in user's userLoginId will be used.
   *
   * @param ctx The DispatchContext that this service is operating in.
   * @param context Map containing the input arguments.
   * @return Map with the result of the service, the output parameters.
   */
  public static Map<String, Object> setUserPreferenceGroup(
      DispatchContext ctx, Map<String, ?> context) {
    Delegator delegator = ctx.getDelegator();
    Locale locale = (Locale) context.get("locale");

    String userLoginId = PreferenceWorker.getUserLoginId(context, false);
    Map<String, Object> userPrefMap =
        checkMap(context.get("userPrefMap"), String.class, Object.class);
    String userPrefGroupTypeId = (String) context.get("userPrefGroupTypeId");
    if (UtilValidate.isEmpty(userLoginId)
        || UtilValidate.isEmpty(userPrefGroupTypeId)
        || userPrefMap == null) {
      return ServiceUtil.returnError(
          UtilProperties.getMessage(resource, "setPreference.invalidArgument", locale));
    }

    try {
      for (Iterator i = userPrefMap.entrySet().iterator(); i.hasNext(); ) {
        Map.Entry mapEntry = (Map.Entry) i.next();
        GenericValue rec =
            delegator.makeValidValue(
                "UserPreference",
                PreferenceWorker.toFieldMap(
                    userLoginId,
                    (String) mapEntry.getKey(),
                    userPrefGroupTypeId,
                    (String) mapEntry.getValue()));
        delegator.createOrStore(rec);
      }
    } catch (GenericEntityException e) {
      Debug.logWarning(e.getMessage(), module);
      return ServiceUtil.returnError(
          UtilProperties.getMessage(
              resource, "setPreference.writeFailure", new Object[] {e.getMessage()}, locale));
    } catch (GeneralException e) {
      Debug.logWarning(e.getMessage(), module);
      return ServiceUtil.returnError(
          UtilProperties.getMessage(
              resource, "setPreference.writeFailure", new Object[] {e.getMessage()}, locale));
    }

    return ServiceUtil.returnSuccess();
  }
  /**
   * Stores a single user preference in persistent storage. Call with userPrefTypeId,
   * userPrefGroupTypeId, userPrefValue and optional userPrefLoginId. If userPrefLoginId isn't
   * specified, then the currently logged-in user's userLoginId will be used.
   *
   * @param ctx The DispatchContext that this service is operating in.
   * @param context Map containing the input arguments.
   * @return Map with the result of the service, the output parameters.
   */
  public static Map<String, Object> setUserPreference(DispatchContext ctx, Map<String, ?> context) {
    Delegator delegator = ctx.getDelegator();
    Locale locale = (Locale) context.get("locale");

    String userLoginId = PreferenceWorker.getUserLoginId(context, false);
    String userPrefTypeId = (String) context.get("userPrefTypeId");
    Object userPrefValue = (String) context.get("userPrefValue");
    if (UtilValidate.isEmpty(userLoginId)
        || UtilValidate.isEmpty(userPrefTypeId)
        || userPrefValue == null) {
      return ServiceUtil.returnError(
          UtilProperties.getMessage(resource, "setPreference.invalidArgument", locale));
    }
    String userPrefGroupTypeId = (String) context.get("userPrefGroupTypeId");
    String userPrefDataType = (String) context.get("userPrefDataType");

    try {
      if (UtilValidate.isNotEmpty(userPrefDataType)) {
        userPrefValue =
            ObjectType.simpleTypeConvert(userPrefValue, userPrefDataType, null, null, false);
      }
      GenericValue rec =
          delegator.makeValidValue(
              "UserPreference",
              PreferenceWorker.toFieldMap(
                  userLoginId, userPrefTypeId, userPrefGroupTypeId, userPrefValue));
      delegator.createOrStore(rec);
    } catch (GenericEntityException e) {
      Debug.logWarning(e.getMessage(), module);
      return ServiceUtil.returnError(
          UtilProperties.getMessage(
              resource, "setPreference.writeFailure", new Object[] {e.getMessage()}, locale));
    } catch (GeneralException e) {
      Debug.logWarning(e.getMessage(), module);
      return ServiceUtil.returnError(
          UtilProperties.getMessage(
              resource, "setPreference.writeFailure", new Object[] {e.getMessage()}, locale));
    }

    return ServiceUtil.returnSuccess();
  }