/*
 */
import lotus.domino.*;	// Notes stuff
import java.util.*;			// what's your Vector, Victor?
import java.io.*;				// we're working with files here
import net.freeutils.tnef.*;	// TNEF decoder ( http://www.freeutils.net/source/jtnef )
import javax.swing.*;		// messagebox to the user at the end
// these are necessary for the optional getMimeMessage method
import net.freeutils.tnef.mime.*;
import javax.activation.*;
import javax.mail.internet.*;


/**
 * This is a Lotus Notes agent to be placed in mail files and run against selected 
 * docs that were sent from Outlook/Exchange and have all of their attachments and
 * rich text wrapped up in an unreadable Winmail.dat or ATT####.dat file.
 * 
 * It extracts the attachments embedded in the winmail.dat  or ATT0001.dat (or other 
 * TNEF-formatted files), puts them in a folder, and attaches them to a new message
 * in the inbox of your mail file. This uses the open-source JTNEF decoder library,
 * available at http://www.freeutils.net/source/jtnef . You will need to include that jar
 * file in the agent that contains this code, by using the "Edit Project" button at the
 * bottom of the agent window. Here's how to set everything up:
 * 
 * 1.  Go to http://www.freeutils.net/source/jtnef and download the jtnef library
 * 2.  Unzip the file on your computer
 * 3.  Open your Notes mail file in Domino Designer
 * 4.  Go to the Agents section and create a new Java agent
 * 5.  At the bottom of the agent screen, click "Edit Project" and browse to the "lib" 
 *     directory of the jtnef file you downloaded and unzipped
 * 6.  Click the "Add/Replace All" button to include the jar file with your project 
 *     (if you don't see it, you either don't have the "archive" file type checked, or
 *     you're in the wrong directory)
 * 7.  Click OK and go back to the agent
 * 8.  Delete all the code that's there, and copy and paste the contents of this file
 * 9.  Call the agent something meaningful, and make sure it's set to run against "all 
 *     selected docs"
 * 10.  Save and close
 * 11.  Go to your inbox in the regular Notes client
 * 12.  Select one or more messages that have that stupid winmail.dat or att0001.dat 
 *      file in them
 * 13.  Run your new agent
 * 14.  See if anything happens
 *
 * This agent is designed to operate against all selected docs in a view or folder of
 * your Lotus Notes e-mail database. It will check each doc, and scan all the 
 * attachments in the Body field, and any attachments that are valid TNEF files will 
 * have their contents exported to the location specified in the extractPath variable.
 * The extracted/converted files will then be attached to a new copy of the original
 * e-mail message, which will be copied to your Inbox folder.
 * 
 * I've only tested this with Notes 6.51. The JTNEF code uses javax.mail classes (which
 * are included with Notes 6 by default), and I added a Swing messagebox, so I'm
 * not sure if this code will work in R5 or not. If not, you could always remove the
 * messagebox and try to include an old version of javax.mail (if there is one that's
 * compatible with jre 1.1.8), and give it a go.
 * 
 * If you find this agent useful, you should consider making a donation to Amichai 
 * Rothman, the author of the JTNEF library, at http://www.freeutils.net . Without all the
 * work he did writing that code and making it freely available, none of this would
 * be possible. It's also worth noting that the JTNEF library has been released under
 * the GNU General Public License agreement, and you should read the license that
 * is linked to on the freeutils site if you plan to distribute or modify this code.
 * 
 * The only change to this code from 1.0 to 1.1 was the addition of the line:
 *   eo.recycle();
 * to ensure that the temporary file that gets created when you get the EmbeddedObject
 * attachment as an InputStream is deleted when you're done with it. Otherwise, you can
 * end up with a bunch of eo###tm files in your Notes program directory.
 * 
 * version 1.2
 * December 12, 2004
 * Julian Robichaux -- http://www.nsftools.com
 */

public class JavaAgent extends AgentBase {
	// set the debug level to 1 or 2 for additional output from this agent
	private final int DEBUG_LEVEL = 0;
	
