/**
   * Create the parameters file.
   *
   * @param searchParametersFile the file where to save the search parameters
   * @return the parameters file
   * @throws IOException exception thrown whenever an error occurred while writing the configuration
   *     file
   */
  private File createParametersFile(File searchParametersFile) throws IOException {

    File andromedaTempFolder = new File(andromedaTempFolderPath);

    String fileName;
    try {
      fileName = Util.removeExtension(searchParametersFile.getName()) + ".apar";
    } catch (Exception e) {
      fileName = "SearchGUI.apar";
    }

    File parameterFile = new File(andromedaTempFolder, fileName);
    BufferedWriter bw = new BufferedWriter(new FileWriter(parameterFile));

    try {
      boolean semiSpecific = false;
      DigestionPreferences digestionPreferences = searchParameters.getDigestionPreferences();

      if (digestionPreferences.getCleavagePreference()
          == DigestionPreferences.CleavagePreference.enzyme) {
        Enzyme enzyme = digestionPreferences.getEnzymes().get(0);
        String enzymeName = enzyme.getName();
        bw.write("enzymes=" + enzymeName); // @TODO: support multiple enzymes?
        bw.newLine();
        if (digestionPreferences.getSpecificity(enzyme.getName())
                == DigestionPreferences.Specificity.semiSpecific
            || digestionPreferences.getSpecificity(enzyme.getName())
                == DigestionPreferences.Specificity.specificCTermOnly
            || digestionPreferences.getSpecificity(enzyme.getName())
                == DigestionPreferences.Specificity.specificNTermOnly) {
          semiSpecific = true;
        }
      } else if (digestionPreferences.getCleavagePreference()
          == DigestionPreferences.CleavagePreference.unSpecific) {
        bw.write("enzyme mode=unspecific");
        bw.newLine();
      } else {
        // whole enzyme
        // @TODO: what to put here..?
      }

      if (semiSpecific) {
        bw.write("enzyme mode=semispecific"); // @TODO: support: Semispecific Free N-terminus and
        // Semispecific Free C-terminus
      } else {
        bw.write("enzyme mode=specific");
      }
      bw.newLine();
      PtmSettings modificationProfile = searchParameters.getPtmSettings();
      StringBuilder list = new StringBuilder();
      for (String ptmName : modificationProfile.getVariableModifications()) {
        if (list.length() > 0) {
          list.append(",");
        }
        list.append(ptmName);
      }
      bw.write("variable modifications=" + list);
      bw.newLine();
      list = new StringBuilder();
      for (String ptmName : modificationProfile.getFixedModifications()) {
        if (list.length() > 0) {
          list.append(",");
        }
        list.append(ptmName);
      }
      bw.write("fixed modifications=" + list);
      bw.newLine();
      bw.write("label modifications="); // @TODO: support labels
      bw.newLine();
      if (!modificationProfile.getRefinementVariableModifications().isEmpty()) {
        bw.write("has additional variable modifications=True");
        bw.newLine();
        list = new StringBuilder();
        for (String ptmName : modificationProfile.getRefinementVariableModifications()) {
          if (list.length() > 0) {
            list.append(",");
          }
          list.append(ptmName);
        }
        bw.write("additional variable modifications=" + list);
        bw.newLine();
        bw.write("additional variable modification proteins=");
        bw.newLine();
      } else {
        bw.write("has additional variable modifications=False");
        bw.newLine();
        bw.write("additional variable modifications=");
        bw.newLine();
        bw.write("additional variable modification proteins=");
        bw.newLine();
      }
      bw.write("peptide mass tolerance=" + searchParameters.getPrecursorAccuracy());
      bw.newLine();
      bw.write("max peptide mass=" + andromedaParameters.getMaxPeptideMass());
      bw.newLine();
      bw.write("max combinations=" + andromedaParameters.getMaxCombinations());
      bw.newLine();
      if (searchParameters.isPrecursorAccuracyTypePpm()) {
        bw.write("peptide mass tolerance Unit=ppm");
      } else {
        bw.write("peptide mass tolerance Unit=Da");
      }
      bw.newLine();
      bw.write("fragment mass tolerance=" + searchParameters.getFragmentIonAccuracy());
      bw.newLine();
      if (searchParameters.getFragmentAccuracyType() == SearchParameters.MassAccuracyType.PPM) {
        bw.write("fragment mass tolerance Unit=ppm");
      } else {
        bw.write("fragment mass tolerance Unit=Da");
      }
      bw.newLine();
      bw.write("top peaks=" + andromedaParameters.getTopPeaks());
      bw.newLine();
      bw.write("top peaks window=" + andromedaParameters.getTopPeaksWindow());
      bw.newLine();

      if (digestionPreferences.getCleavagePreference()
          == DigestionPreferences.CleavagePreference.enzyme) {
        Integer missedCleavages = null;
        for (Enzyme enzyme : digestionPreferences.getEnzymes()) {
          int enzymeMissedCleavages = digestionPreferences.getnMissedCleavages(enzyme.getName());
          if (missedCleavages == null || enzymeMissedCleavages > missedCleavages) {
            missedCleavages = enzymeMissedCleavages;
          }
        }
        bw.write("max missed cleavages=" + missedCleavages);
        bw.newLine();
      }

      bw.write("fasta file=\"" + searchParameters.getFastaFile().getAbsolutePath() + "\"");
      bw.newLine();
      bw.write("decoy mode=" + andromedaParameters.getDecoyMode());
      bw.newLine();
      bw.write("include contaminants=False");
      bw.newLine();
      if (andromedaParameters.isIncludeWater()) {
        bw.write("include water=True");
      } else {
        bw.write("include water=False");
      }
      bw.newLine();
      if (andromedaParameters.isIncludeAmmonia()) {
        bw.write("include ammonia=True");
      } else {
        bw.write("include ammonia=False");
      }
      bw.newLine();
      if (andromedaParameters.isDependentLosses()) {
        bw.write("dependent losses=True");
      } else {
        bw.write("dependent losses=False");
      }
      bw.newLine();
      bw.write("special aas=");
      bw.newLine();
      if (andromedaParameters.isFragmentAll()) {
        bw.write("fragment all=True");
      } else {
        bw.write("fragment all=False");
      }
      bw.newLine();
      if (andromedaParameters.isEmpiricalCorrection()) {
        bw.write("empirical correction=True");
      } else {
        bw.write("empirical correction=False");
      }
      bw.newLine();
      if (andromedaParameters.isHigherCharge()) {
        bw.write("higher charges=True");
      } else {
        bw.write("higher charges=False");
      }
      bw.newLine();
      bw.write("fragmentation type=" + andromedaParameters.getFragmentationMethod().name);
      bw.newLine();
      bw.write("max number of modifications=" + andromedaParameters.getMaxNumberOfModifications());
      bw.newLine();
      bw.write("min peptide length no enzyme=" + andromedaParameters.getMinPeptideLengthNoEnzyme());
      bw.newLine();
      bw.write("max peptide length no enzyme=" + andromedaParameters.getMaxPeptideLengthNoEnzyme());
      bw.newLine();
      if (andromedaParameters.isEqualIL()) {
        bw.write("equal il=True");
      } else {
        bw.write("equal il=False");
      }
      bw.newLine();
      bw.write("number of candidates=" + andromedaParameters.getNumberOfCandidates());
      bw.newLine();

    } finally {
      bw.close();
    }
    return parameterFile;
  }
  /**
   * Creates the enzyme configuration file.
   *
   * @param andromedaFolder the Andromeda installation folder
   * @throws IOException exception thrown whenever an error occurred while writing the file.
   */
  public static void createEnzymesFile(File andromedaFolder) throws IOException {
    EnzymeFactory enzymeFactory = EnzymeFactory.getInstance();
    File file = new File(andromedaFolder, "conf");
    file = new File(file, "enzymes.xml");
    BufferedWriter bw = new BufferedWriter(new FileWriter(file));
    int index = 0;
    String date = "0001-01-01T00:00:00";
    try {
      bw.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
      bw.newLine();
      bw.write(
          "<enzymes xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">");
      bw.newLine();
      for (Enzyme enzyme : enzymeFactory.getEnzymes()) {

        bw.write(
            "   <enzyme index=\""
                + index
                + "\" title=\""
                + enzyme.getName()
                + "\" description=\""
                + enzyme.getDescription()
                + "\" create_date=\""
                + date
                + "\" last_modified_date=\""
                + date
                + "\" user=\"SearchGUI\">");
        bw.newLine();
        bw.write("      <specificity>");
        bw.newLine();
        ArrayList<Character> aaBefore = new ArrayList<Character>(enzyme.getAminoAcidBefore());
        if (aaBefore.isEmpty()) {
          for (char aa : AminoAcid.getUniqueAminoAcids()) {
            aaBefore.add(aa);
          }
        }
        ArrayList<Character> aaAfter = new ArrayList<Character>(enzyme.getAminoAcidAfter());
        if (aaAfter.isEmpty()) {
          for (char aa : AminoAcid.getUniqueAminoAcids()) {
            aaAfter.add(aa);
          }
        }
        for (Character aa1 : aaBefore) {
          for (Character aa2 : aaAfter) {
            if (!enzyme.getRestrictionBefore().contains(aa1)
                && !enzyme.getRestrictionAfter().contains(aa2)) {
              bw.write("         <string>" + aa1 + aa2 + "</string>");
              bw.newLine();
            }
          }
        }
        bw.write("      </specificity>");
        bw.newLine();
        bw.write("    </enzyme>");
        bw.newLine();
        index++;
      }
      bw.write("</enzymes>");
      bw.newLine();
    } finally {
      bw.close();
    }
  }