/*
 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.Enumeration;
 import java.util.Vector;
 
 
 public class Modes
 {
 	private static Vector modes, prefixes, masks;
 	
 	static
 	{
 		// Define default user modes and prefixes
 	
 		modes = new Vector();
 		prefixes = new Vector();
 		masks = new Vector();
 		 
 		// Each new element must be added from the highest privilege to the smallest
 		
 		modes.addElement("q");
 		modes.addElement("a");
 		modes.addElement("o");
 		modes.addElement("h");
 		modes.addElement("v");
 		prefixes.addElement("~");
 		prefixes.addElement("&");
 		prefixes.addElement("@");
 		prefixes.addElement("%");
 		prefixes.addElement("+");
 		masks.addElement(new Integer(User.OWNER_MASK));
 		masks.addElement(new Integer(User.ADMIN_MASK));
 		masks.addElement(new Integer(User.OP_MASK));
 		masks.addElement(new Integer(User.HALFOP_MASK));
 		masks.addElement(new Integer(User.VOICE_MASK));
 	}
 	
 	/**
 	 * Returns a canonical representation of <code>nick</code>, that is, without the mode character.
 	 *
 	 * @param nick the nick name to canonicalize.
 	 */
 	 
 	public static String canonicalizeNick(String nick)
 	{
 		char ch = nick.charAt(0);
 
 		if (User.NORMAL_MASK == symbolicToMask(ch))
 			return nick;
 		else
 			return nick.substring(1);
 	}
 	
 	public static void parseSupportedPrefixes(String list) throws ParseException
 	{
 		int i = list.indexOf(')');
 		if (i < 0 || !list.startsWith("("))
 			throw new ParseException("Non-standard prefixes string", 0);
 		
 		String modes_list = list.substring(1, i);
 		String prefixes_list = list.substring(i + 1);
 		
 		if (modes_list.length() != prefixes_list.length())
 			throw new ParseException("Prefixes list doesn't match", i + 1);
 		
 		for (i = 0; i < modes_list.length(); i++)
 		{
 			String mode = modes_list.substring(i, i + 1);
 			if (!modes.contains(mode))
 			{
 				// Adding a new prefix
 				modes.insertElementAt(mode, i);
 				prefixes.insertElementAt(prefixes_list.substring(i, i + 1), i);
 				masks.insertElementAt(new Integer(User.EXTENDS_MASK), i);
 			}
 		}
 	}
 
 	/**
 	 * Prepends a symbolic char to <code>nick</code> depending on the <code>mask</code> provided.
 	 *
 	 * @param nick the nick name to uncanonicalize.
 	 * @param mask the user mode mask corresponding to nick.
 	 */
 	 
 	public static String uncanonicalizeNick(String nick, int mask)
 	{
 		return maskToSymbolic(mask).concat(nick);
 	}
 
 
 	public static int symbolicToMask(char symbol)
 	{
 		int index = prefixes.indexOf(String.valueOf(symbol));
 		if (index > -1)
 			return (((Integer)masks.elementAt(index)).intValue());
 		
 		return User.NORMAL_MASK;
 	}
 
 	public static String maskToSymbolic(int mask)
 	{
 		for (int index = 0; index < masks.size(); index++)
 		{
 			int m = ((Integer)masks.elementAt(index)).intValue();
 			if ((m & mask) != 0)
 				return ((String)prefixes.elementAt(index));
 		}
 		
 		return "";
 	}
 
 	public static int alphaToMask(char ch)
 	{
 		int index = modes.indexOf(String.valueOf(ch));
 		if (index > -1)
 			return (((Integer)masks.elementAt(index)).intValue());
 		
 		return User.NORMAL_MASK;
 	}
 
 	public static String maskToAlpha(int mask)
 	{
 		for (int index = 0; index < masks.size(); index++)
 		{
 			int m = ((Integer)masks.elementAt(index)).intValue();
 			if ((m & mask) != 0)
 				return ((String)modes.elementAt(index));
 		}
 
 		return "";
 	}
 }