package org.chartsy.chatsy.chat.ui;
import java.awt.BorderLayout;
import java.awt.Container;
import org.jivesoftware.smack.packet.Presence;
import org.chartsy.chatsy.chat.PresenceManager;
import org.chartsy.chatsy.chat.util.ModelUtil;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.TexturePaint;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.chartsy.chatsy.chat.util.FontLoader;
import org.chartsy.chatsy.chat.ChatsyManager;
public class ContactGroup extends JPanel implements MouseListener
{
private static final Logger LOG = Logger.getLogger(ContactGroup.class.getName());
private List<String> contactItems = new ArrayList<String>();
private Map<String, ContactItem> contactItemsMap = new HashMap<String, ContactItem>();
private List<ContactGroupListener> listeners = new ArrayList<ContactGroupListener>();
private String groupName;
private GroupNamePanel groupNamePanel;
private JPanel listPanel;
private boolean expanded = true;
public ContactGroup(String groupName)
{
super(new BorderLayout());
setOpaque(false);
setName(groupName);
this.groupName = groupName;
groupNamePanel = new GroupNamePanel();
groupNamePanel.setGroupName(groupName);
listPanel = new JPanel();
listPanel.setOpaque(false);
listPanel.setLayout(new LayoutManager()
{
public void addLayoutComponent(String name, Component comp)
{
}
public void removeLayoutComponent(Component comp)
{
}
public Dimension preferredLayoutSize(Container parent)
{
return new Dimension(0, 0);
}
public Dimension minimumLayoutSize(Container parent)
{
return new Dimension(0, 0);
}
public void layoutContainer(Container parent)
{
Insets insets = parent.getInsets();
int w = parent.getWidth() - insets.left - insets.right;
int x = 0;
int y = 0;
for (Component component : parent.getComponents())
{
if (component.isVisible())
{
component.setBounds(x, y, w, 42);
y += 42;
}
}
}
});
add(groupNamePanel, BorderLayout.NORTH);
add(listPanel, BorderLayout.CENTER);
groupNamePanel.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
if (e.getButton() == MouseEvent.BUTTON1)
toggleExpanded();
else if (e.getButton() == MouseEvent.BUTTON3)
fireContactGroupPopupEvent(e);
}
});
}
public int getPanelHeight()
{
int height = 25;
if (expanded)
for (int i = 0; i < getComponentCount(); i++)
height += 42;
return height;
}
public void toggleExpanded()
{
setExpanded(!expanded);
}
public void setExpanded(boolean expanded)
{
this.expanded = expanded;
this.listPanel.setVisible(expanded);
}
public boolean isExpanded()
{
return expanded;
}
public boolean isEmpty()
{
Component[] components = listPanel.getComponents();
for (Component component : components)
if (component.isVisible())
return false;
return true;
}
public void setTitle(String title)
{
groupNamePanel.setGroupName(title);
}
public void addOfflineContactItem(final String alias, final String nickname, final String jid, final String status)
{
try
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
final ContactItem offlineItem = new ContactItem(alias, nickname, jid);
offlineItem.setGroupName(getGroupName());
final Presence offlinePresence = PresenceManager.getPresence(jid);
offlineItem.setPresence(offlinePresence);
offlineItem.setIcon(PresenceManager.getIconFromPresence(offlinePresence));
if (ModelUtil.hasLength(status))
offlineItem.setStatusText(status);
offlineItem.setOffline(true);
contactItems.add(offlineItem.getJID());
contactItemsMap.put(offlineItem.getJID(), offlineItem);
insertOfflineContactItem(offlineItem);
}
});
}
catch(Exception ex)
{
LOG.log(Level.SEVERE, "", ex);
}
}
public void insertOfflineContactItem(ContactItem offlineItem)
{
Collections.sort(contactItems);
int index = contactItems.indexOf(offlineItem.getJID());
listPanel.add(offlineItem, index);
}
public void removeOfflineContactItem(ContactItem item)
{
contactItems.remove(item.getJID());
contactItemsMap.remove(item.getJID());
removeContactItem(item);
}
public void removeOfflineContactItem(String jid)
{
for (Component component : listPanel.getComponents())
if (component.getName().equals(jid))
removeOfflineContactItem((ContactItem) component);
}
public void toggleOfflineVisibility(boolean show)
{
final List<ContactItem> items = getContactItems();
for (ContactItem contactItem : items)
{
if (show)
insertOfflineContactItem(contactItem);
}
}
public void addContactItem(ContactItem item)
{
removeOfflineContactItem(item.getJID());
item.setGroupName(getGroupName());
contactItems.add(item.getJID());
contactItemsMap.put(item.getJID(), item);
List<String> tempItems = getContactItemsJIDs();
Collections.sort(tempItems);
int index = tempItems.indexOf(item.getJID());
listPanel.add(item, index);
fireContactItemAdded(item);
updateTitle();
}
public void fireContactGroupUpdated()
{
listPanel.validate();
listPanel.repaint();
updateTitle();
}
public void addContactGroup(ContactGroup contactGroup)
{
}
public void removeContactGroup(ContactGroup contactGroup)
{
}
public void setPanelBackground(Color color)
{
}
public ContactGroup getContactGroup(String groupName)
{
return null;
}
public void removeContactItem(ContactItem item)
{
contactItems.remove(item.getJID());
contactItemsMap.remove(item.getJID());
if (contactItems.isEmpty())
setVisible(false);
listPanel.remove(item);
updateTitle();
fireContactItemRemoved(item);
}
public ContactItem getContactItemByDisplayName(String displayName)
{
for (Component component : listPanel.getComponents())
if (component instanceof ContactItem) {
final ContactItem item = (ContactItem) component;
if (item.getDisplayName().equals(displayName))
return item;
}
return null;
}
public ContactItem getContactItemByJID(String bareJID)
{
return contactItemsMap.get(bareJID);
}
public List<ContactItem> getContactItems()
{
final List<ContactItem> list = new ArrayList<ContactItem>();
for (Component component : listPanel.getComponents())
if (component instanceof ContactItem)
list.add((ContactItem)component);
return list;
}
public String getGroupName()
{
return groupName;
}
public void mouseClicked(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
public void mousePressed(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e)
{
}
public void checkPopup(MouseEvent e)
{
if (e.getButton() == MouseEvent.BUTTON3)
{
final Collection<ContactItem> selectedItems = ChatsyManager.getChatManager().getSelectedContactItems();
if (selectedItems.size() > 1)
firePopupEvent(e, selectedItems);
else if (selectedItems.size() == 1)
firePopupEvent(e, (ContactItem)selectedItems.iterator().next());
}
}
public void addContactGroupListener(ContactGroupListener listener)
{
listeners.add(listener);
}
public void removeContactGroupListener(ContactGroupListener listener)
{
listeners.remove(listener);
}
public void contactItemClicked(ContactItem item)
{
fireContactItemClicked(item);
}
private void fireContactItemClicked(ContactItem item)
{
for (ContactGroupListener contactGroupListener : new ArrayList<ContactGroupListener>(listeners))
contactGroupListener.contactItemClicked(item);
}
public void contactItemDoubleClicked(ContactItem item)
{
fireContactItemDoubleClicked(item);
}
private void fireContactItemDoubleClicked(ContactItem item)
{
for (ContactGroupListener contactGroupListener : new ArrayList<ContactGroupListener>(listeners))
contactGroupListener.contactItemDoubleClicked(item);
}
private void firePopupEvent(MouseEvent e, ContactItem item)
{
for (ContactGroupListener contactGroupListener : new ArrayList<ContactGroupListener>(listeners))
contactGroupListener.showPopup(e, item);
}
private void firePopupEvent(MouseEvent e, Collection<ContactItem> items)
{
for (ContactGroupListener contactGroupListener : new ArrayList<ContactGroupListener>(listeners))
contactGroupListener.showPopup(e, items);
}
private void fireContactGroupPopupEvent(MouseEvent e)
{
for (ContactGroupListener contactGroupListener : new ArrayList<ContactGroupListener>(listeners))
contactGroupListener.contactGroupPopup(e, this);
}
private void fireContactItemAdded(ContactItem item)
{
for (ContactGroupListener contactGroupListener : new ArrayList<ContactGroupListener>(listeners))
contactGroupListener.contactItemAdded(item);
}
private void fireContactItemRemoved(ContactItem item)
{
for (ContactGroupListener contactGroupListener : new ArrayList<ContactGroupListener>(listeners))
contactGroupListener.contactItemRemoved(item);
}
private void updateTitle()
{
int count = 0;
List<ContactItem> list = new ArrayList<ContactItem>(getContactItems());
int size = list.size();
for (int i = 0; i < size; i++)
{
ContactItem it = list.get(i);
if (!it.isOffline())
count++;
}
setTitle(getGroupTitle(groupName) + " (" + count + " " + "Online" + ")");
setVisible(count == 0 ? false : true);
}
public void clearSelection()
{
}
public void removeAllContacts()
{
for (ContactItem item : new ArrayList<ContactItem>(getContactItems()))
removeContactItem(item);
for (ContactItem item : getOfflineContacts())
removeOfflineContactItem(item);
}
public boolean hasAvailableContacts()
{
for (ContactItem item : getContactItems())
if (item.getPresence() != null)
return true;
return false;
}
public Collection<ContactItem> getOfflineContacts()
{
final List<ContactItem> list = new ArrayList<ContactItem>();
for (ContactItem contactItem : getContactItems())
if (contactItem.isOffline())
list.add(contactItem);
return list;
}
final Comparator<ContactItem> itemComparator = new Comparator<ContactItem>()
{
public int compare(ContactItem item1, ContactItem item2)
{
return item1.getDisplayName().toLowerCase().compareTo(item2.getDisplayName().toLowerCase());
}
};
public boolean isOfflineGroup()
{
return "Offline Group".equals(getGroupName());
}
public boolean isUnfiledGroup()
{
return "Unfiled".equals(getGroupName());
}
public String toString()
{
return getGroupName();
}
public boolean isSharedGroup()
{
return false;
}
protected void setSharedGroup(boolean sharedGroup)
{
}
public List<ContactItem> getSelectedContacts()
{
return new ArrayList<ContactItem>();
}
public JPanel getContainerPanel()
{
return listPanel;
}
public Collection<ContactGroup> getContactGroups()
{
return new ArrayList<ContactGroup>();
}
public Dimension getPreferredSize()
{
final Dimension size = super.getPreferredSize();
size.width = 0;
return size;
}
public void setGroupName(String groupName)
{
this.groupName = groupName;
this.setName(groupName);
updateTitle();
}
public String getGroupTitle(String title)
{
int lastIndex = title.lastIndexOf("::");
if (lastIndex != -1)
title = title.substring(lastIndex + 2);
return title;
}
public boolean isSubGroup(String groupName)
{
return groupName.indexOf("::") != -1;
}
public boolean isSubGroup()
{
return isSubGroup(getGroupName());
}
public JPanel getListPanel()
{
return listPanel;
}
private List<String> getContactItemsJIDs()
{
return contactItems;
}
private static class GroupNamePanel extends JPanel
{
private JLabel groupName;
private TexturePaint texturePaint;
private GroupNamePanel()
{
super(new BorderLayout());
setOpaque(false);
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
groupName = new JLabel();
groupName.setOpaque(false);
groupName.setFont(FontLoader.getDroidFont(Font.BOLD, 14));
groupName.setForeground(Color.WHITE);
groupName.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0));
add(groupName, BorderLayout.CENTER);
try
{
BufferedImage bufferedImage = ImageIO.read(getClass().getResource("/org/chartsy/chatsy/resources/contact-group-bg.png"));
Rectangle rectangle = new Rectangle(0, 0, bufferedImage.getWidth(null), bufferedImage.getHeight(null));
texturePaint = new TexturePaint(bufferedImage, rectangle);
}
catch (IOException ex)
{
}
}
public void setGroupName(String name)
{
groupName.setText(name);
}
public String getGroupName()
{
return groupName.getText();
}
public Dimension getPreferredSize()
{
final Dimension dimension = super.getPreferredSize();
dimension.setSize(dimension.getWidth(), 25);
return dimension;
}
protected void paintComponent(Graphics g)
{
super.paintComponent(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.setPaint(texturePaint);
graphics2D.fill(new Rectangle(0, 0, getWidth(), getHeight()));
}
}
}