package org.bouncycastle.openpgp;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;

import org.bouncycastle.bcpg.BCPGOutputStream;
import org.bouncycastle.bcpg.CompressionAlgorithmTags;
import org.bouncycastle.bcpg.PacketTags;

/**
 * Class for producing literal data packets.
 */
public class PGPLiteralDataGenerator 
	implements CompressionAlgorithmTags, PacketTags
{	
	private BCPGOutputStream			pkOut;
	
	public PGPLiteralDataGenerator()
	{		
	}
	
	/**
	 * Open a literal data packet, returning a stream to store the data inside
	 * the packet.
	 * 
	 * @param out the stream we want the packet in
	 * @param format the format we are using
	 * @param name the name of the "file"
	 * @param length the length of the data we will write
	 * @param modificationTime the time of last modification we want stored.
	 */
	public OutputStream open(
		OutputStream	out,
		char					format,
		String				name,
		long					length,
		Date					modificationTime)
		throws IOException
	{
		pkOut = new BCPGOutputStream(out, LITERAL_DATA, length + 2 + name.length() + 4);
		pkOut.write(format);
		pkOut.write((byte)name.length());

		for (int i = 0; i != name.length(); i++)
		{
			pkOut.write(name.charAt(i));
		}

		long	modDate = modificationTime.getTime() / 1000;

		pkOut.write((byte)(modDate >> 24));
		pkOut.write((byte)(modDate >> 16));
		pkOut.write((byte)(modDate >> 8));
		pkOut.write((byte)(modDate));

		return pkOut;
	}
	
	/**
	 * Open a literal data packet for the passed in File object, returning
	 * an output stream for saving the file contents.
	 * 
	 * @param out
	 * @param format
	 * @param file
	 * @return OutputStream
	 * @throws IOException
	 */
	public OutputStream open(
		OutputStream	out,
		char					format,
		File					file)
		throws IOException
	{
		String	name = file.getName();
		
		pkOut = new BCPGOutputStream(out, LITERAL_DATA, file.length() + 2 + name.length() + 4);
		pkOut.write(format);
		pkOut.write((byte)name.length());

		for (int i = 0; i != name.length(); i++)
		{
			pkOut.write(name.charAt(i));
		}

		long	modDate = file.lastModified() / 1000;

		pkOut.write((byte)(modDate >> 24));
		pkOut.write((byte)(modDate >> 16));
		pkOut.write((byte)(modDate >> 8));
		pkOut.write((byte)(modDate));

		return pkOut;
	}
	
	/**
	 * Close the literal data packet.
	 * 
	 * @throws IOException
	 */
	public void close()
		throws IOException
	{
		pkOut.flush();
	}
}
