package org.mime4j.samples.tree;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeSelectionModel;

import org.mime4j.field.AddressListField;
import org.mime4j.field.ContentTypeField;
import org.mime4j.field.DateTimeField;
import org.mime4j.field.Field;
import org.mime4j.field.UnstructuredField;
import org.mime4j.field.address.Mailbox;
import org.mime4j.field.address.MailboxList;
import org.mime4j.message.BinaryBody;
import org.mime4j.message.Body;
import org.mime4j.message.BodyPart;
import org.mime4j.message.Entity;
import org.mime4j.message.Header;
import org.mime4j.message.Message;
import org.mime4j.message.Multipart;
import org.mime4j.message.TextBody;

/**
 * Displays a parsed Message in a window. The window will be divided into
 * two panels. The left panel displays the Message tree. Clicking on a 
 * node in the tree shows information on that node in the right panel.
 *
 * Some of this code have been copied from the Java tutorial's JTree section.
 *
 * @author Niklas Therning
 * @version $Id$
 */
public class MessageTree extends JPanel implements TreeSelectionListener {
    private JPanel contentPane;
    private JTextArea textView;
    private JTree tree;

    /**
     * Wraps an Object and associates it with a text. All message parts 
     * (headers, bodies, multiparts, body parts) will be wrapped in
     * ObjectWrapper instances before they are added to the JTree instance.
     */
    public static class ObjectWrapper {
        private String text = "";
        private Object object = null;
        
        public ObjectWrapper(String text, Object object) {
            this.text = text;
            this.object = object;
        }
        
        public String toString() {
            return text;
        }
        
        public Object getObject() {
            return object;
        }
    }
    
    /**
     * Creates a new <code>MessageTree</code> instance displaying the 
     * specified <code>Message</code>.
     * 
     * @param message the message to display.
     */
    public MessageTree(Message message) {
        super(new GridLayout(1,0));

        DefaultMutableTreeNode root = createNode(message);

        tree = new JTree(root);
        tree.getSelectionModel().setSelectionMode(
                TreeSelectionModel.SINGLE_TREE_SELECTION);

        tree.addTreeSelectionListener(this);

        JScrollPane treeView = new JScrollPane(tree);

        contentPane = new JPanel(new GridLayout(1,0));
        JScrollPane contentView = new JScrollPane(contentPane);

        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
        splitPane.setLeftComponent(treeView);
        splitPane.setRightComponent(contentView);

        Dimension minimumSize = new Dimension(100, 50);
        contentView.setMinimumSize(minimumSize);
        treeView.setMinimumSize(minimumSize);
        splitPane.setDividerLocation(250);
        splitPane.setPreferredSize(new Dimension(750, 500));

        add(splitPane);
        
        textView = new JTextArea();
        textView.setEditable(false);
        textView.setLineWrap(true);
        contentPane.add(textView);
    }
    
    /**
     * Create a node given a Multipart body.
     * Add the Preamble, all Body parts and the Epilogue to the node.
     * 
     * @param multipart the Multipart.
     * @return the root node of the tree.
     */
    private DefaultMutableTreeNode createNode(Header header) {
        DefaultMutableTreeNode node = new DefaultMutableTreeNode(
                new ObjectWrapper("Header", header));

        for (Iterator it = header.getFields().iterator(); it.hasNext();) {
            Field field = (Field) it.next();
            String name = field.getName();
            
            node.add(new DefaultMutableTreeNode(new ObjectWrapper(name, field)));
        }        

        return node;
    }
    
    /**
     * Create a node given a Multipart body.
     * Add the Preamble, all Body parts and the Epilogue to the node.
     * 
     * @param multipart the Multipart.
     * @return the root node of the tree.
     */
    private DefaultMutableTreeNode createNode(Multipart multipart) {
        DefaultMutableTreeNode node = new DefaultMutableTreeNode(
                new ObjectWrapper("Multipart", multipart));

        node.add(new DefaultMutableTreeNode(
                       new ObjectWrapper("Preamble", multipart.getPreamble())));
        for (Iterator it = multipart.getBodyParts().iterator(); it.hasNext();) {
            BodyPart part = (BodyPart) it.next();
            node.add(createNode(part));
        }
        node.add(new DefaultMutableTreeNode(
                       new ObjectWrapper("Epilogue", multipart.getEpilogue())));

        return node;
    }
    
