package com.regula.documentreader;

import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMapKeySetIterator;
import com.regula.documentreader.api.DocumentReader;
import com.regula.documentreader.api.ParamsCustomization;
import com.regula.documentreader.api.params.Functionality;
import com.regula.documentreader.api.params.ProcessParam;
import com.regula.documentreader.api.params.DataGroups;

import android.widget.ImageView.ScaleType;
import android.graphics.Typeface;
import android.graphics.Matrix;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

// You can read more about each these settings at 
// https://github.com/regulaforensics/DocumentReader-Android/wiki/Custom-settings

public class RegulaConfig {

  static String[] extractStringArray(ReadableArray readableArray) {
    String[] result = new String[readableArray.size()];
    for (int i = 0; i < readableArray.size(); i++) {
      result[i] = readableArray.getString(i);
    }
    return result;
  }

  static int[] extractIntArray(ReadableArray readableArray) {
    int[] result = new int[readableArray.size()];
    for (int i = 0; i < readableArray.size(); i++) {
      result[i] = readableArray.getInt(i);
    }
    return result;
  }

  static float[] extractFloatArray(ReadableArray readableArray) {
    float[] result = new float[readableArray.size()];
    for (int i = 0; i < readableArray.size(); i++) {
      result[i] = (float) readableArray.getDouble(i);
    }
    return result;
  }

  public static void setConfig(DocumentReader reader, ReadableMap opts) {
    if (opts.hasKey("customization"))
      setCustomization(reader.customization(), opts.getMap("customization"));
    if (opts.hasKey("functionality"))
      setFunctionality(reader.functionality(), opts.getMap("functionality"));
      if (opts.hasKey("processParams")) {
        JSONObject params = convertMapToJson(opts.getMap("processParams"));
        if (params.has("logs")) {
          try {
            params.put("log", params.optBoolean("logs"));
            params.remove("logs");
          } catch (JSONException e) {
          }
        }
        reader.processParams().fromJson(params.toString());
      }
  }

  public static JSONObject getConfig(DocumentReader reader) {
    JSONObject object = new JSONObject();
    try {
      object.put("customization", getCustomization(reader.customization()));
      object.put("functionality", getFunctionality(reader.functionality()));
      object.put("processParams", getProcessParams(reader.processParams()));
    } catch (JSONException e) {
    }

    return object;
  }

  public static void setFunctionality(Functionality functionality, ReadableMap opts) {
    if (opts.hasKey("pictureOnBoundsReady"))
      functionality.setPictureOnBoundsReady(opts.getBoolean("pictureOnBoundsReady"));
    if (opts.hasKey("showTorchButton"))
      functionality.setShowTorchButton(opts.getBoolean("showTorchButton"));
    if (opts.hasKey("showCloseButton"))
      functionality.setShowCloseButton(opts.getBoolean("showCloseButton"));
    if (opts.hasKey("videoCaptureMotionControl"))
      functionality.setVideoCaptureMotionControl(opts.getBoolean("videoCaptureMotionControl"));
    if (opts.hasKey("showCaptureButton"))
      functionality.setShowCaptureButton(opts.getBoolean("showCaptureButton"));
    if (opts.hasKey("showChangeFrameButton"))
      functionality.setShowChangeFrameButton(opts.getBoolean("showChangeFrameButton"));
    if (opts.hasKey("showCaptureButtonDelayFromDetect"))
      functionality.setShowCaptureButtonDelayFromDetect(opts.getInt("showCaptureButtonDelayFromDetect"));
    if (opts.hasKey("showCaptureButtonDelayFromStart"))
      functionality.setShowCaptureButtonDelayFromStart(opts.getInt("showCaptureButtonDelayFromStart"));
    if (opts.hasKey("isOnlineMode"))
      functionality.setOnlineMode(opts.getBoolean("isOnlineMode"));
    if (opts.hasKey("databaseAutoupdate"))
      functionality.setDatabaseAutoupdate(opts.getBoolean("databaseAutoupdate"));
    if (opts.hasKey("showSkipNextPageButton"))
      functionality.setShowSkipNextPageButton(opts.getBoolean("showSkipNextPageButton"));
    if (opts.hasKey("useAuthenticator"))
      functionality.setUseAuthenticator(opts.getBoolean("useAuthenticator"));
    if (opts.hasKey("skipFocusingFrames"))
      functionality.setSkipFocusingFrames(opts.getBoolean("skipFocusingFrames"));
    if (opts.hasKey("showCameraSwitchBtn"))
      functionality.setShowCameraSwitchBtn(opts.getBoolean("showCameraSwitchBtn"));
    if (opts.hasKey("cameraFrame"))
      functionality.setCameraFrame(opts.getString("cameraFrame"));
    if (opts.hasKey("serviceURL"))
      functionality.setServiceURL(opts.getString("serviceURL"));
    if (opts.hasKey("databaseIdentifier"))
      functionality.setDatabaseIdentifier(opts.getString("databaseIdentifier"));
    if (opts.hasKey("btDeviceName"))
      functionality.setBtDeviceName(opts.getString("btDeviceName"));
    if (opts.hasKey("orientation"))
      functionality.setOrientation(opts.getInt("orientation"));
  }

