/*
 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.text.MessageFormat;
 import java.util.Observable;
 import java.util.Observer;
 import ar.com.jkohen.irc.User;
 import ar.com.jkohen.irc.MircMessage;
 import ar.com.jkohen.awt.NickInfo;
 import ar.com.jkohen.util.Resources;
 import ar.com.jkohen.util.ConfigurationProperties;
 
 public abstract class ChatWindow extends OutputWindow implements Observer
 {
 	protected static final String separator = Resources.getString("msg.separator1");
 	protected static final String talkto = Resources.getString("msg.separator2");
 
 	protected static final MessageFormat ME	= new MessageFormat(Resources.getString("msg.me"));
 	protected static final MessageFormat ACTION = new MessageFormat(Resources.getString("msg.action"));
 	protected static final MessageFormat PRIVMSG = new MessageFormat(Resources.getString("msg.privmsg"));
 	protected static final MessageFormat MY_NOTICE = new MessageFormat(Resources.getString("msg.my_notice"));
 	protected static final MessageFormat MY_ACTION = new MessageFormat(Resources.getString("msg.my_action"));
 	protected static final MessageFormat OP_PRIVMSG = new MessageFormat(Resources.getString("msg.op"));
 	protected static final MessageFormat HOP_PRIVMSG = new MessageFormat(Resources.getString("msg.hop"));
 	protected static final MessageFormat VOICE_PRIVMSG = new MessageFormat(Resources.getString("msg.voice"));
 	protected static final MessageFormat ADMIN_PRIVMSG = new MessageFormat(Resources.getString("msg.admin"));
 	protected static final MessageFormat OWNER_PRIVMSG = new MessageFormat(Resources.getString("msg.owner"));
 	protected static final MessageFormat MALE_PRIVMSG = new MessageFormat(Resources.getString("msg.male"));
 	protected static final MessageFormat FEMALE_PRIVMSG	= new MessageFormat(Resources.getString("msg.female"));
 	protected static final MessageFormat UNKNOWN_PRIVMSG = new MessageFormat(Resources.getString("msg.unknown"));
 
 	public ChatWindow(String title)
 	{
 		super(title);
 	}
 
 	public void printAction(String s, String whom)
 	{
  		s = highlightNick(s);
 		
 		Object [] o = { getDate(), whom, s };
 		text_canvas.appendNickInfo(ACTION.format(o), hyperlinks, whom);
 
 //		postTextEvent();
 	}
 
 	public void printMyAction(String s)
 	{
 		Object [] o = { getDate(), getNick(), s };
 		text_canvas.append(MY_ACTION.format(o));
 
 		postTextEvent();
 	}
 
 
 	public void printInfo(String s)
 	{
 		s = highlightNick(s);
 		
 		Object [] o = { getDate(), s };
 		text_canvas.append(INFO.format(o));
 	}
 
 	// Channel window message.
 
 	public void printPrivmsg(String s, String whom, User u)
 	{
 		s = highlightNick(s);
 
 		Object [] o = { getDate(), whom, separator, s };
 		MessageFormat mf = getMessageFormat(whom);
 
 		if (u != null)
 		{
 			if (u.isVoiced())
 				mf = VOICE_PRIVMSG;
 			if (u.isHalfOp())
 				mf = HOP_PRIVMSG;
 			if (u.isOp())
 				mf = OP_PRIVMSG;
 			if (u.isAdmin())
 				mf = ADMIN_PRIVMSG;
 			if (u.isOwner())
 				mf = OWNER_PRIVMSG;
 		}
 
 		text_canvas.appendNickInfo(mf.format(o), hyperlinks, whom);
 
 //		postTextEvent();
 	}
 
 	// Private window message.
 	
 	public void printPrivmsg(String s, String whom)
 	{
 		Object [] o = { getDate(), whom, separator, s };
 		MessageFormat mf = getMessageFormat(whom);
 
 		text_canvas.appendNickInfo(mf.format(o), hyperlinks, whom);
 
 		postTextEvent();
 	}
 
 	public void printMyPrivmsg(String s)
 	{
 		Object my_nick[] = { getNick() };
 	
 		String formatted_nick = ME.format(my_nick);
 		
 		Object o[] = { getDate(), formatted_nick, separator, s };
 		MessageFormat mf = getMessageFormat(getNick());
 		
 		text_canvas.appendNickInfo(mf.format(o), hyperlinks, getNick());
 //		postTextEvent();
 	}
 	
 	public void printMyPrivmsg(String s, User u)
 	{
 		Object my_nick[] = { getNick() };
 	
 		String formatted_nick = ME.format(my_nick);
 		
 		Object o[] = { getDate(), formatted_nick, separator, s };
 		MessageFormat mf = getMessageFormat(getNick());
 
 		if (u != null)
 		{
 			if (u.isVoiced())
 				mf =  VOICE_PRIVMSG;
 			if (u.isHalfOp())
 				mf =  HOP_PRIVMSG;
 			if (u.isOp())
 				mf =  OP_PRIVMSG;
 			if (u.isAdmin())
 				mf =  ADMIN_PRIVMSG;
 			if (u.isOwner())
 				mf =  OWNER_PRIVMSG;
 		}
 
 		text_canvas.appendNickInfo(mf.format(o), hyperlinks, getNick());
 //		postTextEvent();
 	}
 
 	public void printMyNotice(String s)
 	{
 		Object o[] = { getDate(), getNick(), s };
 		if (hyperlinks)
 			text_canvas.append(MY_NOTICE.format(o));
 		else
 			text_canvas.appendNoUrls(MY_NOTICE.format(o));
 
 //		postTextEvent();
 	}
 	
 	public void update(Observable o, Object arg)
 	{
 		ConfigurationProperties props = (ConfigurationProperties)o;
 
 //		if (arg == null || arg.equals("prefix_own"))
 //			this.prefix_own = props.getBoolean("prefix_own");
 			
 		if (arg == null || arg.equals("nolinks"))
 			this.hyperlinks = !props.getBoolean("nolinks");
 			
 		if (arg == null || arg.equals("date_format"))
 			setDateFormat(props.getInt("date_format"));
 	}
 
 	public MessageFormat getMessageFormat(String nick)
 	{
 		MessageFormat mf;
 	
    		switch (NickInfo.getSex(nick))
    		{
    		// FIXME: there could be a law prohibiting this.
    		case NickInfo.SEX_MALE:
 			mf = MALE_PRIVMSG;
 			break;
 		case NickInfo.SEX_FEMALE:
 			mf = FEMALE_PRIVMSG;
 			break;
    		default:
 			mf = UNKNOWN_PRIVMSG;
 			break;
    		}
    		
 		return(mf);
 	}
 	
 	public String highlightNick(String s)
 	{
 		String whom = getNick();
 		int i = s.toLowerCase().indexOf(whom.toLowerCase());
 		if (i >= 0)
 		{
 	   		String before_nick = "";
 	   		String after_nick = "";
 	   		char char_before = ' ';
 	   		char char_after = ' ';
 			
 			if (i > 0)
 				before_nick = s.substring(0, i);
 			
 			if (i + whom.length() < s.length())
 				after_nick = s.substring(i + whom.length());
 				
 			String before_filter = MircMessage.filterMircAttributes(before_nick);
 			if (before_filter.length() > 0)
 				char_before = before_filter.charAt(before_filter.length() - 1);
 			
 			String after_filter = MircMessage.filterMircAttributes(after_nick);
 			if (after_filter.length() > 0)
 				char_after = after_filter.charAt(0);
 			
 			if (!Character.isLetterOrDigit(char_before) && !Character.isLetterOrDigit(char_after))
 			{
 				Object nick[] = { whom };
 				String formatted_nick = ME.format(nick);
 			
 				s = before_nick + formatted_nick + after_nick;
 				
 				bell();
 				postTextEvent();
 			}
 		}
 		return(s);
 	}
 	
 	/* Returns the user's current nick */
 	protected abstract String getNick();
 	
 	/* Sound alert */
 	protected abstract void bell();	
 }