	public void NotesMain() {

		try {
			// we'll be telling the user what happens with a Swing dialog box below,
			// so let's go ahead and set the look and feel to be the system default
			String nativeLF = UIManager.getSystemLookAndFeelClassName();
			try { UIManager.setLookAndFeel(nativeLF); } catch (Exception uie) { }
			
			// grab the selected documents
			Session session = getSession();
			AgentContext agentContext = session.getAgentContext();
			Database db = agentContext.getCurrentDatabase();
			DocumentCollection dc = agentContext.getUnprocessedDocuments();
			Document doc = dc.getFirstDocument();
			String message = "";
			
			while (doc != null) {
				// set some of the variable defaults
				String subject = doc.getItemValueString("Subject");
				Vector fileList = new Vector();
				int count = 0;
				
				// per Wayne Hoar's suggestion (http://www.vulcangroup.com), 
				// make sure that the Subject line isn't null
				if (subject == null)
					subject = "No Subject";
				
				// create a nice directory name to store the extracted files to
				String dirSubject = subject;
				char[] badDirChars = (new String("\\/?:|*\"<>")).toCharArray();
				for (int i = 0; i < badDirChars.length; i++)
					dirSubject = dirSubject.replace(badDirChars[i], '_');
				if (dirSubject.length() > 30)
					dirSubject = dirSubject.substring(0, 30) + "...";
				String extractPath = "C:\\TNEF Files\\" + doc.getNoteID() + " (" + dirSubject + ")\\";
				File extractDir = new File(extractPath);
				
				// grab the Body field of the current document, and check each attachment
				RichTextItem body = (RichTextItem)doc.getFirstItem("Body");
				Vector v = body.getEmbeddedObjects();
				Enumeration e = v.elements();
				while (e.hasMoreElements()) {
					EmbeddedObject eo = (EmbeddedObject)e.nextElement();
					if (eo.getType() == EmbeddedObject.EMBED_ATTACHMENT) {
						// make sure the extractPath directory exists
						extractDir.mkdirs();
						String errorMsg = "";
						
						try {
							// try to convert the file to a TNEF stream (if the file is not a valid
							// TNEF file, we'll end up in the catch block). The TNEF.extractContent
							// method will send all the attachments in the TNEF file to our 
							// extractPath
							TNEFInputStream in = new TNEFInputStream(eo.getInputStream());
							Message tnefMsg = new Message(in);
							fileList = extractContentCustom(tnefMsg, extractPath, count);
							
							// if we're debugging, also output some information about the tnef file
							if (DEBUG_LEVEL > 0) {
								String debugFileName = extractPath + eo.getName() + ".info.doc";
								FileWriter out = new FileWriter(debugFileName);
								out.write(tnefMsg.toString());
								fileList.add(debugFileName);
							}
							
							// if we're debugging, see what the MIME message would have translated into
							if (DEBUG_LEVEL > 1) {
								String mimeFile = getMimeMessage(tnefMsg, extractPath, fileList.size());
								if (mimeFile.length() > 0)
									fileList.add(mimeFile);
							}
							
							count += fileList.size();
							in.close();
							eo.recycle();
						} catch (Exception tne) {
							System.err.println("Error processing " + eo.getName());
							tne.printStackTrace();
							errorMsg = tne.getMessage();
						}
					}
				}
				
				// if we ended up extracting any files, we'll forward the e-mail back to ourselves
				// with the extracted files attached
				if (count > 0) {
					try {
						// create a new copy of the original e-mail
						Document copyDoc = db.createDocument();
						doc.copyAllItems(copyDoc, true);
						
						// attach the converted files to the end
						RichTextItem bodyCopy = (RichTextItem)copyDoc.getFirstItem("Body");
						bodyCopy.addNewLine(2);
						bodyCopy.appendText("===============================================");
						bodyCopy.addNewLine(2);
						bodyCopy.appendText("Here are the files that were extracted from the *.dat attachments");
						bodyCopy.addNewLine(2);
						String[] files = extractDir.list();
						for (int i = 0; i < files.length; i++) {
							bodyCopy.embedObject(EmbeddedObject.EMBED_ATTACHMENT, null, 
														extractPath + files[i], null);
						}
						
						// and try to add the new doc to the Inbox folder
						//doc.send(session.getUserName());
						copyDoc.replaceItemValue("Subject", "(Converted) " + subject);
						copyDoc.save();
						copyDoc.putInFolder("($Inbox)");
						copyDoc.recycle();
						message += "\nCopied message '" + subject + 
								"' to your Inbox, with converted files attached\n";
						
					} catch (Exception se) {
						message += "\nError copying converted message: " + se + "\n";
					}
					
					// optionally delete the directory with all the files in it when we're done
					if (DEBUG_LEVEL == 0)
						deleteDir(extractDir);
				} else {
					// if we didn't end up extracting anything, delete the extractPath that
					// may have been created
					deleteDir(extractDir);
					message += "\nNo valid TNEF attachments found in message '" + subject + "'\n";
				}
				
				// next doc, please
				Document nextDoc = dc.getNextDocument();
				doc.recycle();
				doc = nextDoc;
			}
			
			// tell the user what we did when we're all done
			if (message.length() == 0)
				message = "No files were processed";
			JOptionPane.showMessageDialog(null, message);
			
		} catch(Exception e) {
			// oops, this can't be good...
			e.printStackTrace();
			try {
				JOptionPane.showMessageDialog(null, e.getMessage());
			} catch (Exception msge) {
			}
		}
	}
	
	
	public static boolean deleteDir(File dir) {
		// delete a directory and any files or subdirectories beneath it
		// from http://javaalmanac.com/egs/java.io/DeleteDir.html
		if (dir.isDirectory()) {
			String[] children = dir.list();
			for (int i=0; i