  public static void setCustomization(ParamsCustomization customization, ReadableMap opts) {
    if (opts.hasKey("status"))
      customization.setStatus(opts.getString("status"));
    if (opts.hasKey("resultStatus"))
      customization.setResultStatus(opts.getString("resultStatus"));
    if (opts.hasKey("cameraFrameDefaultColor"))
      customization.setCameraFrameDefaultColor(opts.getString("cameraFrameDefaultColor"));
    if (opts.hasKey("cameraFrameActiveColor"))
      customization.setCameraFrameActiveColor(opts.getString("cameraFrameActiveColor"));
    if (opts.hasKey("statusTextColor"))
      customization.setStatusTextColor(opts.getString("statusTextColor"));
    if (opts.hasKey("resultStatusTextColor"))
      customization.setResultStatusTextColor(opts.getString("resultStatusTextColor"));
    if (opts.hasKey("resultStatusBackgroundColor"))
      customization.setResultStatusBackgroundColor(opts.getString("resultStatusBackgroundColor"));
    if (opts.hasKey("multipageButtonBackgroundColor"))
      customization.setMultipageButtonBackgroundColor(opts.getString("multipageButtonBackgroundColor"));
    if (opts.hasKey("tintColor"))
      customization.setTintColor(opts.getString("tintColor"));
    if (opts.hasKey("activityIndicatorColor"))
      customization.setActivityIndicatorColor(opts.getString("activityIndicatorColor"));
    if (opts.hasKey("showStatusMessages"))
      customization.setShowStatusMessages(opts.getBoolean("showStatusMessages"));
    if (opts.hasKey("showResultStatusMessages"))
      customization.setShowResultStatusMessages(opts.getBoolean("showResultStatusMessages"));
    if (opts.hasKey("showHelpAnimation"))
      customization.setShowHelpAnimation(opts.getBoolean("showHelpAnimation"));
    if (opts.hasKey("showNextPageAnimation"))
      customization.setShowNextPageAnimation(opts.getBoolean("showNextPageAnimation"));
    if (opts.hasKey("showBackgroundMask"))
      customization.setShowBackgroundMask(opts.getBoolean("showBackgroundMask"));
    if (opts.hasKey("cameraFrameBorderWidth"))
      customization.setCameraFrameBorderWidth(opts.getInt("cameraFrameBorderWidth"));
    if (opts.hasKey("statusTextSize"))
      customization.setStatusTextSize(opts.getInt("statusTextSize"));
    if (opts.hasKey("cameraFrameLineLength"))
      customization.setCameraFrameLineLength(opts.getInt("cameraFrameLineLength"));
    if (opts.hasKey("cameraFrameShapeType"))
      customization.setCameraFrameShapeType(opts.getInt("cameraFrameShapeType"));
    if (opts.hasKey("resultStatusTextSize"))
      customization.setResultStatusTextSize(opts.getInt("resultStatusTextSize"));
    if (opts.hasKey("helpAnimationImageID"))
      customization.setHelpAnimationImageID(opts.getInt("helpAnimationImageID"));
    if (opts.hasKey("multipageAnimationFrontImage"))
      customization.setMultipageAnimationFrontImage(opts.getInt("multipageAnimationFrontImage"));
    if (opts.hasKey("multipageAnimationBackImage"))
      customization.setMultipageAnimationBackImage(opts.getInt("multipageAnimationBackImage"));
    if (opts.hasKey("borderBackgroundImage"))
      customization.setBorderBackgroundImage(opts.getInt("borderBackgroundImage"));
    if (opts.hasKey("statusPositionMultiplier"))
      customization.setStatusPositionMultiplier(opts.getDouble("statusPositionMultiplier"));
    if (opts.hasKey("resultStatusPositionMultiplier"))
      customization.setResultStatusPositionMultiplier(opts.getDouble("resultStatusPositionMultiplier"));
    if (opts.hasKey("backgroundMaskAlpha"))
      customization.setBackgroundMaskAlpha((float) opts.getDouble("backgroundMaskAlpha"));
    if (opts.hasKey("statusTextFont"))
      customization
          .setStatusTextFont(Typeface.create(opts.getString("statusTextFont"), opts.getInt("statusTextFontStyle")));
    if (opts.hasKey("resultStatusTextFont"))
      customization.setResultStatusTextFont(
          Typeface.create(opts.getString("resultStatusTextFont"), opts.getInt("resultStatusTextFontStyle")));
    if (opts.hasKey("helpAnimationImageScaleType"))
      customization.setHelpAnimationImageScaleType(ScaleType.valueOf(opts.getString("helpAnimationImageScaleType")));
    if (opts.hasKey("multipageAnimationFrontImageScaleType"))
      customization.setMultipageAnimationFrontImageScaleType(
          ScaleType.valueOf(opts.getString("multipageAnimationFrontImageScaleType")));
    if (opts.hasKey("multipageAnimationBackImageScaleType"))
      customization.setMultipageAnimationBackImageScaleType(
          ScaleType.valueOf(opts.getString("multipageAnimationBackImageScaleType")));
    if (opts.hasKey("helpAnimationImageMatrix")) {
      Matrix matrix = new Matrix();
      matrix.setValues(extractFloatArray(opts.getArray("helpAnimationImageMatrix")));
      customization.setHelpAnimationImageMatrix(matrix);
    }
    if (opts.hasKey("multipageAnimationFrontImageMatrix")) {
      Matrix matrix = new Matrix();
      matrix.setValues(extractFloatArray(opts.getArray("multipageAnimationFrontImageMatrix")));
      customization.setMultipageAnimationFrontImageMatrix(matrix);
    }
    if (opts.hasKey("multipageAnimationBackImageMatrix")) {
      Matrix matrix = new Matrix();
      matrix.setValues(extractFloatArray(opts.getArray("multipageAnimationBackImageMatrix")));
      customization.setMultipageAnimationBackImageMatrix(matrix);
    }
  }

