/**
  * Returns decoded message
  *
  * @param msg Integer[]
  * @return String
  */
 public String deCode(Integer[] msg) {
   String unpadded = "";
   for (int i = 0; i < msg.length; i++) {
     unpadded = unpadded + alphaNum.getLetter(msg[i]);
   }
   unpadded = unpadded.replaceAll("X", " ");
   return unpadded;
 }
  /**
   * Returns enCoded message
   *
   * @param msg String
   * @return numbers Integer[]
   */
  public Integer[] enCode(String msg) {
    msg = msg.toUpperCase();
    msg = msg.replace(" ", "X");

    Integer[] numbers = new Integer[msg.length()];
    char[] table = msg.toCharArray();
    for (int j = 0; j < table.length; j++) {
      numbers[j] = alphaNum.getNum(String.valueOf(table[j]));
    }
    return numbers;
  }
  /**
   * Returns all phases of decrypting and decoding in a String
   *
   * @param msg String
   * @param exp BigInteger
   * @param mod BigInteger
   * @return String
   */
  public String getDeCrypted(String msg, BigInteger exp, BigInteger mod) {
    StringBuilder s = new StringBuilder();
    AlphabetNum alpha = new AlphabetNum();
    EncryptDecrypt decrypter = new EncryptDecrypt();

    // --------------------cryptotext to numbers------------------
    s.append("Cryptotext: \n");
    s.append(msg + "\n\n");
    s.append(alpha.getLetters() + "\n\n");
    msg = alpha.stringOfLettersToNumbers(msg);
    String[] stringMessage = msg.split(" "); // Message in String[]

    // ----------------------deCrypting--------------------------
    BigInteger[] numberMessage = new BigInteger[stringMessage.length];

    for (int i = 0; i < numberMessage.length; i++) {
      numberMessage[i] = new BigInteger(stringMessage[i]); // message to BigInteger[]
    }
    s.append("Encrypted message: \n");
    s.append(msg);
    s.append("\n\nDecrypting: \n");
    for (int i = 0; i < numberMessage.length; i++) {
      CalculationPhase phase = new CalculationPhase(numberMessage[i], exp);
      s.append(phase.getAll(mod));
      s.append("\n\n");
    }
    s.append("Decrypted: \n");
    Integer[] integerMessage = new Integer[numberMessage.length];
    for (int i = 0; i < numberMessage.length; i++) {
      integerMessage[i] = (decrypter.decryptToInt(numberMessage[i], exp, mod));
      s.append(integerMessage[i] + " ");
    }

    // -----------------------deCoding-------------------------------
    s.append("\n\n" + alpha.getNumbers());
    s.append("\n\nDecoded text: ");
    String unCoded = (deCode(integerMessage));
    s.append(unCoded + "\n");
    return s.toString();
  }
  /**
   * Returns all phases of encoding and encrypting in a String
   *
   * @param msg String messge to be encrypted
   * @param exp BigInteger exponend
   * @param mod BigInteger modulo
   * @return String
   */
  public String getEnCrypted(String msg, BigInteger exp, BigInteger mod) {
    StringBuilder s = new StringBuilder();
    AlphabetNum alpha = new AlphabetNum();
    EncryptDecrypt encrypter = new EncryptDecrypt();

    // --------------------- enCoding-------------------------
    Integer[] numberMessage = enCode(msg);
    s.append(msg + "\n\n");
    s.append(alpha.getLetters() + "\n\n");
    s.append("Type 1 encoded text:\n");
    for (Integer integer : numberMessage) {
      s.append(integer.toString() + " ");
    }

    // ------------------------enCrypting-----------------------
    s.append("\n\nEncrypting:\n");
    for (int i = 0; i < numberMessage.length; i++) {
      CalculationPhase phase =
          new CalculationPhase(new BigInteger(numberMessage[i].toString()), exp);
      s.append(phase.getAll(mod));
      s.append("\n\n");
    }
    s.append("Encrypted: \n");
    BigInteger[] enCrypted = new BigInteger[numberMessage.length];
    String[] enCryptedLetters = new String[enCrypted.length];
    for (int i = 0; i < enCrypted.length; i++) {
      enCrypted[i] = (encrypter.encrypt(numberMessage[i], exp, mod));
      enCryptedLetters[i] = alpha.stringOfNumbersToLetters(enCrypted[i].toString());
      s.append(enCrypted[i] + " ");
    }

    // -------------------------to cryptotext----------------------
    s.append("\n\n" + alpha.getNumbers());
    s.append("\n\nCryptotext: \n");
    for (String string : enCryptedLetters) {
      s.append(string + " ");
    }
    return s.toString();
  }
  /**
   * Decrypts and decodes cryptotext to a plaintext.
   *
   * @param msg String
   * @param exp BigInteger
   * @param mod BigInteger
   * @return String
   */
  public String getDeCryptedSecure(String msg, BigInteger exp, BigInteger mod) {
    AlphabetNum alpha = new AlphabetNum();
    EncryptDecrypt decrypter = new EncryptDecrypt();

    // --------------------cryptotext to numbers------------------
    msg = alpha.stringOfLettersToNumbers(msg);
    String[] stringMessage = msg.split(" "); // Message in String[]

    // ----------------------deCrypting--------------------------
    BigInteger[] numberMessage = new BigInteger[stringMessage.length];
    for (int i = 0; i < numberMessage.length; i++) {
      numberMessage[i] = new BigInteger(stringMessage[i]); // message to BigInteger[]
    }
    Integer[] integerMessage = new Integer[numberMessage.length];
    for (int i = 0; i < numberMessage.length; i++) {
      integerMessage[i] = (decrypter.decryptToInt(numberMessage[i], exp, mod));
    }

    // -----------------------deCoding-------------------------------
    String deCoded = (deCode(integerMessage));
    return deCoded;
  }
  /**
   * Encodes and encrypts a message and returns cryptotext as a String.
   *
   * @param msg String messge to be encrypted
   * @param exp BigInteger exponend
   * @param mod BigInteger modulo
   * @return String
   */
  public String getEnCryptedSecure(String msg, BigInteger exp, BigInteger mod) {
    StringBuilder sB = new StringBuilder();
    AlphabetNum alpha = new AlphabetNum();
    EncryptDecrypt encrypter = new EncryptDecrypt();

    // --------------------- enCoding-------------------------
    Integer[] numberMessage = enCode(msg);

    // ------------------------enCrypting-----------------------
    BigInteger[] enCrypted = new BigInteger[numberMessage.length];
    String[] enCryptedLetters = new String[enCrypted.length];
    for (int i = 0; i < enCrypted.length; i++) {
      enCrypted[i] = (encrypter.encrypt(numberMessage[i], exp, mod));
      enCryptedLetters[i] = alpha.stringOfNumbersToLetters(enCrypted[i].toString());
    }

    // -------------------------to cryptotext----------------------
    for (String string : enCryptedLetters) {
      sB.append(string + " ");
    }
    return sB.toString().trim();
  }