    /**
     * Creates the tree nodes given a MIME entity (either a Message or 
     * a BodyPart).
     * 
     * @param entity the entity.
     * @return the root node of the tree displaying the specified entity and 
     *         its children.
     */
    private DefaultMutableTreeNode createNode(Entity entity) {
        
        /*
         * Create the root node for the entity. It's either a
         * Message or a Body part.
         */
        String type = "Message";
        if (entity instanceof BodyPart) {
            type = "Body part";
        }
        DefaultMutableTreeNode node = new DefaultMutableTreeNode(
                                            new ObjectWrapper(type, entity));

        /*
         * Add the node encapsulating the entity Header.
         */
        node.add(createNode(entity.getHeader()));
        
        Body body = entity.getBody();
        
        if (body instanceof Multipart) {
            /*
             * The body of the entity is a Multipart.
             */
            
            node.add(createNode((Multipart) body));
        } else if (body instanceof Message) {
            /*
             * The body is another Message.
             */
            
            node.add(createNode((Message) body));
            
        } else {
            /*
             * Discrete Body (either of type TextBody or BinaryBody).
             */
            type = "Text body";
            if (body instanceof BinaryBody) {
                type = "Binary body";
            }
            
            type += " (" + entity.getMimeType() + ")";
            node.add(new DefaultMutableTreeNode(new ObjectWrapper(type, body)));
            
        }
        
        return node;
    }
    
    /**
     * Called whenever the selection changes in the JTree instance showing
     * the Message nodes.
     * 
     * @param e the event.
     */
    public void valueChanged(TreeSelectionEvent e) {
        DefaultMutableTreeNode node = (DefaultMutableTreeNode)
                tree.getLastSelectedPathComponent();

        textView.setText("");
        
        if (node == null) {
            return;
        }
        
        Object o = ((ObjectWrapper) node.getUserObject()).getObject();

        if (node.isLeaf()) {
            
            if (o instanceof TextBody){
                /*
                 * A text body. Display its contents.
                 */
                TextBody body = (TextBody) o;
                StringBuffer sb = new StringBuffer();
                try {
                    Reader r = body.getReader();
                    int c;
                    while ((c = r.read()) != -1) {
                        sb.append((char) c);
                    }
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                textView.setText(sb.toString());
                
            } else if (o instanceof BinaryBody){
                /*
                 * A binary body. Display its MIME type and length in bytes.
                 */
                BinaryBody body = (BinaryBody) o;
                int size = 0;
                try {
                    InputStream is = body.getInputStream();
                    int b;
                    while ((b = is.read()) != -1) {
                        size++;
                    }
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                textView.setText("Binary body\n"
                               + "MIME type: " 
                                   + body.getParent().getMimeType() + "\n" 
                               + "Size of decoded data: " + size + " bytes");
                
            } else if (o instanceof ContentTypeField) {
                /*
                 * Content-Type field.
                 */
                ContentTypeField field = (ContentTypeField) o;
                StringBuffer sb = new StringBuffer();
                sb.append("MIME type: " + field.getMimeType() + "\n");
                Map params = field.getParameters();
                for (Iterator it = params.keySet().iterator(); it.hasNext();) {
                    String name = (String) it.next();
                    sb.append(name + " = " + params.get(name) + "\n");
                }
                textView.setText(sb.toString());
                
            } else if (o instanceof AddressListField) {
                /*
                 * An address field (From, To, Cc, etc)
                 */
                AddressListField field = (AddressListField) o;
                MailboxList list = field.getAddressList().flatten();
                StringBuffer sb = new StringBuffer();
                for (int i = 0; i < list.size(); i++) {
                    Mailbox mb = list.get(i);
                    sb.append(mb.getAddressString() + "\n");
                }
                textView.setText(sb.toString());
                
            } else if (o instanceof DateTimeField) {
                Date date = ((DateTimeField) o).getDate();
                textView.setText(date.toString());                
            } else if (o instanceof UnstructuredField){
                textView.setText(((UnstructuredField) o).getValue());                
            } else if (o instanceof Field){
                textView.setText(((Field) o).getBody());                
            } else {
                /*
                 * The Object should be a Header or a String containing a 
                 * Preamble or Epilogue.
                 */
                textView.setText(o.toString());                
            }
            
        }
    }
    
    /**
     * Creates and displays the gui.
     * 
     * @param message the Message to display in the tree.
     */
    private static void createAndShowGUI(Message message) {
        /*
         * Create and set up the window.
         */
        JFrame frame = new JFrame("MessageTree");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        /*
         * Create and set up the content pane.
         */
        MessageTree newContentPane = new MessageTree(message);
        newContentPane.setOpaque(true);
        frame.setContentPane(newContentPane);

        /*
         * Display the window.
         */
        frame.pack();
        frame.setVisible(true);
    }
    
    public static void main(String[] args) {
        try {
            
            final Message message = new Message(new FileInputStream(args[0]));
            
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowGUI(message);
                }
            });
        
        } catch (ArrayIndexOutOfBoundsException e) {
            System.err.println("Wrong number of arguments.");
            System.err.println("Usage: org.mime4j.samples.tree.MessageTree"
                             + " path/to/message");
        } catch (FileNotFoundException e) {
            System.err.println("The file '" + args[0] + "' could not be found.");
        } catch (IOException e) {
            System.err.println("The file '" + args[0] + "' could not be read.");
        }
    }

}