  public static JSONObject getFunctionality(Functionality functionality) {
    JSONObject object = new JSONObject();
    try {
      object.put("pictureOnBoundsReady", functionality.isPictureOnBoundsReady());
      object.put("showTorchButton", functionality.isShowTorchButton());
      object.put("showCloseButton", functionality.isShowCloseButton());
      object.put("videoCaptureMotionControl", functionality.isVideoCaptureMotionControl());
      object.put("showCaptureButton", functionality.isShowCaptureButton());
      object.put("showChangeFrameButton", functionality.isShowChangeFrameButton());
      object.put("showCaptureButtonDelayFromDetect", functionality.getShowCaptureButtonDelayFromDetect());
      object.put("showCaptureButtonDelayFromStart", functionality.getShowCaptureButtonDelayFromStart());
      object.put("isOnlineMode", functionality.isOnlineMode());
      object.put("databaseAutoupdate", functionality.isDatabaseAutoupdate());
      object.put("showSkipNextPageButton", functionality.isShowSkipNextPageButton());
      object.put("useAuthenticator", functionality.isUseAuthenticator());
      object.put("skipFocusingFrames", functionality.isSkipFocusingFrames());
      object.put("showCameraSwitchBtn", functionality.isShowCameraSwitchBtn());
      object.put("cameraFrame", functionality.getCameraFrame());
      object.put("serviceURL", functionality.getServiceURL());
      object.put("databaseIdentifier", functionality.getDatabaseIdentifier());
      object.put("btDeviceName", functionality.getBtDeviceName());
      object.put("orientation", functionality.getOrientation());
    } catch (JSONException e) {
    }

    return object;
  }

