/*
Eteria IRC Client, an RFC 1459 compliant client program written in Java.
Copyright (C) 2000-2001 Javier Kohen <jkohen at tough.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import java.net.MalformedURLException;
import java.io.*;
import java.util.*;
import java.text.Collator;
import java.text.MessageFormat;
import java.text.ParseException;
import ar.com.jkohen.irc.Channel;
import ar.com.jkohen.irc.User;
import ar.com.jkohen.irc.MircMessage;
//import ar.com.jkohen.awt.BorderedPanel;
import ar.com.jkohen.awt.ChatPanel;
import ar.com.jkohen.awt.ImageButton;
import ar.com.jkohen.awt.MircSmileyTextArea;
import ar.com.jkohen.util.Resources;
import ar.com.jkohen.util.ConfigurationProperties;
import com.splendid.awtchat.*;
public class ChanListWindow extends ChatPanel implements ActionListener, ItemListener, HyperlinkReceiver, Observer, CopyText
{
private EIRC eirc;
private String title;
private MircSmileyTextArea text_canvas;
private TextField new_chan, users_nbr;
private Checkbox byname, bynumber;
private ImageButton b;
// private BorderedPanel panel;
private Label label;
private int number = 0;
private Resources res;
protected static final String min_str = Resources.getString("channel_list.minima");
protected static final String users_str = Resources.getString("channel_list.users");
protected static final String newchan_str = Resources.getString("channel_list.new");
protected static final String refresh = Resources.getString("channel_list.refresh");
private Vector chans;
private Vector chanserv;
private Collator collator;
private final int SORT_BYNAME = 0;
private final int SORT_BYNUM = 1;
private final int SORT_BYTOPIC = 2;
private int sort_criteria = SORT_BYNAME;
/* Configuration properties. */
private String list_parameter;
public ChanListWindow(EIRC eirc, String title)
{
super(title);
text_canvas = new MircSmileyTextArea(this, this);
this.eirc = eirc;
this.title = title;
this.collator = Collator.getInstance();
text_canvas.setMode(eirc.scrollSpeed());
text_canvas.setBufferlen(35000);
text_canvas.setBreaks(false);
int tabs[] = {-1, 160, 190};
text_canvas.setTabs(tabs);
GridBagLayout gb = new GridBagLayout();
GridBagConstraints gbc = new GridBagConstraints();
setLayout(gb);
gbc.insets = new Insets(2, 2, 2, 2);
label = new Label(newchan_str + " : ");
gbc.gridx = 0;
gbc.gridy = 2;
gbc.gridwidth = 3;
gbc.anchor = GridBagConstraints.WEST;
gbc.fill = GridBagConstraints.NONE;
gbc.weighty = 0;
gbc.weightx = 0;
gb.setConstraints(label, gbc);
add(label);
new_chan = new TextField(20);
gbc.gridx = 3;
gbc.weighty = 0;
gbc.gridwidth = 4;
gbc.anchor = GridBagConstraints.WEST;
gbc.fill = GridBagConstraints.HORIZONTAL;
gb.setConstraints(new_chan, gbc);
add(new_chan);
// panel = new BorderedPanel(res.getString("channel_list.frame"));
// GridBagLayout gb2 = new GridBagLayout();
// GridBagConstraints gbc2 = new GridBagConstraints();
// panel.setLayout(gb2);
// gbc2.weightx = 1.0;
// gbc2.insets = new Insets(2, 2, 2, 2);
Label l = new Label(min_str);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.weightx = 0;
gbc.fill = GridBagConstraints.NONE;
gbc.anchor = GridBagConstraints.WEST;
gb.setConstraints(l, gbc);
add(l);
gbc.gridx++;
users_nbr = new TextField("1", 2);
gb.setConstraints(users_nbr, gbc);
add(users_nbr);
gbc.gridx++;
l = new Label(users_str);
gb.setConstraints(l, gbc);
add(l);
l = new Label(res.getString("channel_list.sort") + " :");
gbc.gridx++;
gb.setConstraints(l, gbc);
add(l);
CheckboxGroup cbg = new CheckboxGroup();
byname = new Checkbox(res.getString("channel_list.byname"), cbg, (sort_criteria == SORT_BYNAME));
gbc.gridx++;
gb.setConstraints(byname, gbc);
add(byname);
bynumber = new Checkbox(res.getString("channel_list.bynumber"), cbg, (sort_criteria == SORT_BYNUM));
gbc.gridx++;
gb.setConstraints(bynumber, gbc);
add(bynumber);
b = new ImageButton(refresh);
b.setWaitType();
b.setEnabled(true);
b.setActionCommand("list");
gbc.gridx++;
gbc.anchor = GridBagConstraints.WEST;
gb.setConstraints(b, gbc);
add(b);
// gbc.gridx = 0;
// gbc.gridy++;
// gbc.gridwidth = 2;
// gbc.weighty = 0;
// gbc.anchor = GridBagConstraints.NORTH;
// gb.setConstraints(panel, gbc);
// add(panel);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.CENTER;
gbc.fill = GridBagConstraints.BOTH;
gbc.weighty = 1;
gbc.weightx = 1;
gbc.gridwidth = 7;
gb.setConstraints(text_canvas, gbc);
add(text_canvas);
bynumber.addItemListener(this);
byname.addItemListener(this);
new_chan.addActionListener(this);
users_nbr.addActionListener(this);
b.addActionListener(this);
// readChanServList("chanlist.txt");
}
public void clear()
{
text_canvas.clear();
}
public void listChannels()
{
String l[];
int min = 1;
try
{
min = Integer.parseInt(users_nbr.getText());
} catch (NumberFormatException e) {}
if (--min > 0)
{
l = new String[1];
l[0] = MessageFormat.format(list_parameter, new Object[] { new Integer(min) });
eirc.sendMessage("LIST", l);
}
else
{
l = new String[0];
eirc.sendMessage("LIST", l);
}
}
public void loadChannels(Vector data)
{
/*
for (Enumeration e = chanserv.elements(); e.hasMoreElements(); )
{
ChannelItem reg_channel = (ChannelItem) e.nextElement();
String reg_name = reg_channel.getTag();
boolean insert = true;
for (Enumeration ee = data.elements(); ee.hasMoreElements(); )
{
ChannelItem channel = (ChannelItem) ee.nextElement();
String name = channel.getTag();
if (reg_name.equalsIgnoreCase(name))
insert = false;
}
if (insert)
data.addElement(reg_channel);
}
*/
this.chans = data;
display();
}
private void display()
{
text_canvas.setMode(text_canvas.SAFE);
text_canvas.clear();
sort(chans);
for (Enumeration e = chans.elements(); e.hasMoreElements(); )
{
ChannelItem channel = (ChannelItem) e.nextElement();
String topic = channel.getTopic();
if (topic != null)
{
// Strip chan modes in topic (Unreal)
if (topic.startsWith("[+"))
{
MessageFormat mf = new MessageFormat("[+{0}] {1}");
try
{
Object o[] = mf.parse(topic);
if (o[1] != null)
topic = o[1].toString();
}
catch (ParseException ex) {}
}
}
text_canvas.append(channel.getTag() + " " + MircMessage.COLOR + "3 " + channel.getUsers() + " " + MircMessage.RESET + topic);
}
text_canvas.setMode(eirc.scrollSpeed());
b.setEnabled(true);
}
// Sorting algorithm from James Gosling
private void sort(Vector v)
{
sort(v, 0, v.size() - 1);
}
private void sort(Vector v, int i, int j)
{
int k = i;
int l = j;
if(k >= l)
return;
else
if(k == l - 1)
{
Object a = v.elementAt(k);
Object b = v.elementAt(l);
if (compare(a, b) < 0)
{
v.setElementAt(b, k);
v.setElementAt(a, l);
}
}
Object a = v.elementAt((k + l) / 2);
v.setElementAt(v.elementAt(l), (k + l) / 2);
v.setElementAt(a, l);
while(k < l)
{
while(k < l && compare(a, v.elementAt(k)) >= 0)
k++;
while(k < l && compare(a, v.elementAt(l)) <= 0)
l--;
if(k < l)
{
Object o = v.elementAt(k);
v.setElementAt(v.elementAt(l), k);
v.setElementAt(o, l);
}
}
v.setElementAt(v.elementAt(l), j);
v.setElementAt(a, l);
sort(v, i, k - 1);
sort(v, l + 1, j);
}
private int compare(Object o1, Object o2)
{
int comp = 0;
ChannelItem a = (ChannelItem)o1;
ChannelItem b = (ChannelItem)o2;
switch (sort_criteria)
{
default:
case SORT_BYNAME:
comp = collator.compare(a.getTag(), b.getTag());
break;
case SORT_BYNUM:
comp = b.getUsers() - a.getUsers();
break;
case SORT_BYTOPIC:
comp = collator.compare(a.getTopic(), b.getTopic());
break;
}
return(comp);
}
public int number()
{
return(number);
}
/*
private void readChanServList(String f)
{
this.chanserv = new Vector();
URL u = null;
try
{
u = new URL(eirc.getCodeBase() + f);
}
catch(MalformedURLException e)
{
u = ClassLoader.getSystemResource(f);
}
try
{
BufferedReader br = new BufferedReader(new InputStreamReader(u.openStream()));
String s;
while((s = br.readLine()) != null)
{
MessageFormat m = new MessageFormat("{0}\t{1}");
try
{
Object ob[] = m.parse(s);
if (ob[0] != null)
{
chanserv.addElement(new ChannelItem((String)ob[0], 0, (String)ob[1]));
number_reg++;
}
}
catch (ParseException ex) {}
}
br.close();
}
catch(IOException e)
{
System.out.println("Cannot open " + u);
}
}
*/
public void updateBackground(Container ct, Color cl)
{
ct.setBackground(cl);
Component cp[] = ct.getComponents();
for (int i = 0; i < cp.length; i++)
{
if (cp[i] instanceof Container)
updateBackground((Container)cp[i], cl);
else
if (!(cp[i] instanceof TextField))
cp[i].setBackground(cl);
}
}
public void setBackground(Color c)
{
super.setBackground(c);
label.setBackground(c);
// updateBackground((Container)panel, c);
}
public void setTextBackground(Color c)
{
new_chan.setBackground(c);
users_nbr.setBackground(c);
text_canvas.setBackground(c);
}
public void setSelectedBackground(Color c)
{
text_canvas.setSelectedBackground(c);
}
public void setForeground(Color c)
{
super.setForeground(c);
}
public void setTextForeground(Color c)
{
new_chan.setForeground(c);
users_nbr.setForeground(c);
}
public void setFont(Font f)
{
new_chan.setFont(f);
users_nbr.setFont(f);
text_canvas.setFont(f);
}
protected void visitURL(URL url)
{
eirc.visitURL(url);
}
protected void joinChannel(String name)
{
eirc.joinChannel(name);
}
public void handleHyperlink(String link)
{
if (Channel.isChannel(link))
{
joinChannel(link);
}
else
{
try
{
visitURL(new URL(link));
}
catch (MalformedURLException e) {}
}
}
public void handleNick(String nick)
{
}
public void addText(String s)
{
eirc.cutPaste(s);
}
public void update(Observable o, Object arg)
{
ConfigurationProperties props = (ConfigurationProperties) o;
if (arg == null || arg.equals("list_parameter"))
this.list_parameter = props.getString("list_parameter");
if (arg == null || arg.equals("scroll_speed"))
text_canvas.setMode(props.getInt("scroll_speed"));
}
public void itemStateChanged(ItemEvent ev)
{
Object ob = ev.getSource();
if (ob == byname || ob == bynumber)
{
if (byname.getState())
sort_criteria = SORT_BYNAME;
if (bynumber.getState())
sort_criteria = SORT_BYNUM;
display();
}
}
public void actionPerformed(ActionEvent ev)
{
String ac = ev.getActionCommand();
Object ob = ev.getSource();
if (ob == new_chan)
{
String chan = new_chan.getText();
if (!Channel.isChannel(chan))
chan = "#" + chan;
if (chan.length() > 1)
joinChannel(chan);
}
if (ac.equals("list") || ob == users_nbr)
{
b.setEnabled(false);
listChannels();
}
}
}