package nxm.ucl.lib;//remove for non-nxm use

/** This class is used for encoding given string passwords.
 *
 *  @author Jay Hallam
 *  @since NeXtMidas 2.1.0
 */
public class encoder {

  /** Password string */
  public static String strPass;

  private static final char [] alphabet = {
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',   //  0 to  7
    'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',   //  8 to 15
    'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',   // 16 to 23
    'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',   // 24 to 31
    'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',   // 32 to 39
    'o', 'p', 'q', 'r', 's', 't', 'u', 'v',   // 40 to 47
    'w', 'x', 'y', 'z', '0', '1', '2', '3',   // 48 to 55
    '4', '5', '6', '7', '8', '9', '+', '/' }; // 56 to 63

  /** default constructor */
  public encoder () {}

  /** Main driver method for running encoder as an instance
   *  @param args the string password
   */
  public static void main(String[] args) {
    try {
      strPass = new String(args[0]);

      System.out.println("original psw-"+strPass+"-");

      //String strEnc = encodeBase64 (strPass);
      encoder enc = new encoder();
      String strEnc = enc.encrypt(strPass);
      System.out.println("encpsw-"+strEnc+"-");
      strEnc = enc.decrypt(strEnc);

      System.out.println("original encpsw-"+strEnc+"-");
    } catch(Exception e) {
      System.out.println("Exception in main " + e);
      e.printStackTrace();
    }
  }

  /** Calls {@link #encodeBase64(String)} to return a Base64-encoded string
   *  @param s the string to be encoded
   *  @return the string after it has been encoded
   */
  public String encrypt(String s) {
    return encodeBase64 (s.getBytes());
  }

  /** Calls {@link Base64#base64Decode(String)} to return a Base64-decrypted string
   *  @param s the string to be decrypted
   *  @return the string after it has been decrypted
   */
  public String decrypt(String s) {
    return Base64.base64Decode (s);
  }

  /** Alternative method for encoding a string
   *  @param s the string to be encoded
   *  @return the string after it has been encoded
   */
  public String easyencrypt(String s) {
     int nCharPos = 0;
     int nLen=0;
     int nOrd=0;
     String strEnc="";
     byte[] sbytes = s.getBytes();
     nLen = sbytes.length;
     for (nCharPos = 0; nCharPos < nLen; nCharPos++) {
        byte bChar;
        char ch;
        bChar = sbytes[nCharPos];
        ch = s.charAt(nCharPos);
       // if (Character.isDigit(ch)) {
       //   System.out.println("got number");
       // }
        if (65 <= bChar && bChar <= 90) {
           bChar = (byte)(90 - (byte)(bChar - 65)) ;
           sbytes[nCharPos] = bChar;
           //System.out.println(s.charAt(nCharPos) + " translates to " + sbytes[nCharPos]);
        }else if(97 <= bChar && bChar <= 122) {
           bChar = (byte)(122 - (byte)(bChar - 97)) ;
           sbytes[nCharPos] = bChar;
           //System.out.println(s.charAt(nCharPos) + " translates to " + sbytes[nCharPos]);
        }
       // System.out.println(s.charAt(nCharPos) + " = "+bChar);

     } // end for
     strEnc = new String(sbytes);
     return strEnc;
  }

  /** Calls {@link #encodeBase64(byte[])} to return a Base64-encrypted string
   *  @param s the string to be encrypted
   *  @return the string after it has been encrypted
   */
  public String encodeBase64 (String s) {
    return encodeBase64 (s.getBytes());
  }

  /** convert byte array to a base64 encoded string.
      @param octetString byte array to base64 encode
      @return base64 encoded string of byte array
   */
  public String encodeBase64 (byte[] octetString) {
    int bits24, bits6;
    int outIndex = 0;
    int i        = 0;

    if (octetString==null) return null;
    char [ ] out = new char [ ( ( octetString.length - 1 ) / 3 + 1 ) * 4 ];

    try {
      while ( ( i + 3 ) <= octetString.length ) {
        // store the octets
        bits24  = ( octetString [ i++ ] & 0xFF ) << 16;
        bits24 |= ( octetString [ i++ ] & 0xFF ) <<  8;
        bits24 |= ( octetString [ i++ ] & 0xFF ) <<  0;

        bits6 = ( bits24 & 0x00FC0000 ) >> 18;
        out [ outIndex++ ] = alphabet [ bits6 ];
        bits6 = ( bits24 & 0x0003F000 ) >> 12;
        out [ outIndex++ ] = alphabet [ bits6 ];
        bits6 = ( bits24 & 0x00000FC0 ) >> 6;
        out [ outIndex++ ] = alphabet [ bits6 ];
        bits6 = ( bits24 & 0x0000003F );
        out [ outIndex++ ] = alphabet [ bits6 ];
      }

      if ( octetString.length - i == 2 ) {
        // store the octets
        bits24  = ( octetString [ i     ] & 0xFF ) << 16;
        bits24 |= ( octetString [ i + 1 ] & 0xFF ) <<  8;

        bits6 = ( bits24 & 0x00FC0000 ) >> 18;
        out [ outIndex++ ] = alphabet [ bits6 ];
        bits6 = ( bits24 & 0x0003F000 ) >> 12;
        out [ outIndex++ ] = alphabet [ bits6 ];
        bits6 = ( bits24 & 0x00000FC0 ) >> 6;
        out [ outIndex++ ] = alphabet [ bits6 ];

        // padding
        out [ outIndex++ ] = '=';
      } else if ( octetString.length - i == 1 ) {
       // store the octets
        bits24 = ( octetString [ i ] & 0xFF ) << 16;

        bits6 = ( bits24 & 0x00FC0000 ) >> 18;
        out [ outIndex++ ] = alphabet [ bits6 ];
        bits6 = ( bits24 & 0x0003F000 ) >> 12;
        out [ outIndex++ ] = alphabet [ bits6 ];

        // padding
        out [ outIndex++ ] = '=';
        out [ outIndex++ ] = '=';
      }
    } catch (Exception e) {
      System.out.println("Exception in encodebase64"+e);
      e.printStackTrace();
    }
    return new String ( out );
  }
}