package rpicq;

import javax.swing.*;
import java.awt.*;
import javax.swing.border.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.util.EventListener;

/**
 * This class encompasses the GUI side of a conversation between 2 people.
 * Any message listener added will be notified every time the local user
 * enters something in the bottom half of the window.
 * To post a message that comes from the remote user, use the gotMessage()
 * method.
 *
 * @author JJ Johns
 * @version 1
 **/

public class MessageSplitFrame extends JFrame implements MessageListener {

    private JTextArea mTopHalf;
    private JTextArea mBottomHalf;
    private String mOtherName;
    private String mMyName;

    private final Font italicFont = new Font("Helvetica", Font.ITALIC, 12 );
    private final Font normalFont = new Font("Helvetica", Font.PLAIN, 12 );  
    
    private EventListenerList mListenerList = new EventListenerList();

    private UIEventListener mUIEventListener;
    
    /**
     * This method should be called to add a message listener to the frame.
     * This listener will recieve messages that the local user types
     * into the frame.
     **/
    
    public void addMessageListener(MessageListener inListener) {
	mListenerList.add( MessageListener.class, inListener );
    }

    /**
     * This should be called to remove any added message listeners.
     **/
    public void removeMessageListener(MessageListener inListener) {
	try {
	    mListenerList.remove( MessageListener.class, inListener );
	} catch (Exception e) { }
    }

    /**
     * Since this frame is a MessageListener, it needs this method.
     * Any messages sent to this method will be posted in the current frame,
     * and they will be shown as coming from the remote user.
     **/
    
    public void gotMessage(MessageEvent inEvent) {
	addRemoteMessage(inEvent.getText());
    }

    /**
     * This is the constructor used to start a new conversation with
     * someone.
     */
    
    public MessageSplitFrame(String myName, String otherName,
			     UIEventListener inEL) {
	super("Conversation with " + otherName);
	mOtherName = otherName;
	mMyName = myName;
	mUIEventListener = inEL;
	
	createUI();
    }

    private void createUI() {
	this.getContentPane().setLayout( new BorderLayout(10,20) );
	
	mTopHalf = new JTextArea(10,40);
	mTopHalf.setEditable(false);
	JPanel topPanel = new JPanel(new GridLayout(1,1));
	topPanel.add( new JScrollPane(mTopHalf) );
	topPanel.setBorder( new TitledBorder( new EtchedBorder(),
					      "Conversation",
					      TitledBorder.LEFT,
					      TitledBorder.TOP));

	mBottomHalf = new JTextArea(10,40);
	JPanel bottomPanel = new JPanel(new GridLayout(1,1));
	bottomPanel.add( new JScrollPane(mBottomHalf) );
	bottomPanel.setBorder( new TitledBorder( new EtchedBorder(),
						 "Message to Send",
						 TitledBorder.LEFT,
						 TitledBorder.TOP));

	
	this.getContentPane().add( topPanel, BorderLayout.NORTH );
	this.getContentPane().add( bottomPanel, BorderLayout.CENTER );	

	JPanel buttons = new JPanel(new FlowLayout());

	JButton send = new JButton("Send");
	JButton quit = new JButton("Quit");

	send.addActionListener( new ActionListener() {
		public void actionPerformed(ActionEvent e) {
		    if (mBottomHalf.getText().equals(""))
			return;
		    addLocalMessage( mBottomHalf.getText() );
		    fireNewMessage( mBottomHalf.getText() );
		    mBottomHalf.setText("");
		}
	    });

	quit.addActionListener( new ActionListener() {
		public void actionPerformed(ActionEvent e) {
		    if (mUIEventListener != null)
			mUIEventListener
			    .endConversation(mMyName,
					     mOtherName,
					     MessageSplitFrame.this );
		    else
			System.err.println("UI WARNING: UIEventListener "+
					   "is null in MessageSplitFrame");
		    setVisible(false);
		    dispose();
		}
	    });

	
	buttons.add(send);
	buttons.add(quit);

	this.getContentPane().add( buttons, BorderLayout.SOUTH);

	this.pack();
	this.setVisible(true);

	this.addWindowListener( new WindowAdapter() {
		public void windowClosing(WindowEvent event) {
		    if (mUIEventListener != null)
			mUIEventListener
			    .endConversation(mMyName, mOtherName,
					     MessageSplitFrame.this );
		    else
			System.err.println("UI WARNING: UIEventListener is "
					   +"null in MessageSplitFrame");
		    setVisible(false);
		    dispose();
		}
	    });
    }

    /**
     * This is used to post local text to the conversation half of the frame.
     **/
    
    private void addLocalMessage(String text) {
	mTopHalf.append(mMyName + ": ");
	mTopHalf.append( text );
	if (!text.endsWith("\n"))
	    mTopHalf.append("\n");
    }

    /**
     * This is used to post text from the remote user into the conversation
     * frame.
     **/
    private void addRemoteMessage(String text) {
	mTopHalf.append(mOtherName + ": ");
	mTopHalf.append( text );
	if (!text.endsWith("\n"))
	    mTopHalf.append("\n");
    }

    private synchronized void fireNewMessage(String message) {
	Object[] listeners = mListenerList.getListenerList();

	MessageEvent newMessage = new MessageEvent(message);
	for( int i = listeners.length-2; i >= 0; i-=2 ) {
	    if (listeners[i] == MessageListener.class) {
		((MessageListener)listeners[i+1]).gotMessage( newMessage );
	    }
	}

    }


}


