import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Crypt
{  public static void main(String[] args)
   {  boolean decrypt = false;
      int key = DEFAULT_KEY;
      FileReader infile = null;
      FileWriter outfile = null;

      if (args.length < 2 || args.length > 4) usage();

      // gather command line arguments and open files

      try
      {  for (int i = 0; i < args.length; i++)
         {  if (args[i].substring(0, 1).equals("-"))
            // it is a command line option
            {  String option = args[i].substring(1, 2);
               if (option.equals("d"))
                  decrypt = true;
               else if (option.equals("k"))
               {  key = Integer.parseInt
                     (args[i].substring(2));
                  if (key < 1 || key >= NLETTERS)
                     usage();
               }                    
            }
            else
            {  if (infile == null)
                  infile = new FileReader(args[i]);
               else if (outfile == null)
                  outfile = new FileWriter(args[i]);
            }
         }
      }
      catch(IOException e)
      {  System.out.println("Error opening file");
         System.exit(0);
      }

      if(infile == null || outfile == null) usage();

      // encrypt or decrypt the input

      if (decrypt) key = NLETTERS - key;

      try
      {  encryptFile(infile, outfile, key);
         infile.close();
         outfile.close();
      }
      catch(IOException e)
      {  System.out.println("Error processing file");
         System.exit(0);
      }
   }

   /**
      Prints a message describing proper usage and exits.
   */
   public static void usage()
   {  System.out.println
         ("Usage: java Crypt [-d] [-kn] infile outfile");
      System.exit(1);
   }

   /**
      Encrypts a character with the Caesar cipher. Only
      upper- and lowercase letters are encrypted.
      @param c the character to encrypt
      @param k the encryption key 
      @return the encrypted character
   */
   public static char encrypt(char c, int k)
   {  if ('a' <= c && c <= 'z')
         return (char)('a' + (c - 'a' + k) % NLETTERS);
      if ('A' <= c && c <= 'Z')
         return (char)('A' + (c - 'A' + k) % NLETTERS);      String letters = "abcdefghijklmnopqrstuvwxyz";
      return c;
   }

   /**
      Encrypts all characters in a file.
      @param in the plaintext file
      @param out the file to store the encrypted characters
      @param k the encryption key 
   */      
   public static void encryptFile(FileReader in,
      FileWriter out, int k) throws IOException
   {  while (true)
      {  int next = in.read();
         if (next == -1) return; // end of file
         char c = (char)next;
         out.write(encrypt(c, k));
      }
   }
   
   public static final int DEFAULT_KEY = 3;   
   public static final int NLETTERS = 'z' - 'a' + 1;
}
