import type.lang.*;
import java.util.*;

public class DemoCharFreq
{
	public static void main(String[] args)
	{
		if (args.length == 0)
		{
			IO.println("-----------------------------------------");
			IO.println("usage: java DemoCharFreq file [options]");			
			IO.println("where 'file' is any text file");
			IO.println("(NOTE: map elements are tokens in file)\n");
			IO.println("The following options are supported:\n");
			IO.println("   -u     include uppercase characters"); 
			IO.println("   -l     include lowercase characters"); 
			IO.println("   -d     include digit characters"); 
			IO.println("   -c     convert uppercase to lowercase"); 
			IO.println("   -s     include space character"); 
			IO.println("   -p     include punctuation characters"); 
			IO.println("   -os    output size of map"); 
			IO.println("   -oe    output elements in map"); 
			IO.println("   -osbk  output map, sorted by key"); 
			IO.println("   -osbv  output map, sorted by value"); 
			IO.println("-----------------------------------------");
			System.exit(0);
		}

		UniReader ur = new UniReader(args[0]);

		boolean uOption = false; // uppercase 
		boolean lOption = false; // lowercase
		boolean dOption = false; // digit
		boolean cOption = false; // convert
		boolean sOption = false; // space
		boolean pOption = false; // punctuation
		boolean osOption = false;    // output size of map
		boolean oeOption = false;    // output elements in map
		boolean osbkOption = false;  // output map, sorted by key
		boolean osbvOption = false;  // output map, sorted by value

		for (int i = 1; i < args.length; ++i)
		{
			if (args[i].equals("-u")) uOption = true;
			else if (args[i].equals("-l")) lOption = true;
			else if (args[i].equals("-d")) dOption = true;
			else if (args[i].equals("-c")) cOption = true;
			else if (args[i].equals("-s")) sOption = true;
			else if (args[i].equals("-p")) pOption = true;
			else if (args[i].equals("-os")) osOption = true;
			else if (args[i].equals("-oe")) oeOption = true;
			else if (args[i].equals("-osbk")) osbkOption = true;
			else if (args[i].equals("-osbv")) osbvOption = true;
			else
			{
				IO.println("Unsupported option: " + args[i]);
				System.exit(0);
			}
		}

		TreeMap tm = new TreeMap();
		String s;
		while ((s = ur.readLine()) != null)
		{
			if (cOption)
				s = s.toLowerCase();

			for (int i = 0; i < s.length(); ++i)
			{
				char c = s.charAt(i);

				boolean isPunctuation = false;
				final String PUNCTUATION = "~!@#$%^&*()_+`-={}|[]\\:\";'<>?,./";
				if (PUNCTUATION.indexOf(c) >= 0)
					isPunctuation = true;

				if (uOption && Character.isUpperCase(c) ||
					 lOption && Character.isLowerCase(c) ||
					 dOption && Character.isDigit(c) ||
					 sOption && Character.isSpaceChar(c) ||
					 pOption && isPunctuation)
				{
					Character key = new Character(c);
					if (!tm.containsKey(key))
						tm.put(key, new Integer(1));
					else
					{
						int count = ((Integer)tm.get(key)).intValue();
						tm.put(key, new Integer(count + 1));
					}
				}
			}
		}

		if (osOption)
			IO.println("Size = " + tm.size());

		if (oeOption)
			IO.println("Elements: " + tm);

		if (osbkOption) // output sorted by key
		{
			Iterator it = tm.keySet().iterator();
			while(it.hasNext())
			{	
				Character key = (Character)(it.next());
				Integer value = (Integer)tm.get(key);
				IO.println(key + " " + value);
			}
		}

		if (osbvOption)
		{
			IO.println("Sorry! Not implemented yet!");
		}
	}
}
