package org.chartsy.chatsy.chat.ui;
import org.jdesktop.swingx.calendar.DateUtils;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smackx.packet.DelayInformation;
import org.chartsy.chatsy.chat.ChatsyManager;
import org.chartsy.chatsy.chat.plugin.ContextMenuListener;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JPopupMenu;
import javax.swing.KeyStroke;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
public class TranscriptWindow extends ChatArea implements ContextMenuListener
{
private final SimpleDateFormat notificationDateFormatter;
private final SimpleDateFormat messageDateFormatter;
private final String notificationDateFormat = ((SimpleDateFormat)SimpleDateFormat.getDateInstance(SimpleDateFormat.FULL)).toPattern();
private final String messageDateFormat = ((SimpleDateFormat)SimpleDateFormat.getTimeInstance(SimpleDateFormat.SHORT)).toPattern();
private Date lastUpdated;
private Font defaultFont = new Font("Dialog", Font.PLAIN, 12);
private Date lastPost;
public TranscriptWindow()
{
setEditable(false);
addMouseListener((MouseListener)this);
addMouseMotionListener((MouseMotionListener)this);
addContextMenuListener((ContextMenuListener)this);
setDragEnabled(true);
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("Ctrl c"), "copy");
getActionMap().put("copy", new AbstractAction("copy")
{
public void actionPerformed(ActionEvent evt)
{
StringSelection stringSelection = new StringSelection(getSelectedText());
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
}
});
notificationDateFormatter = new SimpleDateFormat(notificationDateFormat);
messageDateFormatter = new SimpleDateFormat(messageDateFormat);
}
public void addComponent(Component component)
{
final StyledDocument doc = (StyledDocument)getDocument();
Style style = doc.addStyle("StyleName", null);
StyleConstants.setComponent(style, component);
try
{
doc.insertString(doc.getLength(), "ignored text", style);
doc.insertString(doc.getLength(), "\n", null);
}
catch (BadLocationException e)
{
}
}
public void insertMessage(String nickname, Message message, Color foreground)
{
insertMessage(nickname, message, foreground, Color.white);
}
public void insertMessage(String nickname, Message message, Color foreground, Color background)
{
for (TranscriptWindowInterceptor interceptor : ChatsyManager.getChatManager().getTranscriptWindowInterceptors())
{
boolean handled = interceptor.isMessageIntercepted(this, nickname, message);
if (handled)
return;
}
String body = message.getBody();
try
{
DelayInformation inf = (DelayInformation)message.getExtension("x", "jabber:x:delay");
if (inf != null)
body = "(Offline) " + body;
StyleConstants.setBold(styles, false);
StyleConstants.setForeground(styles, foreground);
StyleConstants.setBackground(styles, background);
final Document doc = getDocument();
styles.removeAttribute("link");
StyleConstants.setFontSize(styles, defaultFont.getSize());
doc.insertString(doc.getLength(), nickname + ": ", styles);
StyleConstants.setBold(styles, false);
StyleConstants.setForeground(styles, Color.black);
setText(body);
insertText("\n");
}
catch (BadLocationException e)
{
}
}
public void insertPrefixAndMessage(String prefix, String message, Color foreground)
{
try
{
StyleConstants.setBold(styles, false);
StyleConstants.setForeground(styles, foreground);
final Document doc = getDocument();
styles.removeAttribute("link");
StyleConstants.setFontSize(styles, defaultFont.getSize());
if (prefix != null)
doc.insertString(doc.getLength(), prefix + ": ", styles);
StyleConstants.setBold(styles, false);
StyleConstants.setForeground(styles, Color.black);
setText(message);
insertText("\n");
}
catch (BadLocationException e)
{
}
}
public synchronized void insertNotificationMessage(String message, Color foregroundColor)
{
try
{
StyleConstants.setBold(styles, false);
StyleConstants.setForeground(styles, foregroundColor);
final Document doc = getDocument();
styles.removeAttribute("link");
StyleConstants.setFontSize(styles, defaultFont.getSize());
doc.insertString(doc.getLength(), "", styles);
StyleConstants.setBackground(styles, Color.white);
StyleConstants.setBold(styles, false);
StyleConstants.setForeground(styles, foregroundColor);
setText(message);
insertText("\n");
StyleConstants.setForeground(styles, Color.black);
}
catch (BadLocationException ex)
{
}
}
public synchronized void insertCustomText(String text, boolean bold, boolean underline, Color foreground)
{
try
{
StyleConstants.setBold(styles, true);
StyleConstants.setForeground(styles, foreground);
final Document doc = getDocument();
styles.removeAttribute("link");
StyleConstants.setFontSize(styles, defaultFont.getSize());
doc.insertString(doc.getLength(), "", styles);
StyleConstants.setBold(styles, bold);
StyleConstants.setUnderline(styles, underline);
StyleConstants.setForeground(styles, foreground);
setText(text);
insertText("\n");
StyleConstants.setUnderline(styles, false);
StyleConstants.setForeground(styles, Color.black);
}
catch (BadLocationException ex)
{
}
}
public Date getLastUpdated()
{
return lastUpdated;
}
public void insertHistoryMessage(String userid, String message, Date date)
{
try
{
String value;
long lastPostTime = lastPost != null ? lastPost.getTime() : 0;
long lastPostStartOfDay = DateUtils.startOfDayInMillis(lastPostTime);
long newPostStartOfDay = DateUtils.startOfDayInMillis(date.getTime());
int diff = DateUtils.getDaysDiff(lastPostStartOfDay, newPostStartOfDay);
if (diff != 0)
insertCustomText(notificationDateFormatter.format(date), true, true, Color.BLACK);
value = "(" + messageDateFormatter.format(date) + ") ";
value = value + userid + ": ";
lastPost = date;
StyleConstants.setBold(styles, false);
StyleConstants.setForeground(styles, Color.BLACK);
final Document doc = getDocument();
styles.removeAttribute("link");
StyleConstants.setFontSize(styles, defaultFont.getSize());
doc.insertString(doc.getLength(), value, styles);
StyleConstants.setBold(styles, false);
StyleConstants.setForeground(styles, Color.gray);
setText(message);
StyleConstants.setForeground(styles, Color.BLACK);
insertText("\n");
}
catch (BadLocationException ex)
{
}
}
public void showWindowDisabled()
{
final Document document = getDocument();
final SimpleAttributeSet attrs = new SimpleAttributeSet();
StyleConstants.setForeground(attrs, Color.LIGHT_GRAY);
final int length = document.getLength();
StyledDocument styledDocument = getStyledDocument();
styledDocument.setCharacterAttributes(0, length, attrs, false);
}
public void saveTranscript(String fileName, List<Message> transcript, String headerData)
{
}
public void cleanup()
{
super.releaseResources();
clear();
removeMouseListener(this);
removeMouseMotionListener(this);
removeContextMenuListener(this);
getActionMap().remove("copy");
}
public void setFont(Font font)
{
this.defaultFont = font;
}
public Font getFont()
{
return defaultFont;
}
public void poppingUp(final Object object, JPopupMenu popup)
{
}
public void poppingDown(JPopupMenu popup)
{
}
public boolean handleDefaultAction(MouseEvent e)
{
return false;
}
}