import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;

/**
 * An encryptor encrypts files using the Caesar cipher.
 * For decryption, use an encryptor whose key is the 
 * negative of the encryption key.
 * @version 1.0
 */
public class Encryptor {

  private int mKey;

  /**
   * Constructs an encryptor.
   *  @param aKey the encryption key
   */
  public Encryptor(int aKey) {
    mKey = aKey;
  }
  
  /**
   * Encrypts the contents of a file.
   * @param inFile the input file
   * @param outFile the output file
   */
  public void encryptFile(File inFile, File outFile)
    throws IOException {
    InputStream in = null;
    OutputStream out = null;

    try {
      in = new BufferedInputStream(new FileInputStream(inFile));
      out = new BufferedOutputStream(new FileOutputStream(outFile));
      encryptStream(in, out);
    } finally {
      if (in != null) {
	in.close();
      }
      if (out != null) {
	out.flush();
	out.close();
      }
    }    
  }
  
  /**
   * Encrypts the contents of a stream.
   * @param in the input stream
   * @param out the output stream
   */      
  public void encryptStream(InputStream in, OutputStream out)
    throws IOException {
    boolean done = false;
    while (!done) {
      int next = in.read();
      if (next == -1) {
	done = true;
      } else {
	byte b = (byte)next;
	byte c = encrypt(b);
	out.write(c);
      }
    }
  }

  /**
   * Encrypts a byte.
   * @param b the byte to encrypt
   * @return the encrypted byte
   */
  public byte encrypt(byte b) {
    return (byte)(b + mKey);
  }
}
