/*
 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
 */
 
 package ar.com.jkohen.irc;
 
 import java.text.ParseException;
 import java.util.*;
 
 public class Message
 {
 	protected String prefix;
 	protected boolean from_server;
 	protected String command;
 	protected String [] parameters;
 
 	public Message(String msg) throws ParseException
 	{
 		if (msg.trim().length() == 0)
 			throw new ParseException("Empty message", 0);
 
 		StringTokenizer st = new StringTokenizer(msg, " ");
 		String t;
 
 		if (!st.hasMoreTokens())
 			throw new ParseException("Empty message", 0);
 
 		t = st.nextToken();
 
 		// Let's see if there's a prefix
 		
 		if (t.charAt(0) == ':')
 		{
 			if (t.length() == 1)
 				throw new ParseException("Empty prefix", 1);
 
 			this.prefix = t.substring(1);
 			
 			if(prefix.indexOf('!') < 0 && prefix.indexOf('@') < 0)
 				this.from_server = true;
 			
 			if (!st.hasMoreTokens())
 				throw new ParseException("Command expected (" + msg + ")", 0);
 	
 			t = st.nextToken();
 		}
 		else
 		{
 			this.prefix = "";
 		}
 
 		// Then we should have received the command
 		
 		this.command = t.toUpperCase(Locale.US);
 		if (!st.hasMoreTokens())
 			throw new ParseException("Parameters expected", 0);
 
 		Vector tmp_params = new Vector();
 		st = new StringTokenizer(st.nextToken(""), " ");
 		while (st.hasMoreTokens())
 		{
 			t = st.nextToken();
 			if (t.charAt(0) == ':')
 			{
 				// We found the last parameter, it needs special treatment.
 				break;
 			}
 			tmp_params.addElement(t);
 		}
 
 		// We want to pass the last parameter unparsed, therefore, we can't use the output of StringTokenizer; we have to work with the original message.
 		// Start looking one char past the beginning to avoid finding the prefix marker.
 		// **Fixed for IPv6** Start looking at the beginning of the command.
 		
 		int colon_index = msg.indexOf(" :", msg.indexOf(this.command));
 		if (colon_index != -1)
 	   		tmp_params.addElement(msg.substring(colon_index + 2));
 
 		this.parameters = new String [tmp_params.size()];
 		tmp_params.copyInto(parameters);
 	}
 
 	public Message(String command, String[] parameters)
 	{
 		this("", command, parameters);
 	}
 
 	public Message(String prefix, String command, String[] parameters)
 	{
 		this.prefix = prefix;
 		this.command = command;
 		this.parameters = parameters;
 	}
 
 	public String toString()
 	{
 		String pre = "";
 
 		if (prefix.length() != 0)
 			pre += ":" + prefix + " ";
 
 		return(pre + command + getParametersString() + "\r\n");
 	}
 
 
 	/* Produce as many 512-byte strings as needed to represent the message.
 	 * PREFIX and COMMAND are included in every fragment.
 	 */
 	 
 	public String[] slices()
 	{
 		String pre = "";
 
 		if (prefix.length() != 0)
 			pre += ":" + prefix + " ";
 
 		pre += command;
 
 		String params = getParametersString();
 
 		Vector v = new Vector();
 		
 		// Length is 510 instead of 512 because of the "\r\n" appended later.
 		
 		final int max_slice_len = 510 - pre.length();
 		int i = 0;
 		do
 		{
 			int slice_len = Math.min(max_slice_len, params.length() - i);
 			String slice = params.substring(i, i + slice_len);
 			v.addElement(pre + slice + "\r\n");
 			i += slice_len;
 		}
 		while (i < params.length());
 
 		String[] slices = new String[v.size()];
 		v.copyInto(slices);
 
 		return(slices);
 	}
 
 	public boolean isFromServer()
 	{
 		return(from_server);
 	}
 	
 	public String getPrefix()
 	{
 		return(prefix);
 	}
 
 	public String getCommand()
 	{
 		return(command);
 	}
 
 	public String[] getParameters()
 	{
 		return(parameters);
 	}
 
 	protected String getParametersString()
 	{
 		StringBuffer buf = new StringBuffer();
 
 		if (parameters.length > 0)
 		{
 			for (int i = 0; i < parameters.length - 1; i++)
 			{
 				String s = parameters[i].trim();
 				if (s != null || !s.equals(""))
 					buf.append(' ').append(s);
 			}
 
 			buf.append(" :").append(parameters[parameters.length - 1]);
 		}
 
 		return(buf.toString());
 	}
 }