package org.buzztroll.mud;

import java.util.StringTokenizer;
import java.util.Hashtable;
import java.util.Vector;
import java.awt.*;
import java.io.*;
import java.text.*;
import java.net.*;
import java.awt.event.*;
import java.awt.datatransfer.*;

import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.*;
import javax.swing.border.*;

import com.ozten.font.JFontChooser;

public class MudChatWindow extends JFrame
    implements MudConnectionListener {
    
    private static final String PAGES =
	" pages, ";
    
    private static final String SAYS = 
	" [to you]: ";

    private static final String WHISPER =
	" whispers to you, ";

    private static final String FROM =
	"(from ";

    protected JPopupMenu menu;
    protected JMenuItem pasteMenu;
    protected TextDisplay display;
    protected EmacsTextBox commandText;

    private JRadioButton privateReplyCB;
    private JRadioButton publicReplyCB;

    private Color peerColor = Color.red;
    private Color selfColor = Color.green;

    private MudConnection connection;
    private String who = null;
    private int whoLen;
    private String self = null;

    public MudChatWindow(MudConnection connection,
			 String self,
			 String peer,
			 ConfigFrame configFrame) {
	super("Chat - [" + peer + "]");

	this.connection = connection;
	this.connection.addListener(this);

	this.who = peer;
	this.whoLen = who.length();
	
	this.self = self;

	this.display = new TextDisplay(configFrame);
	this.display.addMouseListener(new ChatMouseListener());

	this.commandText = new EmacsTextBox();
	this.commandText.addKeyListener(new ChatKeyListener());
	this.commandText.setRows(1);
        this.commandText.setBorder(new EtchedBorder());
	this.commandText.setLineWrap(true);
        this.commandText.setWrapStyleWord(true);

	this.getContentPane().setLayout(new BorderLayout());
	this.getContentPane().add("Center", this.display);
	this.getContentPane().add("South", this.commandText);

	this.addWindowListener(new ChatWindowListener(this));

	this.menu = new JPopupMenu("BuzzTroll Chat");
	this.pasteMenu = menu.add("Paste");
        this.pasteMenu.addActionListener(new ChatActionListener());

	JMenu typeMenu = new JMenu("Reply");
	this.privateReplyCB = new JRadioButton("Private");
	this.publicReplyCB = new JRadioButton("Public");

	typeMenu.add(this.privateReplyCB);
	typeMenu.add(this.publicReplyCB);

	ButtonGroup group = new ButtonGroup();
	group.add(this.privateReplyCB);
	group.add(this.publicReplyCB);

	this.menu.add(typeMenu);

	this.menu.addSeparator();
        this.menu.add("Dismiss");

	this.peerColor = configFrame.namePanel.getColor(peer);
	this.selfColor = configFrame.namePanel.getSelfColor();

	this.privateReplyCB.setSelected(true);
	this.commandText.grabFocus();
    }

    public void disconnected() {
	display.addMessage(new DisplayMessage("Connection broken",
					      Color.red, 
					      null));
    }

    public void messageReceived(String message) {
	if (message == null) {
	    return;
	}
	
	String msg = null;

	if (message.regionMatches(true, 0, who, 0, whoLen)) {
	    if (message.regionMatches(true, whoLen, PAGES, 
				      0, PAGES.length())) {
		msg = message.substring(whoLen + PAGES.length() + 1,
					message.length()-1);
	    } else if (message.regionMatches(true, whoLen, SAYS, 
					     0, SAYS.length())) {
		msg = message.substring(whoLen + SAYS.length());
	    } else if (message.regionMatches(true, whoLen, WHISPER,
					     0, WHISPER.length())) {
		msg = message.substring(whoLen + WHISPER.length() + 1,
					message.length()-1);
	    } else {
		return;
	    }
	} else if (message.startsWith(FROM)) {
	    int pos = message.indexOf(')', FROM.length());
	    if (pos == -1) {
		return;
	    }
	    if (message.regionMatches(true, pos+2, who, 0, whoLen)) {
		msg = message.substring(pos+2+whoLen+1);
	    } else {
		return;
	    }
	} else {
	    return;
	}

	msg = who + ": " + msg;
	this.display.addMessage(new DisplayMessage(msg, peerColor, null));

	commandText.grabFocus();
    }

    public void connectTic() {}

    class ChatKeyListener implements KeyListener {
	public void keyPressed(KeyEvent ke) {}
	public void keyReleased(KeyEvent ke) {}

	public void keyTyped(KeyEvent ke) {
	    if( ke.getKeyChar() == '\n') {
		String msg = commandText.getRawText();
		if (msg.length() == 0) {
		    return;
		}
		if (privateReplyCB.isSelected()) {
		    connection.sendLine("page " + who + " " + msg);
		} else {
		    connection.sendLine(who + ", " + msg);
		}
		commandText.setText("");
		display.addMessage(new DisplayMessage(self + ": " + msg, 
						      selfColor, null));
	    }
	}
    }
    
    class ChatWindowListener extends WindowAdapter {

	MudChatWindow window;

	public ChatWindowListener(MudChatWindow window) {
	    this.window = window;
	}

	public void windowClosing(WindowEvent we) {
	    connection.removeListener(this.window);
	    this.window.dispose();
	}
    }

    class ChatActionListener implements ActionListener {
	
	public void actionPerformed(ActionEvent e) {
	    if (e.getSource() == pasteMenu) {
		Clipboard clipboard = getToolkit().getSystemClipboard();
		Transferable data = clipboard.getContents(this);
		if(data == null ||
                   !data.isDataFlavorSupported (DataFlavor.stringFlavor)) {
		    return;
		}

		String strData = null;
		try {
		    strData = 
			(String)data.getTransferData(DataFlavor.stringFlavor);
		} catch (Exception ex) {
		    System.err.println(ex.getMessage());
		    return;
		}
		
		StringBuffer buf = new StringBuffer();
		buf.append("@pasteto ").append(who).append("\n");
		buf.append(strData);
		buf.append("\n.\n");
		
		connection.sendLine(buf.toString());
	    }
	}
    }
    
    class ChatMouseListener extends MouseAdapter {
	public void mouseClicked(MouseEvent e) {
	    if ( ((e.getModifiers() & InputEvent.BUTTON2_MASK) != 0) ||
		 ((e.getModifiers() & InputEvent.BUTTON3_MASK) != 0) ) {
		// TBD: disable paste button if nothing in clipboard
		// just like in MudClient.java
		menu.show(e.getComponent(), e.getX(), e.getY());
	    } else {
		commandText.grabFocus();
	    }
	}
    }
}