  public static JSONObject getCustomization(ParamsCustomization customization) {
    JSONObject object = new JSONObject();
    try {
      object.put("status", customization.getStatus());
      object.put("resultStatus", customization.getResultStatus());
      object.put("cameraFrameDefaultColor", customization.getCameraFrameDefaultColor());
      object.put("cameraFrameActiveColor", customization.getCameraFrameActiveColor());
      object.put("statusTextColor", customization.getStatusTextColor());
      object.put("resultStatusTextColor", customization.getResultStatusTextColor());
      object.put("resultStatusBackgroundColor", customization.getResultStatusBackgroundColor());
      object.put("multipageButtonBackgroundColor", customization.getMultipageButtonBackgroundColor());
      object.put("tintColor", customization.getTintColor());
      object.put("activityIndicatorColor", customization.getActivityIndicatorColor());
      object.put("showStatusMessages", customization.isShowStatusMessages());
      object.put("showResultStatusMessages", customization.isShowResultStatusMessages());
      object.put("showHelpAnimation", customization.isShowHelpAnimation());
      object.put("showNextPageAnimation", customization.isShowNextPageAnimation());
      object.put("showBackgroundMask", customization.isShowBackgroundMask());
      object.put("cameraFrameBorderWidth", customization.getCameraFrameBorderWidth());
      object.put("statusTextSize", customization.getStatusTextSize());
      object.put("cameraFrameLineLength", customization.getCameraFrameLineLength());
      object.put("cameraFrameShapeType", customization.getCameraFrameShapeType());
      object.put("resultStatusTextSize", customization.getResultStatusTextSize());
      object.put("helpAnimationImageID", customization.getHelpAnimationImageID());
      object.put("multipageAnimationFrontImage", customization.getMultipageAnimationFrontImage());
      object.put("multipageAnimationBackImage", customization.getMultipageAnimationBackImage());
      object.put("borderBackgroundImage", customization.getBorderBackgroundImage());
      object.put("helpAnimationImageScaleType", customization.getHelpAnimationImageScaleType());
      object.put("multipageAnimationFrontImageScaleType", customization.getMultipageAnimationFrontImageScaleType());
      object.put("multipageAnimationBackImageScaleType", customization.getMultipageAnimationBackImageScaleType());
      object.put("helpAnimationImageMatrix", customization.getHelpAnimationImageMatrix());
      object.put("multipageAnimationFrontImageMatrix", customization.getMultipageAnimationFrontImageMatrix());
      object.put("multipageAnimationBackImageMatrix", customization.getMultipageAnimationBackImageMatrix());
      object.put("statusTextFont", customization.getStatusTextFont());
      object.put("resultStatusTextFont", customization.getResultStatusTextFont());
      object.put("statusPositionMultiplier", customization.getStatusPositionMultiplier());
      object.put("resultStatusPositionMultiplier", customization.getResultStatusPositionMultiplier());
      object.put("backgroundMaskAlpha", customization.getBackgroundMaskAlpha());
    } catch (JSONException e) {
    }

    return object;
  }

  public static JSONObject getProcessParams(ProcessParam processParams) {
    JSONObject object = new JSONObject();
    try {
      object.put("scenario", processParams.scenario);
      object.put("measureSystem", processParams.measureSystem);
      object.put("uvTorchEnabled", processParams.uvTorchEnabled);
      object.put("logs", processParams.logs);
      object.put("debugSaveImages", true);
      object.put("debugSaveLogs", processParams.debugSaveLogs);
      object.put("multipageProcessing", processParams.multipageProcessing);
      object.put("dateFormat", processParams.dateFormat);
      object.put("debugSaveCroppedImages", processParams.debugSaveCroppedImages);
      object.put("sessionLogFolder", processParams.sessionLogFolder);
      object.put("disableFocusingCheck", processParams.disableFocusingCheck);
      object.put("captureButtonScenario", processParams.captureButtonScenario);
      object.put("returnUncroppedImage", processParams.returnUncroppedImage);
      if (processParams.customParams != null) {
        object.put("customParams", processParams.customParams.toString());
      } else {
        object.put("customParams", new JSONArray());
      }

      JSONArray jdocumentIDList = new JSONArray();
      if (processParams.documentIDList != null && processParams.documentIDList.length > 0) {
        int index = 0;
        for (int item : processParams.documentIDList) {
          jdocumentIDList.put(index, item);
          index++;
        }
      }
      object.put("documentIDList", jdocumentIDList);

      JSONArray jdoBarcodes = new JSONArray();
      if (processParams.doBarcodes != null && processParams.doBarcodes.length > 0) {
        int index = 0;
        for (String item : processParams.doBarcodes) {
          jdoBarcodes.put(index, item);
          index++;
        }
      }
      object.put("doBarcodes", jdoBarcodes);

      JSONArray jfieldTypesFilter = new JSONArray();
      if (processParams.fieldTypesFilter != null && processParams.fieldTypesFilter.length > 0) {
        int index = 0;
        for (int item : processParams.fieldTypesFilter) {
          jfieldTypesFilter.put(index, item);
          index++;
        }
      }
      object.put("fieldTypesFilter", jfieldTypesFilter);
    } catch (Exception e) {
    }
    return object;
  }

