/****************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one   *
 * or more contributor license agreements.  See the NOTICE file *
 * distributed with this work for additional information        *
 * regarding copyright ownership.  The ASF licenses this file   *
 * to you under the Apache License, Version 2.0 (the            *
 * "License"); you may not use this file except in compliance   *
 * with the License.  You may obtain a copy of the License at   *
 *                                                              *
 *   http://www.apache.org/licenses/LICENSE-2.0                 *
 *                                                              *
 * Unless required by applicable law or agreed to in writing,   *
 * software distributed under the License is distributed on an  *
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
 * KIND, either express or implied.  See the License for the    *
 * specific language governing permissions and limitations      *
 * under the License.                                           *
 ****************************************************************/

package org.apache.james.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.
 *
 * 
 * @version $Id: MessageTree.java 509117 2007-02-19 07:41:05Z norman $
 */
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.");
        }
    }

}
