/*
 * @(#)MetalworksInBox.java	1.3 99/04/06
 *
 * Copyright 1998 by Team Noriega: Noah Green, John Weber, and Michael Ahern
 *       
 * All rights reserved.
 *
 * This software is the confidential and proprietary information
 * of Team Noriega ("Confidential Information").  You
 * shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement
 * you entered into with Team Noriega.
 */
package noriega.expresso.client;
import java.awt.*;
import java.awt.event.*;
import java.util.Set;
import java.util.HashMap;
import java.util.*;
import javax.swing.JTree;
import javax.swing.JLabel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.event.TreeSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.tree.TreeSelectionModel;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.ListSelectionEvent;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.tree.*;
import javax.swing.event.*;
import javax.swing.JLabel;
import javax.swing.JCheckBox;
import javax.swing.JScrollPane;

import noriega.expresso.structures.Mailbox;

import java.net.*;
import java.rmi.*;
import noriega.expresso.protocols.*;
import noriega.expresso.server.*;
import noriega.expresso.structures.BinaryFlag;
import noriega.expresso.structures.*;
import noriega.util.*;


/**
 * This is a subclass of JInternalFrame which displays a tree.
 *
 * @version 1.3 04/07/99
 * @author Team Noriega
 */
public class MetalworksInBox extends JInternalFrame
				     implements TreeSelectionListener, 
								ListSelectionListener,
								TableModelListener {
    Date d = new Date();
    //FROM THE TESTCLIENT.JAVA FILE
    //*****************************
    ExpressoServer es;
    ServiceDirectory sd;
    IMAPService imap;
    SmtpService smtp;
    FlagService flags;
    //*****************************
    
    private boolean ALLOW_COLUMN_SELECTION = false;
    private boolean ALLOW_ROW_SELECTION = true;

    private JSplitPane splitPane;
    private JTree tree;
	private JPanel mailBoxPanel;
    DefaultMutableTreeNode top;
    JLabel label;
    String urg = "U";
    String resp = "R";
    JLabel defaultlabel;
	public JTable theTable;
	private JTextArea textarea;
	private Color bkgd = new Color(53);
	private Color bkgd1 = new Color(153);
	private Color bkgd2 = new Color(253);
	private final int height = 400;
	private final int width = 600;
	MyTableModel model; 
	private StringBuffer CURRENT_MAIL_BOX = null;
	
    
    private Object[][] data123 = {
	{"Mary.Campione@sun.com", 
	 "Snowboarding", d, new JCheckBox(urg, false), new JCheckBox(resp, false)},
	{"Alison.Huml@sun.com", 
	 "Rowing", d, new JCheckBox(urg, true), new JCheckBox(resp, false)},
	{"Kathy.Walrath@sun.com",
	 "Chasing toddlers", d, new JCheckBox(urg, false), new JCheckBox(resp, false)},
	{"Mark.Andrews@sun.com",
	 "Speed reading", d, new JCheckBox(urg, true), new JCheckBox(resp, false)},
	{"Angela.Lih@sun.com",
	 "Teaching high school", d, new JCheckBox(urg, false), new JCheckBox(resp, false)}
    };
    
    private String[] columnNames = {"From", 
				    "Subject",
				    "Received",
				    "Urgent",
				    "Responded"};
    
    
    public MetalworksInBox(MetalworksFrame parent,
						   ExpressoServer es,
						   ServiceDirectory sd,
						   IMAPService imap,
						   SmtpService smtp,
						   FlagService flags) {

	super("Expresso Mailboxes", true, true, true, true);

	System.err.println("Constructor start");
	// -----------------------------------------------
	// ----------- Get the server values, etc --------
	// -----------------------------------------------
	this.es = es;
	this.sd = sd;
	this.imap = imap;
	this.smtp = smtp;
	this.flags = flags;
	
	//-----------------------------------------------
	//----------- This is the main panel for the ----
	//----------- entire JInternal Frame ------------
	//----- Other panels are added to this panel ----
	//-----------------------------------------------
	System.err.println("Panel construction");
	mailBoxPanel = new JPanel();
	mailBoxPanel.setBorder(new BevelBorder(1));
	mailBoxPanel.setDoubleBuffered(true);
	mailBoxPanel.setLayout(new BorderLayout());
	mailBoxPanel.setMinimumSize(new Dimension(width, height));
	mailBoxPanel.add(buildMessagePane(), BorderLayout.CENTER);
	mailBoxPanel.add(buildTreePanel(), BorderLayout.WEST);
	System.err.println("Panel finished");
	setContentPane(mailBoxPanel);
	setSize(600, 450);
	setLocation( 75, 75 );
    CURRENT_MAIL_BOX = new StringBuffer("  ");
	System.err.println("Constructor finish");

    }
	
	private JPanel buildMessagePane() {
		//------------------------------------------------
		//--------- Create the Message Panel -------------
		//--------- With default empty panels -----------
		//------------------------------------------------
	
		JPanel messagePane = new JPanel(new GridLayout(2,1, 5,5 ));
		messagePane.setMinimumSize(new Dimension((int) (width*.66), height - 15));
		messagePane.add( buildMessageTable() );
		messagePane.add( buildtextAreaPanel() );
		return messagePane;			
	}
	
	private JScrollPane buildMessageTable() {
		
	    JScrollPane messageTable = null;
	    
	    try {
		
		model = new MyTableModel(es, sd, imap, smtp, flags);
		theTable = new JTable(model);
		model.addTableModelListener(theTable);
		
		theTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		    if (ALLOW_ROW_SELECTION) { // true by default
		        ListSelectionModel rowSM = theTable.getSelectionModel();
		        rowSM.addListSelectionListener(this); 
		    } else {
		        theTable.setRowSelectionAllowed(false);
		    }
			
		messageTable = new JScrollPane(theTable, 
							   JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, 
							   JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED );
		messageTable.setBorder(new TitledBorder("Select a Message"));
		messageTable.setMinimumSize( new Dimension((int) (width*.66), height/2 - 15) );
		messageTable.setSize(new Dimension((int) (width*.66), height/2 - 15));
		
	    } catch (Exception e) {
		System.err.println("model building: " + e.getMessage());
		e.printStackTrace();
		
	    }
	    
	    
		return messageTable;
	}
	
	public JScrollPane buildtextAreaPanel() {
		textarea = new JTextArea( 15, 30 );
		textarea.setLineWrap(true);
		textarea.setEditable(false);
		textarea.setBorder(new EmptyBorder(0, 5, 0 ,5));
		textarea.setText("No message currently selected");
											  
		JScrollPane textScroller = new JScrollPane(textarea, 
							   JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, 
							   JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED );
		textScroller.setBorder(new TitledBorder("Message Body"));
		textScroller.setSize(new Dimension((int) (width*.66), height/2 - 15));
		textScroller.setBackground(bkgd2);
	
		return textScroller;
	}
	
	public JScrollPane buildTreePanel() {
		//------------------------------------------------
		//--------- Get the List of MailBoxes ------------
		//------------------------------------------------
		top = this.getMailBoxes();
		System.err.println("Got mailboxes3");
	
		//------------------------------------------------
		//--------- Create the Tree ----------------------
		//------------------------------------------------
		tree = new JTree(top);
		tree.getSelectionModel().setSelectionMode
		    (TreeSelectionModel.SINGLE_TREE_SELECTION);
		//Listen for when the selection changes.
		System.err.println("Got mailboxes4");
		tree.addTreeSelectionListener(this);
		System.err.println("Got mailboxes5");

		JScrollPane treeScroller = new JScrollPane(tree);
		treeScroller.setBackground(tree.getBackground());
		treeScroller.setMinimumSize(new Dimension(width/2 - 10, height - 15));
		treeScroller.setSize(new Dimension((int) (width*.33), height - 15));
		treeScroller.setBorder(new TitledBorder("Available Mailboxes"));
		System.err.println("Got mailboxes6");
	
		return treeScroller;
	}
	
    public DefaultMutableTreeNode getMailBoxes() {
	
	DefaultMutableTreeNode t;	
	
	DefaultMutableTreeNode in;
	DefaultMutableTreeNode out;
	DefaultMutableTreeNode trash;
	
	t = new DefaultMutableTreeNode("Mail Boxes");
	
	
	DefaultMutableTreeNode newnode = null;
	try {
		
	    Set s = imap.listMailboxes();
	    for(Iterator i = s.iterator(); i.hasNext(); ) {
		String mb = (String) i.next();
		t.add( new DefaultMutableTreeNode(new String(mb) ) );
	    }
	    
	} catch (Exception e) {
		e.printStackTrace();

		System.err.println("Adding Default Empty Mailboxes: " + e.getMessage());
		
		t.add( new DefaultMutableTreeNode("Inbox") );
		t.add( new DefaultMutableTreeNode("Outbox") );
		t.add( new DefaultMutableTreeNode("Trashbox     ") );
		
	}
	    return t;
    }
    
    
    /** This is for debug purposes only
     */
    public JTable addTestMessages(String mb) {
	
	JTable jt = new JTable(data123, columnNames);
	return jt;
	
    }
    
    /*
    public JTable getMessageTable(String mb) {
	
	Vector headersV = new Vector();
	Vector columnNames = new Vector();
	Object[][] rowdata = null;
	
	
	try {
	    
	    imap.selectMailbox(mb);
	    
	    Set h = imap.fetchHeaders();
	    // ---------------------------------
	    // -------- Get Column Names -------
            // ---------------------------------
	    Iterator i = h.iterator();
	    Header header = (Header) i.next();
		
	    columnNames.addElement(header.getFrom().toString() );
	    columnNames.addElement(header.getTo().toString() );
	    columnNames.addElement(header.getSubject().toString() );
	    columnNames.addElement(header.getDate().toString() );
	    columnNames.addElement("Read");
	    columnNames.addElement("New");
	    String[] flagsString = flags.getFlagNames();
	    
	    int x = 0;
	    while(flagsString[x] != null)
		columnNames.addElement(flagsString[x++]);

	    // ---------------------------------
	    // -------- Get Row Data -----------
        // ---------------------------------
	    
	    
	    
	    rowdata = new Object[imap.queryMailbox(mb,"Size")][columnNames.size()];
	    
		
            int a = 0;
	    for(Iterator ii = h.iterator(); ii.hasNext(); a++) {
		Header head = (Header) ii.next();
		
		  rowdata[a][0] = head.getFrom();
		  rowdata[a][1] = head.getTo();
		  rowdata[a][2] = head.getDate();
		  rowdata[a][3] = head.getSubject();
		  rowdata[a][4] = new Boolean(imap.queryMessage(head, ExpressoConstants.ISNEW_NAME)); 
		  rowdata[a][5] = new Boolean(imap.queryMessage(head, ExpressoConstants.ISREAD_NAME));
		  for(int xy = 6; xy < x + 6; xy++)
		      rowdata[a][xy] = new Boolean (imap.queryMessage(head, flagsString[xy]));

	    }
	} catch (RemoteException e) { 
	
	} catch (Exception e) {
	    
	}
	


	//TODO: get the columnNames and put in vectors
	String[] colNames = new String[columnNames.size()];
	columnNames.copyInto(colNames);
	JTable mbtable = new JTable(rowdata, colNames);
	
	mbtable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
           
	ListSelectionModel rowSM = mbtable.getSelectionModel();
	rowSM.addListSelectionListener(new ListSelectionListener() {
	    public void valueChanged(ListSelectionEvent e) {
		ListSelectionModel lsm = (ListSelectionModel)e.getSource();
		if (lsm.isSelectionEmpty()) {
		    //no rows are selected
		} else {
		    int selectedRow = lsm.getMinSelectionIndex();
		   
		    //selectedRow is selected
			}
	    }
	});
	
	return mbtable;
	
	
    }
	*/

	public void valueChanged(TreeSelectionEvent e) {
		DefaultMutableTreeNode node = (DefaultMutableTreeNode)
			      tree.getLastSelectedPathComponent();
		  
		if (node == null) return;
		  
		Object nodeInfo = node.getUserObject();
		if (node.isLeaf()) {
		    final String box = (String)nodeInfo;
		    System.err.println("Selected node: " + box);
			SwingWorker worker = new SwingWorker() {
			    public Object construct() {
				return updateTable(box) ;}
			}; // end SwingWorker			
			worker.get();
		    //displayURL(box.bookURL);
		} else {
		    //displayURL(helpURL); 
		}
	    
	}
	
	private Boolean updateTable(String box) {
	    /*
		if (box.equals(CURRENT_MAIL_BOX))
			return new Boolean(true);
		else 
	    */
	    DEBUG.debug ("called updateTable");
	    CURRENT_MAIL_BOX = new StringBuffer(box);
	
	    try {
		DEBUG.debug ("1");
			model.clear();
			DEBUG.debug ("2: " + box);
			imap.selectMailbox(box);
			DEBUG.debug ("3");
			if (imap == null) {DEBUG.debug ("IMAPNULL");}
			Set headersSet = (Set) imap.fetchHeaders();
			DEBUG.debug ("WE GOT: " + headersSet);
			model.setData(headersSet);
			DEBUG.debug ("4");
			//theTable.clearSelection();
		} catch (RemoteException e) {
		    e.printStackTrace();
			remoteExceptionDialog(e);
		} catch (ExpressoServerException e) {
		    e.printStackTrace();
			remoteExceptionDialog(e);
		} 
	    catch (Exception e) {
		e.printStackTrace();
		remoteExceptionDialog (e);
	    } 
	        finally {
			mailBoxPanel.repaint();
			return new Boolean(true);	
		}
	}
	
	public void valueChanged(ListSelectionEvent e) {
        ListSelectionModel lsm = (ListSelectionModel)e.getSource();
        if (lsm.isSelectionEmpty()) {
            System.out.println("No rows are selected.");
        } else {
            final int selectedRow = lsm.getMinSelectionIndex();
            System.out.println("Row " + selectedRow
                               + " is now selected.");
			SwingWorker worker = new SwingWorker() {			
				public Object construct() {
				return updateTextArea(selectedRow) ;}
			}; // end SwingWorker			
			worker.get();
        }
    }
	
	private Boolean updateTextArea(int row) {
		 textarea.setText("Selected row: " + row);
		 mailBoxPanel.repaint();
		 return new Boolean(true);
	}
    
	public void tableChanged(TableModelEvent e) {
		int row = e.getFirstRow();        
		int column = e.getColumn();
       // String columnName = model.getColumnName(column);
        //Object data = model.getValueAt(row, column);
        // Do something with the data
	}
	
	public void remoteExceptionDialog(Exception e) {
		System.err.println("Email error: " + e.getMessage());
		JOptionPane.showMessageDialog(
			  MetalworksInBox.this,
			  MetalworksFrame.REMOTEEXCP + "\n\n" + e.getMessage(),	
			  "RMI Exception",
			  JOptionPane.ERROR_MESSAGE);
	}
}