  public static void setRfidScenario(DocumentReader reader, ReadableMap opts) {
    if (opts.hasKey("paceStaticBinding"))
      reader.Instance().rfidScenario().setPaceStaticBinding(opts.getBoolean("PACE_StaticBinding"));
    if (opts.hasKey("signManagementAction"))
      reader.Instance().rfidScenario().setSignManagementAction(opts.getInt("signManagementAction"));
    if (opts.hasKey("readingBuffer"))
      reader.Instance().rfidScenario().setReadingBuffer(opts.getInt("readingBuffer"));
    if (opts.hasKey("onlineTAToSignDataType"))
      reader.Instance().rfidScenario().setOnlineTAToSignDataType(opts.getInt("onlineTAToSignDataType"));
    if (opts.hasKey("onlineTA"))
      reader.Instance().rfidScenario().setOnlineTA(opts.getBoolean("onlineTA"));
    if (opts.hasKey("writeEid"))
      reader.Instance().rfidScenario().setWriteEid(opts.getBoolean("writeEid"));
    if (opts.hasKey("profilerType"))
      reader.Instance().rfidScenario().setProfilerType(opts.getInt("profilerType"));
    if (opts.hasKey("authProcType"))
      reader.Instance().rfidScenario().setAuthProcType(opts.getInt("authProcType"));
    if (opts.hasKey("baseSMProcedure"))
      reader.Instance().rfidScenario().setBaseSMProcedure(opts.getInt("baseSMProcedure"));
    if (opts.hasKey("pacePasswordType"))
      reader.Instance().rfidScenario().setPacePasswordType(opts.getInt("pacePasswordType"));
    if (opts.hasKey("terminalType"))
      reader.Instance().rfidScenario().setTerminalType(opts.getInt("terminalType"));
    if (opts.hasKey("universalAccessRights"))
      reader.Instance().rfidScenario().setUniversalAccessRights(opts.getBoolean("universalAccessRights"));
    if (opts.hasKey("authorizedRestrictedIdentification"))
      reader.Instance().rfidScenario()
          .setAuthorizedRestrictedIdentification(opts.getBoolean("authorizedRestrictedIdentification"));
    if (opts.hasKey("auxVerificationCommunityID"))
      reader.Instance().rfidScenario().setAuxVerificationCommunityID(opts.getBoolean("auxVerificationCommunityID"));
    if (opts.hasKey("auxVerificationDateOfBirth"))
      reader.Instance().rfidScenario().setAuxVerificationDateOfBirth(opts.getBoolean("auxVerificationDateOfBirth"));
    if (opts.hasKey("skipAA"))
      reader.Instance().rfidScenario().setSkipAA(opts.getBoolean("skipAA"));
    if (opts.hasKey("strictProcessing"))
      reader.Instance().rfidScenario().setStrictProcessing(opts.getBoolean("strictProcessing"));
    if (opts.hasKey("pkdDSCertPriority"))
      reader.Instance().rfidScenario().setPkdDSCertPriority(opts.getBoolean("pkdDSCertPriority"));
    if (opts.hasKey("pkdUseExternalCSCA"))
      reader.Instance().rfidScenario().setPkdUseExternalCSCA(opts.getBoolean("pkdUseExternalCSCA"));
    if (opts.hasKey("trustedPKD"))
      reader.Instance().rfidScenario().setTrustedPKD(opts.getBoolean("trustedPKD"));
    if (opts.hasKey("passiveAuth"))
      reader.Instance().rfidScenario().setPassiveAuth(opts.getBoolean("passiveAuth"));
    if (opts.hasKey("password"))
      reader.Instance().rfidScenario().setPassword(opts.getString("password"));
    if (opts.hasKey("useSFI"))
      reader.Instance().rfidScenario().setUseSFI(opts.getBoolean("useSFI"));
    if (opts.hasKey("pkdPA"))
      reader.Instance().rfidScenario().setPkdPA(opts.getString("pkdPA"));
    if (opts.hasKey("pkdEAC"))
      reader.Instance().rfidScenario().setPkdEAC(opts.getString("pkdEAC"));
    if (opts.hasKey("readEPassport"))
      reader.Instance().rfidScenario().setReadEPassport(opts.getBoolean("readEPassport"));
    if (opts.hasKey("readEID"))
      reader.Instance().rfidScenario().setReadEID(opts.getBoolean("readEID"));
    if (opts.hasKey("readEDL"))
      reader.Instance().rfidScenario().setReadEDL(opts.getBoolean("readEDL"));
    if (opts.hasKey("mrz"))
      reader.Instance().rfidScenario().setMrz(opts.getString("mrz"));
    if (opts.hasKey("eSignPINDefault"))
      reader.Instance().rfidScenario().seteSignPINDefault(opts.getString("eSignPINDefault"));
    if (opts.hasKey("eSignPINNewValue"))
      reader.Instance().rfidScenario().seteSignPINNewValue(opts.getString("eSignPINNewValue"));
    if (opts.hasKey("authorizedSTSignature"))
      reader.Instance().rfidScenario().setAuthorizedSTSignature(opts.getBoolean("authorizedSTSignature"));
    if (opts.hasKey("authorizedSTQSignature"))
      reader.Instance().rfidScenario().setAuthorizedSTQSignature(opts.getBoolean("authorizedSTQSignature"));
    if (opts.hasKey("authorizedWriteDG17"))
      reader.Instance().rfidScenario().setAuthorizedWriteDG17(opts.getBoolean("authorizedWriteDG17"));
    if (opts.hasKey("authorizedWriteDG18"))
      reader.Instance().rfidScenario().setAuthorizedWriteDG18(opts.getBoolean("authorizedWriteDG18"));
    if (opts.hasKey("authorizedWriteDG19"))
      reader.Instance().rfidScenario().setAuthorizedWriteDG19(opts.getBoolean("authorizedWriteDG19"));
    if (opts.hasKey("authorizedWriteDG20"))
      reader.Instance().rfidScenario().setAuthorizedWriteDG20(opts.getBoolean("authorizedWriteDG20"));
    if (opts.hasKey("authorizedWriteDG21"))
      reader.Instance().rfidScenario().setAuthorizedWriteDG21(opts.getBoolean("authorizedWriteDG21"));
    if (opts.hasKey("authorizedVerifyAge"))
      reader.Instance().rfidScenario().setAuthorizedVerifyAge(opts.getBoolean("authorizedVerifyAge"));
    if (opts.hasKey("authorizedVerifyCommunityID"))
      reader.Instance().rfidScenario()
          .setAuthorizedVerifyCommunityID(opts.getBoolean("authorizedVerifyCommunityID"));
    if (opts.hasKey("authorizedPrivilegedTerminal"))
      reader.Instance().rfidScenario()
          .setAuthorizedPrivilegedTerminal(opts.getBoolean("authorizedPrivilegedTerminal"));
    if (opts.hasKey("authorizedCANAllowed"))
      reader.Instance().rfidScenario().setAuthorizedCANAllowed(opts.getBoolean("authorizedCANAllowed"));
    if (opts.hasKey("authorizedPINManagement"))
      reader.Instance().rfidScenario().setAuthorizedPINManagment(opts.getBoolean("authorizedPINManagement"));
    if (opts.hasKey("authorizedInstallCert"))
      reader.Instance().rfidScenario().setAuthorizedInstallCert(opts.getBoolean("authorizedInstallCert"));
    if (opts.hasKey("authorizedInstallQCert"))
      reader.Instance().rfidScenario().setAuthorizedInstallQCert(opts.getBoolean("authorizedInstallQCert"));
    if (opts.hasKey("ePassportDataGroups"))
      setDataGroups(reader.Instance().rfidScenario().ePassportDataGroups(), opts.getMap("ePassportDataGroups"));
    if (opts.hasKey("eIDDataGroups"))
      setDataGroups(reader.Instance().rfidScenario().eIDDataGroups(), opts.getMap("eIDDataGroups"));
    if (opts.hasKey("eDLDataGroups"))
      setDataGroups(reader.Instance().rfidScenario().eDLDataGroups(), opts.getMap("eDLDataGroups"));
  }

