package com.heynt.permutation.utils;

import java.util.List;
import java.util.Map;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.UnmodifiableListIterator;

public class Encrypt
{
    public String EncryptString(final String plaintext, Map<Character, List<Integer>> keymap)
    {
        // The ciphertext output
        StringBuilder cipherTextBuilder = new StringBuilder();

        // Walk the plaintext and encode each letter
        ImmutableList<Character> chars = Lists.charactersOf(plaintext);
        UnmodifiableListIterator<Character> iter = chars.listIterator();
        Integer messageIndex = 0;
        while (iter.hasNext())
        {
            Boolean isNewWord = true;
            Character letter = iter.next();
            
            if (letter == '\n') // end
            {
                break;
            }
            
            else if (letter == ' ') // space
            {
                cipherTextBuilder.append(' ');
                isNewWord = true;
            }
            else // We are continuing a word
            {
                if (!isNewWord)
                {
                    cipherTextBuilder.append(',');
                }
                // Get list of possible numbers from the map
                List<Integer> possibleValuesList = keymap.get(letter);

                // TODO Can extend listPicker to use a different picking algorithm for a value
                String key = schedulingAlgorithm(messageIndex, possibleValuesList);

                // key values less than 10 need a zero prepended (for example, 7 becomes 07)
                if (Integer.valueOf(key) < 10)
                {
                    key = '0' + key;
                }
                cipherTextBuilder.append(key);
            }
            isNewWord = false;
            ++messageIndex;
        }

        return cipherTextBuilder.toString();
    }
    
    /**
     * This method defines how the encryption algorithm picks a ciphertext from a list of possible values
     * 
     */
    private String schedulingAlgorithm(Integer messageIndex, List<Integer> possibleValuesList)
    {
        // TODO Extend this so that different picking algorithms can be used

        // “j mod length(list)” where j = index in the plaintext message
        Integer j = messageIndex;
        Integer lengthList = possibleValuesList.size();
        return possibleValuesList.get( j % lengthList ).toString();
    }

}

@@ -75,16 +75,49 @@
 til.Map;
+%0Aimport java.util.logging.Logger;
 %0A%0Aimport
@@ -281,16 +281,101 @@
 crypt%0A%7B%0A
+    private static final Logger LOGGER = Logger.getLogger(Encrypt.class.getName());%0A%0A
     publ
@@ -765,148 +765,538 @@
 ();%0A
-        Integer messageIndex = 0;%0A        while (iter.hasNext())%0A        %7B%0A            Boolean isNewWord = true;%0A            Character lette
+%0A        if (chars.get(0) == ' ')%0A        %7B%0A            LOGGER.warning(%22Cant start the plaintext message with a space. Exiting.%22);%0A            System.exit(1);%0A        %7D%0A%0A        /* keeps track of the index into the entire message */%0A        Integer messageIndex = 0;%0A        while (iter.hasNext())%0A        %7B%0A            Character prevChar = new Character(' ');%0A            if (iter.hasPrevious())%0A            %7B%0A                prevChar = iter.previous();%0A                iter.next();%0A            %7D%0A            Character currentCha
 r = 
@@ -1308,28 +1308,16 @@
 next();%0A
-            
 %0A       
@@ -1321,29 +1321,34 @@
         if (
-lette
+currentCha
 r == '%5Cn') /
@@ -1420,35 +1420,27 @@
     
-%0A            else if (lette
+else if (currentCha
 r ==
@@ -1519,42 +1519,8 @@
 ');%0A
-                isNewWord = true;%0A
     
@@ -1608,22 +1608,126 @@
     
-if (!isNewWord
+// Suppress printing an extra comma at very beginning or start of a new word%0A                if (!prevChar.equals(' ')
 )%0A  
@@ -1934,21 +1934,26 @@
 map.get(
-lette
+currentCha
 r);%0A%0A   
@@ -2407,39 +2407,8 @@
   %7D%0A
-            isNewWord = false;%0A
     

fix bug where we put too many commas in the ciphertext