/*
 * Copyright 2013-2014 Iowa State University. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY IOWA STATE UNIVERSITY ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL IOWA STATE UNIVERSITY OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * The views and conclusions contained in the software and documentation are those
 * of the authors and should not be interpreted as representing official policies,
 * either expressed or implied, of Iowa State University.
 */
import java.io.*;
import java.text.*;
import java.util.*;

/**
 * Generates Figure 4, Section 5.2.
 *
 * @author Robert Dyer (rdyer@iastate.edu)
 */
public class uses {
	private static double files;
	private static double projects;

	private final static HashMap<String, Long> values = new HashMap<>();
	private final static NumberFormat numFormat = NumberFormat.getInstance();

	public static void main(String[] args) throws IOException {
		getCounts();
		getUses();

	    numFormat.setMaximumFractionDigits(2);

		System.out.println("% $Id: uses.java,v 1.1 2013/09/15 19:49:56 rdyer Exp $");
		System.out.println("% DO NOT EDIT - This file automatically generated by section5-2/uses.java");
		System.out.println("\\begin{figure}[ht]");
		System.out.println("\\vspace{-1em}");
		System.out.println("\\centering");
		System.out.println("\\newcolumntype{R}{%");
		System.out.println("    >{\\adjustbox{minipage=5em,angle=35,lap=\\width}\\bgroup}%");
		System.out.println("    l%");
		System.out.println("    <{\\egroup}%");
		System.out.println("}");
		System.out.println("\\newcommand{\\oldtabcolsep}{\\tabcolsep}\\renewcommand{\\tabcolsep}{5pt}");
		System.out.println("\\subfloat{");
		System.out.println("\\rowcolors{2}{white}{gray!10}");
		System.out.println("\\begin{tabular}[t]{|r|c|}");
		System.out.println("\\multicolumn{1}{c}{\\textbf{JLS2}} &");
		System.out.println("\\multicolumn{1}{R}{\\textbf{Assert}} \\\\");
		System.out.println("\\hline");
		printEntries("Assert");
		System.out.println("\\hline");
		System.out.println("\\end{tabular}");
		System.out.println("}");
		System.out.println("~~");

		System.out.println("\\subfloat{");
		System.out.println("\\rowcolors{2}{white}{gray!10}");
		System.out.println("\\begin{tabular}[t]{|r|c|c|c|c|}");
		System.out.println("\\multicolumn{1}{c}{\\textbf{JLS3}} &");
		System.out.println("\\multicolumn{1}{R}{\\textbf{Annotation Declaration}} &");
		System.out.println("\\multicolumn{1}{R}{\\textbf{Annotation Use}} \\\\");
		System.out.println("\\hline");
		printEntries("AnnotDefine", "AnnotUse");
		System.out.println("\\hline");
		System.out.println("\\end{tabular}");
		System.out.println("}");
		System.out.println("");

		System.out.println("\\rowcolors{2}{white}{gray!10}");
		System.out.println("\\begin{tabular}[t]{|r|c|c|c|c|c|c|c|}");
		System.out.println("\\multicolumn{1}{c}{\\textbf{JLS3}} &");
		System.out.println("\\multicolumn{1}{R}{\\textbf{Enhanced For Loop}} &");
		System.out.println("\\multicolumn{1}{R}{\\textbf{Enums}} &");
		System.out.println("\\multicolumn{1}{R}{\\textbf{Generic Variable}} &");
		System.out.println("\\multicolumn{1}{R}{\\textbf{Generic Method}} \\\\");
		System.out.println("\\hline");
		printEntries("EnhancedFor", "Enums", "GenDefField", "GenDefMethod");
		System.out.println("\\hline");
		System.out.println("\\end{tabular}");
		System.out.println("");

		System.out.println("\\rowcolors{2}{white}{gray!10}");
		System.out.println("\\begin{tabular}[t]{|r|c|c|c|c|c|c|c|}");
		System.out.println("\\multicolumn{1}{c}{\\textbf{JLS3}} &");
		System.out.println("\\multicolumn{1}{R}{\\textbf{Generic Type}} &");
		System.out.println("\\multicolumn{1}{R}{\\textbf{Extends Wildcard}} &");
		System.out.println("\\multicolumn{1}{R}{\\textbf{Super Wildcard}} &");
		System.out.println("\\multicolumn{1}{R}{\\textbf{Other Wildcard}} &");
		System.out.println("\\multicolumn{1}{R}{\\textbf{Varargs}} \\\\");
		System.out.println("\\hline");
		printEntries("GenDefType", "GenExtends", "GenSuper", "GenWildcard", "Varargs");
		System.out.println("\\hline");
		System.out.println("\\end{tabular}");
		System.out.println("");

		System.out.println("\\rowcolors{2}{white}{gray!10}");
		System.out.println("\\begin{tabular}[t]{|r|c|c|c|c|c|c|}");
		System.out.println("\\multicolumn{1}{c}{\\textbf{JLS4}} &");
		System.out.println("\\multicolumn{1}{R}{\\textbf{Binary\\\\ Literals}} &");
		System.out.println("\\multicolumn{1}{R}{\\textbf{Diamond}} &");
		System.out.println("\\multicolumn{1}{R}{\\textbf{MultiCatch}} &");
		System.out.println("\\multicolumn{1}{R}{\\textbf{Safe Varargs}} &");
		System.out.println("\\multicolumn{1}{R}{\\textbf{Try with\\\\ Resources}} &");
		System.out.println("\\multicolumn{1}{R}{\\textbf{Underscore Literals}} \\\\");
		System.out.println("\\hline");
		printEntries("BinaryLit", "Diamond", "MultiCatch", "SafeVarargs", "TryResources", "UnderscoreLit");
		System.out.println("\\hline");
		System.out.println("\\end{tabular}");

		System.out.println("\\caption{Java language feature usage by total number of uses, by");
		System.out.println("percent of all files, and by percent of all projects.}");
		System.out.println("\\label{tab:rq1}");
		System.out.println("\\renewcommand{\\tabcolsep}{\\oldtabcolsep}");
		System.out.println("\\end{figure}");
	}