  private static void setDataGroups(DataGroups dataGroup, ReadableMap opts) {
    if (opts.hasKey("DG1"))
      dataGroup.setDG1(opts.getBoolean("DG1"));
    if (opts.hasKey("DG2"))
      dataGroup.setDG2(opts.getBoolean("DG2"));
    if (opts.hasKey("DG3"))
      dataGroup.setDG3(opts.getBoolean("DG3"));
    if (opts.hasKey("DG4"))
      dataGroup.setDG4(opts.getBoolean("DG4"));
    if (opts.hasKey("DG5"))
      dataGroup.setDG5(opts.getBoolean("DG5"));
    if (opts.hasKey("DG6"))
      dataGroup.setDG6(opts.getBoolean("DG6"));
    if (opts.hasKey("DG7"))
      dataGroup.setDG7(opts.getBoolean("DG7"));
    if (opts.hasKey("DG8"))
      dataGroup.setDG8(opts.getBoolean("DG8"));
    if (opts.hasKey("DG9"))
      dataGroup.setDG9(opts.getBoolean("DG9"));
    if (opts.hasKey("DG10"))
      dataGroup.setDG10(opts.getBoolean("DG10"));
    if (opts.hasKey("DG11"))
      dataGroup.setDG11(opts.getBoolean("DG11"));
    if (opts.hasKey("DG12"))
      dataGroup.setDG12(opts.getBoolean("DG12"));
    if (opts.hasKey("DG13"))
      dataGroup.setDG13(opts.getBoolean("DG13"));
    if (opts.hasKey("DG14"))
      dataGroup.setDG14(opts.getBoolean("DG14"));
    if (opts.hasKey("DG15"))
      dataGroup.setDG15(opts.getBoolean("DG15"));
    if (opts.hasKey("DG16"))
      dataGroup.setDG16(opts.getBoolean("DG16"));
  }

