package org.chartsy.chatsy.chat.ui.status;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.TimerTask;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import org.chartsy.chatsy.chat.util.FontLoader;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smackx.packet.VCard;
import org.chartsy.chatsy.chat.PresenceManager;
import org.chartsy.chatsy.chat.ChatsyManager;
import org.chartsy.chatsy.chat.ui.PresenceListener;
import org.chartsy.chatsy.chat.util.GraphicUtils;
import org.chartsy.chatsy.chat.util.ModelUtil;
import org.chartsy.chatsy.chat.util.SwingTimerTask;
import org.chartsy.chatsy.chat.util.SwingWorker;
import org.chartsy.chatsy.chat.util.TaskEngine;
import org.chartsy.chatsy.chatimpl.profile.VCardEditor;
import org.chartsy.chatsy.chatimpl.profile.VCardListener;
import org.chartsy.chatsy.chatimpl.profile.VCardManager;
import org.openide.util.ImageUtilities;
import org.openide.util.NbPreferences;
public class StatusBar extends JPanel implements VCardListener
{
private static final long serialVersionUID = -4322806442034868526L;
private List<StatusItem> statusList = new ArrayList<StatusItem>();
private AvatarLabel imageLabel;
private JLabel descriptiveLabel = new JLabel();
private JLabel nicknameLabel = new JLabel();
private StatusButton statusButton = new StatusButton();
private Presence currentPresence;
public StatusBar()
{
setLayout(new GridBagLayout());
setOpaque(false);
imageLabel = new AvatarLabel();
add(imageLabel, new GridBagConstraints(0, 0, 1, 4, 0.0, 0.0,
GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
new Insets(2, 2, 2, 2), 0, 0));
add(nicknameLabel, new GridBagConstraints(1, 0, 2, 2, 1.0, 0.0,
GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
new Insets(10, 5, 0, 0), 0, 0));
add(descriptiveLabel, new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0,
GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
new Insets(0, 5, 0, 0), 0, 0));
add(statusButton, new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0,
GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
new Insets(10, 2, 0, 0), 0, 0));
nicknameLabel.setToolTipText(ChatsyManager.getConnection().getUser());
nicknameLabel.setFont(FontLoader.getDroidFont(Font.BOLD, 14));
buildStatusItemList();
setStatus(PresenceManager._AVAILABLE);
currentPresence = new Presence(Presence.Type.available, PresenceManager._AVAILABLE, 1, Presence.Mode.available);
ChatsyManager.getSessionManager().addPresenceListener(new PresenceListener()
{
public void presenceChanged(Presence presence)
{
changeAvailability(presence);
}
});
imageLabel.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent mouseEvent)
{
if (mouseEvent.getClickCount() == 1)
{
VCardManager vcardManager = ChatsyManager.getVCardManager();
VCardEditor editor = new VCardEditor();
editor.editProfile(vcardManager.getVCard(), ChatsyManager.getWorkspace());
}
}
});
final TimerTask task = new SwingTimerTask()
{
public void doRun()
{
ChatsyManager.getVCardManager().addVCardListener(ChatsyManager.getWorkspace().getStatusBar());
}
};
TaskEngine.getInstance().schedule(task, 3000);
}
public void setAvatar(Icon icon)
{
imageLabel.setIcon(icon);
invalidate();
validateTree();
}
public void setNickname(String nickname)
{
nicknameLabel.setText(nickname);
}
public void setStatus(String status)
{
statusButton.setStatus(status);
}
public void setStatusIcon(Icon icon)
{
statusButton.setIcon(icon);
}
public void showPopup(MouseEvent e)
{
final StatusPopup popup = new StatusPopup();
for (final StatusItem statusItem : statusList)
{
final Action statusAction = new AbstractAction()
{
public void actionPerformed(ActionEvent actionEvent)
{
final String text = statusItem.getText();
final StatusItem si = getStatusItem(text);
if (si == null)
return;
SwingWorker worker = new SwingWorker()
{
public Object construct()
{
ChatsyManager.getSessionManager().changePresence(si.getPresence());
return "ok";
}
public void finished()
{
setStatus(text);
}
};
worker.start();
}
};
statusAction.putValue(Action.NAME, statusItem.getText());
statusAction.putValue(Action.SMALL_ICON, statusItem.getIcon());
popup.add(new StatusMenuItem(statusAction));
}
popup.show(statusButton, 0, statusButton.getHeight());
}
public void changeAvailability(final Presence presence)
{
if ((presence.getMode() == currentPresence.getMode())
&& (presence.getType() == currentPresence.getType())
&& (presence.getStatus().equals(currentPresence.getStatus())))
{
PacketExtension pe = presence.getExtension("x", "vcard-temp:x:update");
if (pe != null)
loadVCard();
return;
}
final Runnable changePresenceRunnable = new Runnable()
{
public void run()
{
currentPresence = presence;
setStatus(presence.getStatus());
Icon icon = PresenceManager.getIconFromPresence(presence);
if (icon != null)
statusButton.setStatusIcon(icon);
}
};
SwingUtilities.invokeLater(changePresenceRunnable);
}
private void buildStatusItemList()
{
for (Presence presence : PresenceManager.getPresences())
{
Icon icon = PresenceManager.getIconFromPresence(presence);
StatusItem item = new StatusItem(presence, icon);
statusList.add(item);
}
final Icon availableIcon = PresenceManager.AVAILABLE_ICON;
statusButton.setStatusIcon(availableIcon);
validate();
repaint();
}
public Collection<StatusItem> getStatusList()
{
return statusList;
}
public Presence getPresence()
{
return currentPresence;
}
public StatusItem getStatusItem(String label)
{
for (StatusItem aStatusList : statusList)
if (aStatusList.getText().equals(label))
return aStatusList;
return null;
}
public void loadVCard()
{
final Runnable loadVCard = new Runnable()
{
public void run()
{
VCard vcard = ChatsyManager.getVCardManager().getVCard();
updatVCardInformation(vcard);
}
};
TaskEngine.getInstance().submit(loadVCard);
}
private void updatVCardInformation(final VCard vCard)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
if (vCard.getError() == null)
{
String firstName = vCard.getFirstName();
String lastName = vCard.getLastName();
String nickname = vCard.getNickName();
if (ModelUtil.hasLength(firstName) && ModelUtil.hasLength(lastName)) {
setNickname(firstName + " " + lastName);
NbPreferences.root().node("/org/chartsy/chat").put("nickname", firstName + " " + lastName);
}
else if (ModelUtil.hasLength(firstName)) {
setNickname(firstName);
NbPreferences.root().node("/org/chartsy/chat").put("nickname", firstName);
}
else if (ModelUtil.hasLength(nickname)) {
setNickname(nickname);
NbPreferences.root().node("/org/chartsy/chat").put("nickname", nickname);
}
else
{
nickname = ChatsyManager.getSessionManager().getUsername();
setNickname(nickname);
NbPreferences.root().node("/org/chartsy/chat").put("nickname", nickname);
}
}
else
{
String nickname = ChatsyManager.getSessionManager().getUsername();
setNickname(nickname);
NbPreferences.root().node("/org/chartsy/chat").put("nickname", nickname);
return;
}
byte[] avatarBytes = null;
try
{
avatarBytes = vCard.getAvatar();
}
catch (Exception e)
{
}
if (avatarBytes != null
&& avatarBytes.length > 0)
{
try
{
ImageIcon avatarIcon = new ImageIcon(avatarBytes);
avatarIcon = VCardManager.scale(avatarIcon);
imageLabel.setIcon(GraphicUtils.scaleImageIcon(avatarIcon, 64, 64));
imageLabel.invalidate();
imageLabel.validate();
imageLabel.repaint();
}
catch (Exception e)
{
}
}
else
{
ImageIcon icon = ImageUtilities.loadImageIcon("org/chartsy/chatsy/resources/default-avatar-64.png", true);
imageLabel.setIcon(icon);
imageLabel.invalidate();
imageLabel.validate();
imageLabel.repaint();
}
}
});
}
public static Presence copyPresence(Presence presence)
{
return new Presence(presence.getType(), presence.getStatus(), presence.getPriority(), presence.getMode());
}
public JLabel getNicknameLabel()
{
return nicknameLabel;
}
private class StatusButton extends JButton
{
private Image backgroundImage;
public StatusButton()
{
setOpaque(false);
setBorderPainted(false);
setRolloverEnabled(false);
setFocusPainted(false);
setContentAreaFilled(false);
setPreferredSize(new Dimension(188, 25));
setMinimumSize(new Dimension(188, 25));
setMaximumSize(new Dimension(188, 25));
setHorizontalAlignment(JButton.LEFT);
setHorizontalTextPosition(JButton.RIGHT);
setVerticalAlignment(JButton.CENTER);
setVerticalTextPosition(JButton.CENTER);
setIconTextGap(5);
setMargin(new Insets(0, 10, 0, 5));
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
setFont(FontLoader.getDroidFont(Font.PLAIN, 12));
setForeground(Color.decode("0x111111"));
addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
showPopup(e);
}
});
backgroundImage = ImageUtilities.loadImage("org/chartsy/chatsy/resources/status-btn.png", true);
}
protected void paintComponent(Graphics g)
{
Graphics2D graphics2D = (Graphics2D) g;
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
graphics2D.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
graphics2D.drawImage(backgroundImage, 0, 0, this);
super.paintComponent(graphics2D);
}
public void setStatus(String status)
{
if (status == null)
return;
int length = status.length();
String visualStatus = status;
if (length > 30)
visualStatus = status.substring(0, 27) + "...";
setText(visualStatus);
setToolTipText(status);
}
public void setStatusIcon(Icon icon)
{
setIcon(icon);
this.repaint();
}
}
public void setDescriptiveText(String text)
{
descriptiveLabel.setText(text);
}
public Dimension getPreferredSize()
{
Dimension dim = super.getPreferredSize();
dim.width = 0;
return dim;
}
public void vcardChanged(VCard vcard)
{
updatVCardInformation(vcard);
}
private static class AvatarLabel extends JLabel
{
private boolean mouseOver = false;
private Image borderImage;
private AvatarLabel()
{
super();
setOpaque(false);
setPreferredSize(new Dimension(70, 69));
setMinimumSize(new Dimension(70, 69));
setMaximumSize(new Dimension(70, 69));
setHorizontalAlignment(JLabel.CENTER);
setVerticalAlignment(JLabel.CENTER);
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
borderImage = ImageUtilities.loadImage("org/chartsy/chatsy/resources/avatar-border.png", true);
addMouseListener(new MouseAdapter()
{
public void mouseEntered(MouseEvent e)
{
mouseOver = true;
repaint();
}
public void mouseExited(MouseEvent e)
{
mouseOver = false;
repaint();
}
});
}
protected void paintComponent(Graphics g)
{
Graphics2D graphics2D = (Graphics2D) g;
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
graphics2D.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
super.paintComponent(graphics2D);
if (mouseOver)
graphics2D.drawImage(borderImage, 0, 0, this);
}
}
private static class StatusPopup extends JPopupMenu
{
private StatusPopup()
{
super();
setOpaque(true);
setBorderPainted(false);
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
setBackground(Color.WHITE);
}
public Dimension getPreferredSize()
{
Dimension dimension = super.getPreferredSize();
return new Dimension(188, dimension.height);
}
}
private static class StatusMenuItem extends JMenuItem
{
private StatusMenuItem(Action action)
{
super(action);
setOpaque(false);
setFont(FontLoader.getDroidFont(Font.PLAIN, 12));
setForeground(Color.decode("0x111111"));
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
setBorderPainted(false);
setFocusPainted(false);
setContentAreaFilled(false);
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
}
}