	private static void printEntries(String... args) {
		System.out.print("\\textbf{Uses}");
		for (int i = 0; i < args.length; i++)
			System.out.print(" & " + numFormat.format(values.get("Uses[" + args[i] + "]")));
		System.out.println(" \\\\");

		System.out.print("\\textbf{File}");
		for (int i = 0; i < args.length; i++)
			System.out.print(" & " + numFormat.format(100.0 * values.get("FileUses[" + args[i] + "]") / files) + "\\%");
		System.out.println(" \\\\");

		System.out.print("\\textbf{Project}");
		for (int i = 0; i < args.length; i++)
			System.out.print(" & " + numFormat.format(100.0 * values.get("ProjectUses[" + args[i] + "]") / projects) + "\\%");
		System.out.println(" \\\\");
	}

	private static void getCounts() throws IOException {
		final DataInputStream in = new DataInputStream(new FileInputStream("../section4-2/counts.txt"));
		final BufferedReader br = new BufferedReader(new InputStreamReader(in));

		String strLine;

		while ((strLine = br.readLine()) != null) {
			final String key = strLine.substring(0, strLine.indexOf("["));
			if (key.equals("JavaFiles"))
				files = Long.parseLong(strLine.substring(strLine.indexOf(" = ") + 3));
			else if (key.equals("StudiedProjects"))
				projects = Long.parseLong(strLine.substring(strLine.indexOf(" = ") + 3));
		}

		in.close();
	}

	private static void getUses() throws IOException {
		final DataInputStream in = new DataInputStream(new FileInputStream("uses.txt"));
		final BufferedReader br = new BufferedReader(new InputStreamReader(in));

		String strLine;

		while ((strLine = br.readLine()) != null)
			values.put (strLine.substring(0, strLine.indexOf(" = ")), Long.parseLong(strLine.substring(strLine.indexOf(" = ") + 3)));

		in.close();
	}
}