  private static JSONObject convertMapToJson(ReadableMap readableMap) {
    JSONObject object = new JSONObject();
    try {
      ReadableMapKeySetIterator iterator = readableMap.keySetIterator();
      while (iterator.hasNextKey()) {
        String key = iterator.nextKey();
        switch (readableMap.getType(key)) {
        case Null:
          object.put(key, JSONObject.NULL);
          break;
        case Boolean:
          object.put(key, readableMap.getBoolean(key));
          break;
        case Number:
          object.put(key, readableMap.getDouble(key));
          break;
        case String:
          object.put(key, readableMap.getString(key));
          break;
        case Map:
          object.put(key, convertMapToJson(readableMap.getMap(key)));
          break;
        case Array:
          object.put(key, convertArrayToJson(readableMap.getArray(key)));
          break;
        }
      }
    } catch (JSONException e) {
    }

    return object;
  }

  private static JSONArray convertArrayToJson(ReadableArray readableArray) {
    JSONArray array = new JSONArray();
    try {
      for (int i = 0; i < readableArray.size(); i++) {
        switch (readableArray.getType(i)) {
        case Null:
          break;
        case Boolean:
          array.put(readableArray.getBoolean(i));
          break;
        case Number:
          array.put(readableArray.getDouble(i));
          break;
        case String:
          array.put(readableArray.getString(i));
          break;
        case Map:
          array.put(convertMapToJson(readableArray.getMap(i)));
          break;
        case Array:
          array.put(convertArrayToJson(readableArray.getArray(i)));
          break;
        }
      }
    } catch (JSONException e) {
    }

    return array;
  }
}