/*
 * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - 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.
 *
 *   - Neither the name of Oracle nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER 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.
 */

/**
 * XMLHTMLReporter.java
 *
 * Generates HTML reports from XML results
 *
 * @author Rakesh Menon
 */

package j2dbench.report;

import java.io.*;
import java.util.*;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;

public class XMLHTMLReporter {

    /**
     * Flag to indicate - Generate new report or append to existing report
     */
    private static final int HTMLGEN_FILE_NEW = 1;
    private static final int HTMLGEN_FILE_UPDATE = 2;

    /**
     * Path to results directory where all results are stored
     */
    public static String resultsDir = ".";

    /**
     * Holds the groups and corresponding group-display-names
     */
    public static List groups = new ArrayList();
    public static Map groupNames = new HashMap();

    /**
     * Level at which tests are grouped to be displayed in summary
     */
    public static int LEVEL = 2;

    /**
     * Color -> Better, Same, Worse
     */
    private static final String[] color = {"#99FF99", "#CCFFFF", "#FFCC00"};

    /**
     * String for holding base-build and target-build version
     */
    private static String baseBuild = "";
    private static String targetBuild = "";

    private static final DecimalFormat decimalFormat =
        new DecimalFormat("0.##");
    private static final SimpleDateFormat dateFormat =
        new SimpleDateFormat("EEE, MMM d, yyyy G 'at' HH:mm:ss z");

    public static void setGroupLevel(int level) {
        XMLHTMLReporter.LEVEL = level;
    }

    /**
     * Add Test Group to the list
     */
    private static void addGroup(String testName) {

        String testNameSplit[] = testName.replace('.', '_').split("_");
        String group = testNameSplit[0];
        for(int i=1; i<LEVEL; i++) {
            group = group + "." + testNameSplit[i];
        }

        if( ! groups.contains(group)) {
            groups.add(group);
            groupNames.put(group, getDisplayGroupName(group));
        }
    }

    /**
     * Generate a Display Name for this group
     */
    private static String getDisplayGroupName(String group) {

        String groupSplit[] = group.replace('.', '_').split("_");

        StringBuffer groupName = new StringBuffer();
        String tempName = null;

        for(int i=0; i<groupSplit.length; i++) {
            tempName = groupSplit[i].substring(0, 1).toUpperCase() +
                groupSplit[i].substring(1);
            if(i == 0) {
                groupName.append(tempName);
            } else {
                groupName.append(" " + tempName);
            }
        }

        return groupName.toString();
    }

    /**
     * Get the group to which this testcase belongs
     */
    private static String getGroup(String testName) {

        String testNameSplit[] = testName.replace('.', '_').split("_");
        String group = testNameSplit[0];
        for(int i=1; i<LEVEL; i++) {
            group = group + "." + testNameSplit[i];
        }

        return group;
    }

    /**
     * Opens a File and returns a PrintWriter instance based on new/update
     * option specified in argument.
     */
    private static PrintWriter openFile(String name, int nSwitch) {

        FileOutputStream file = null;
        OutputStreamWriter writer = null;

        try {
            switch (nSwitch) {
                case 1: // HTMLGEN_FILE_NEW
                    file = new FileOutputStream(name, false);
                    break;
                case 2: // HTMLGEN_FILE_UPDATE
                    file = new FileOutputStream(name, true);
                    break;
            }
            writer = new OutputStreamWriter(file);
        } catch (IOException ee) {
            System.out.println("Error opening file: " + ee);
            System.exit(1);
        }

        return new PrintWriter(new BufferedWriter(writer));
    }

    /**
     * Generate an HTML report based on the XML results file passed -
     * J2DBench_Results.html
     */
    public static void generateReport(String resultsDir, String xmlFileName) {

        try {

            String strhtml = null;
            String strstr = null;
            String[] tempstr2 = new String[2];
            String[] tempstr = new String[2];

            J2DAnalyzer.readResults(xmlFileName);
            J2DAnalyzer.SingleResultSetHolder srsh =
                (J2DAnalyzer.SingleResultSetHolder)
                J2DAnalyzer.results.elementAt(0);
            Enumeration enum_ = srsh.getKeyEnumeration();
            Vector keyvector = new Vector();
            while (enum_.hasMoreElements()) {
                keyvector.add(enum_.nextElement());
            }
            String keys[] = new String[keyvector.size()];
            keyvector.copyInto(keys);
            J2DAnalyzer.sort(keys);

            File reportFile = new File(resultsDir, "J2DBench_Results.html");
            PrintWriter writer =
                openFile(reportFile.getAbsolutePath(), HTMLGEN_FILE_NEW);

            writer.println("<html><body bgcolor=\"#ffffff\"><hr size=\"1\">");
            writer.println("<center><h2>J2DBench2 - Report</h2>");
            writer.println("</center><hr size=\"1\"><br>");
            writer.println("<table cols=\"2\" cellspacing=\"2\" " +
                           "cellpadding=\"5\" " +
                           "border=\"0\" width=\"80%\">");
            writer.println("<tr><td bgcolor=\"#CCCCFF\" colspan=\"2\">" +
                           "<b>Build Details</b></td></tr>");
            writer.println("<tr>");
            writer.println("<td bgcolor=\"#f0f0f0\">Description</td>");
            writer.println("<td>" + srsh.getDescription() + "</td>");
            writer.println("</tr>");
            writer.println("<tr><td bgcolor=\"#f0f0f0\">From Date</td>");
            writer.println("<td>" +
                           dateFormat.format(new Date(srsh.getStartTime())) +
                           "</td></tr>");
            writer.println("<tr><td bgcolor=\"#f0f0f0\">To Date</td>");
            writer.println("<td>" +
                           dateFormat.format(new Date(srsh.getEndTime())) +
                           "</td></tr>");
            writer.flush();

            //System Properties
            writer.println("<tr><td bgcolor=\"#CCCCFF\"><b>System Property</b>"+
                           "</td><td bgcolor=\"#CCCCFF\">" +
                           "<b>Value</b></td></tr>");
            String key = null;
            String value = null;
            Map sysProps = srsh.getProperties();
            Iterator iter = sysProps.keySet().iterator();
            while(iter.hasNext()) {
                key = iter.next().toString();
                value = sysProps.get(key).toString();
                writer.println("<tr><td bgcolor=\"#f0f0f0\">" +
                               key + "</td><td>" + value + "&nbsp;</td></tr>");
            }
            writer.flush();

            writer.println("</table>");
            writer.println("<br>");
            writer.println("<hr size=\"1\">");
            writer.println("<br>");

            writer.println("<table cellspacing=\"0\" " +
                           "cellpadding=\"3\" border=\"1\" width=\"80%\">");
            writer.println("<tr>");
            writer.println("<td bgcolor=\"#CCCCFF\" align=\"center\">" +
                           "<b>Num Reps</b></td>");
            writer.println("<td bgcolor=\"#CCCCFF\" align=\"center\">" +
                           "<b>Num Units</b></td>");
            writer.println("<td bgcolor=\"#CCCCFF\" align=\"center\">" +
                           "<b>Name</b></td>");
            writer.println("<td bgcolor=\"#CCCCFF\" align=\"center\">" +
                           "<b>Options</b></td>");
            writer.println("<td bgcolor=\"#CCCCFF\" align=\"center\">" +
                           "<b>Score</b></td>");
            writer.println("</tr>");
            writer.flush();

            for (int k = 0; k < keys.length; k++) {

                J2DAnalyzer.ResultHolder testResult =
                    srsh.getResultByKey(keys[k]);

                writer.println("<tr>");
                writer.println("<td>" + testResult.getReps() + "</td>");
                writer.println("<td>" + testResult.getUnits() + "</td>");
                writer.println("<td>" + testResult.getName() + "</td>");
                writer.println("<td valign=\"center\"><ul>");
                Map map = testResult.getOptions();
                iter = map.keySet().iterator();
                while(iter.hasNext()) {
                    key = iter.next().toString();
                    value = map.get(key).toString();
                    writer.println("<li>" + key + " = " + value + "</li>");
                }
                writer.println("</ul></td>");
                writer.println("<td valign=\"center\">" +
                               decimalFormat.format(testResult.getScore()) +
                               "</td>");
                writer.println("</tr>");
            }
            writer.flush();

            writer.println("</table>");

            writer.println("<br><hr WIDTH=\"100%\" size=\"1\">");
            writer.println("</p><hr WIDTH=\"100%\" size=\"1\"></body></html>");

            writer.flush();
            writer.close();
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Generate the reports from the base & target result XML
     */
    public static void generateComparisonReport(String resultsDir,
                                                String baseXMLFileName,
                                                String targetXMLFileName) {

        XMLHTMLReporter.resultsDir = resultsDir;

        //Get Base XML File ResultSetHolder
        J2DAnalyzer.readResults(baseXMLFileName);
        J2DAnalyzer.SingleResultSetHolder baseSRSH =
            (J2DAnalyzer.SingleResultSetHolder) J2DAnalyzer.results.elementAt(0);
        Enumeration baseEnum_ = baseSRSH.getKeyEnumeration();
        Vector baseKeyvector = new Vector();
        while (baseEnum_.hasMoreElements()) {
            baseKeyvector.add(baseEnum_.nextElement());
        }
        String baseKeys[] = new String[baseKeyvector.size()];
        baseKeyvector.copyInto(baseKeys);
        J2DAnalyzer.sort(baseKeys);

        //Get Target XML File ResultSetHolder
        J2DAnalyzer.readResults(targetXMLFileName);
        J2DAnalyzer.SingleResultSetHolder targetSRSH =
            (J2DAnalyzer.SingleResultSetHolder)
                J2DAnalyzer.results.elementAt(1);
        Enumeration targetEnum_ = baseSRSH.getKeyEnumeration();
        Vector targetKeyvector = new Vector();
        while (targetEnum_.hasMoreElements()) {
            targetKeyvector.add(targetEnum_.nextElement());
        }
        String targetKeys[] = new String[targetKeyvector.size()];
        targetKeyvector.copyInto(targetKeys);
        J2DAnalyzer.sort(targetKeys);

        baseBuild = (String)baseSRSH.getProperties().get("java.vm.version");
        targetBuild = (String)targetSRSH.getProperties().get("java.vm.version");
        generateSysPropsReport(targetSRSH);

        File reportFile = new File(resultsDir, "J2DBench_Complete_Report.html");
        PrintWriter writer = openFile(reportFile.getAbsolutePath(),
                                      HTMLGEN_FILE_NEW);

        String header = getHeader(baseSRSH, targetSRSH,
                                  "J2DBench - Complete Report",
                                  "System_Properties.html");
        writer.println(header);
        writer.flush();

        StringBuffer startTags = new StringBuffer();
        startTags.append("<tr>");
        startTags.append("<td bgcolor=\"#CCCCFF\" align=\"center\">" +
                         "<b>Num Reps</b></td>");
        startTags.append("<td bgcolor=\"#CCCCFF\" align=\"center\">" +
                         "<b>Num Units</b></td>");
        startTags.append("<td bgcolor=\"#CCCCFF\" align=\"center\">" +
                         "<b>Name</b></td>");
        startTags.append("<td bgcolor=\"#CCCCFF\" align=\"center\">" +
                         "<b>Options</b></td>");
        startTags.append("<td bgcolor=\"#CCCCFF\" align=\"center\">" +
                         "<b>" + baseBuild + " Score</b></td>");
        startTags.append("<td bgcolor=\"#CCCCFF\" align=\"center\"><b>" +
                         targetBuild + " Score</b></td>");
        startTags.append("<td bgcolor=\"#CCCCFF\" align=\"center\">" +
                         "<b>% Speedup</b></td>");
        startTags.append("</tr>");

        StringBuffer worseResultTags = new StringBuffer(startTags.toString());
        StringBuffer sameResultTags = new StringBuffer(startTags.toString());
        StringBuffer betterResultTags = new StringBuffer(startTags.toString());

        Map consolBaseRes = new HashMap();
        Map consolTargetResult = new HashMap();

        Map testCaseBaseResult = new HashMap();
        Map testCaseResultCount = new HashMap();
        Map testCaseTargetResult = new HashMap();

        for (int k = 0; k < targetKeys.length; k++) {

            J2DAnalyzer.ResultHolder baseTCR =
                baseSRSH.getResultByKey(targetKeys[k]);
            J2DAnalyzer.ResultHolder targetTCR =
                targetSRSH.getResultByKey(targetKeys[k]);

            Object curTestCountObj = testCaseResultCount.get(baseTCR.getName());
            int curTestCount = 0;
            if(curTestCountObj != null) {
                curTestCount = ((Integer) curTestCountObj).intValue();
            }
            curTestCount++;
            testCaseBaseResult.put(baseTCR.getName() + "_" +
                                   (curTestCount - 1), baseTCR);
            testCaseTargetResult.put(targetTCR.getName() + "_" +
                                     (curTestCount - 1), targetTCR);
            testCaseResultCount.put(baseTCR.getName(),
                                    new Integer(curTestCount));

            /******************************************************************
             * Add the Test to Group List
             ******************************************************************/
            addGroup(baseTCR.getName());

            double baseScore = baseTCR.getScore();
            double targetScore = targetTCR.getScore();

            int selColorIndex = selectColor(baseScore, targetScore);

            StringBuffer tagBuffer = new StringBuffer();

            tagBuffer.append("<tr bgcolor=\""+ color[selColorIndex] + "\">");
            tagBuffer.append("<td align=\"center\">" + baseTCR.getScore() +
                             "</td>");
            tagBuffer.append("<td align=\"center\">" + baseTCR.getUnits() +
                             "</td>");
            tagBuffer.append("<td align=\"center\">" + baseTCR.getName() +
                             "</td>");
            tagBuffer.append("<td valign=\"center\"><ul>");
            Map map = baseTCR.getOptions();
            Iterator iter = map.keySet().iterator();
            while(iter.hasNext()) {
                Object key = iter.next().toString();
                Object value = map.get(key).toString();
                tagBuffer.append("<li>" + key + " = " + value + "</li>");
            }
            tagBuffer.append("</ul></td>");
            tagBuffer.append("<td valign=\"center\" align=\"center\">" +
                             decimalFormat.format(baseTCR.getScore()) +
                             "</td>");
            tagBuffer.append("<td valign=\"center\" align=\"center\">" +
                             decimalFormat.format(targetTCR.getScore()) +
                             "</td>");
            tagBuffer.append("<td valign=\"center\" align=\"center\">" +
                             decimalFormat.format(
                                 calculateSpeedupPercentage(
                                     baseTCR.getScore(),
                                     targetTCR.getScore())) + "</td>");
            tagBuffer.append("</tr>");

            switch(selColorIndex) {
                case 0:
                    betterResultTags.append(tagBuffer.toString());
                    break;
                case 1:
                    sameResultTags.append(tagBuffer.toString());
                    break;
                case 2:
                    worseResultTags.append(tagBuffer.toString());
                    break;
            }

            Object curTotalScoreObj = consolBaseRes.get(baseTCR.getName());
            double curTotalScore = 0;
            if(curTotalScoreObj != null) {
                curTotalScore = ((Double) curTotalScoreObj).doubleValue();
            }
            curTotalScore = curTotalScore + baseTCR.getScore();
            consolBaseRes.put(baseTCR.getName(), new Double(curTotalScore));

            curTotalScoreObj = consolTargetResult.get(targetTCR.getName());
            curTotalScore = 0;
            if(curTotalScoreObj != null) {
                curTotalScore = ((Double) curTotalScoreObj).doubleValue();
            }
            curTotalScore = curTotalScore + targetTCR.getScore();
            consolTargetResult.put(targetTCR.getName(),
                                   new Double(curTotalScore));
        }

        writer.println("<br><hr WIDTH=\"100%\" size=\"1\">");
        writer.println("<A NAME=\"results\"></A><H3>Results:</H3>");

        writer.println("<table cellspacing=\"0\" " +
                         "cellpadding=\"3\" border=\"1\" width=\"80%\">");

        writer.println("<tr><td colspan=\"7\" bgcolor=\"#f0f0f0\">" +
                       "<font size=\"+1\">Tests which run BETTER on target" +
                       "</font></td></tr>");
        writer.println(betterResultTags.toString());
        writer.flush();

        writer.println("<tr><td colspan=\"7\">&nbsp;<br>&nbsp;</td></tr>");
        writer.println("<tr><td colspan=\"7\" bgcolor=\"#f0f0f0\">" +
                       "<font size=\"+1\">Tests which run " +
                       "SAME on target</font></td></tr>");
        writer.println(sameResultTags.toString());
        writer.flush();

        writer.println("<tr><td colspan=\"7\">&nbsp;<br>&nbsp;</td></tr>");
        writer.println("<tr><td colspan=\"7\" bgcolor=\"#f0f0f0\">" +
                       "<font size=\"+1\">Tests which run WORSE on target" +
                       "</font></td></tr>");
        writer.println(worseResultTags.toString());
        writer.flush();

        writer.println("</table>");

        writer.println(getFooter());
        writer.flush();

        writer.close();

        generateTestCaseSummaryReport(baseSRSH, targetSRSH,
                                      consolBaseRes, consolTargetResult,
                                      testCaseBaseResult,
                                      testCaseResultCount,
                                      testCaseTargetResult);

        generateGroupSummaryReport(baseSRSH, targetSRSH,
                                   consolBaseRes, consolTargetResult,
                                   testCaseBaseResult,
                                   testCaseResultCount, testCaseTargetResult);
    }

    /**
     * Generate Group-Summary report - Summary_Report.html
     */
    private static void generateGroupSummaryReport(
        J2DAnalyzer.SingleResultSetHolder baseSRSH,
        J2DAnalyzer.SingleResultSetHolder targetSRSH,
        Map consolBaseResult,
        Map consolTargetResult,
        Map testCaseBaseResult,
        Map testCaseResultCount,
        Map testCaseTargetResult) {

        File groupSummaryReportFile =
            new File(resultsDir, "Summary_Report.html");
        PrintWriter writer =
            openFile(groupSummaryReportFile.getAbsolutePath(),
                     HTMLGEN_FILE_NEW);

        String header = getHeader(baseSRSH, targetSRSH,
                                  "J2DBench - Summary Report",
                                  "System_Properties.html");
        writer.println(header);
        writer.flush();

        writer.println("<br><hr size=\"1\">");

        Map baseValuesMap = new HashMap();
        Map targetValuesMap = new HashMap();

        String tempGroup = null;
        for(int i=0; i<groups.size(); i++) {
            tempGroup = groups.get(i).toString();
            baseValuesMap.put(tempGroup, new Double(0));
            targetValuesMap.put(tempGroup, new Double(0));
        }


        Object key = null;
        double baseValue = 0, targetValue = 0;
        Iterator resultsIter = consolBaseResult.keySet().iterator();

        while(resultsIter.hasNext()) {

            key = resultsIter.next();

            baseValue = ((Double) consolBaseResult.get(key)).doubleValue();
            targetValue = ((Double) consolTargetResult.get(key)).doubleValue();

            tempGroup = getGroup(key.toString());

            Object curTotalScoreObj = null;
            double curTotalScore = 0;

            curTotalScoreObj = baseValuesMap.get(tempGroup);
            if(curTotalScoreObj != null) {
                curTotalScore = ((Double) curTotalScoreObj).doubleValue();
            }
            curTotalScore = curTotalScore + baseValue;
            baseValuesMap.put(tempGroup, new Double(curTotalScore));

            curTotalScore = 0;
            curTotalScoreObj = targetValuesMap.get(tempGroup);
            if(curTotalScoreObj != null) {
                curTotalScore = ((Double) curTotalScoreObj).doubleValue();
            }
            curTotalScore = curTotalScore + targetValue;
            targetValuesMap.put(tempGroup, new Double(curTotalScore));
        }

        writer.println("<A NAME=\"results_summary\"></A>" +
                       "<H3>Results Summary:</H3>");
        writer.println("<table cols=\"4\" cellspacing=\"0\" " +
                       "cellpadding=\"3\" border=\"1\" width=\"80%\">");
        writer.println("<TR BGCOLOR=\"#CCCCFF\">");
        writer.println("<TD><B>Testcase</B></TD>");
        writer.println("<TD align=\"center\"><B>Score for " + baseBuild +
                       "</B></TD>");
        writer.println("<TD align=\"center\"><B>Score for " + targetBuild +
                       "</B></TD>");
        writer.println("<TD align=\"center\"><B>% Speedup</TD>");
        writer.println("</TR>");

        StringBuffer betterResultTags = new StringBuffer();
        StringBuffer sameResultTags = new StringBuffer();
        StringBuffer worseResultTags = new StringBuffer();

        resultsIter = baseValuesMap.keySet().iterator();

        double speedup = 0;

        while(resultsIter.hasNext()) {

            key = resultsIter.next();

            baseValue = ((Double) baseValuesMap.get(key)).doubleValue();
            targetValue = ((Double) targetValuesMap.get(key)).doubleValue();
            speedup = calculateSpeedupPercentage(baseValue, targetValue);

            int selColorIndex = selectColor(baseValue, targetValue);

            String tcFileName = key.toString().replace('.', '_');
            tcFileName = tcFileName.toLowerCase() + ".html";

            switch(selColorIndex) {
                case 0:
                    betterResultTags.append("<tr bgcolor=\""+
                                            color[selColorIndex] + "\">");
                    betterResultTags.append("<td><a href=" +
                        "\"Testcase_Summary_Report.html#status_" + key +
                                            "\">" + groupNames.get(key) +
                                            "</a></td>");
                    betterResultTags.append("<td align=\"center\">" +
                                            decimalFormat.format(baseValue) +
                                            "</td>");
                    betterResultTags.append("<td align=\"center\">" +
                                            decimalFormat.format(targetValue) +
                                            "</td>");
                    betterResultTags.append("<td align=\"center\">" +
                                            decimalFormat.format(speedup) +
                                            "</td>");
                    betterResultTags.append("</tr>");
                    break;
                case 1:
                    sameResultTags.append("<tr bgcolor=\""+
                                          color[selColorIndex] + "\">");
                    sameResultTags.append("<td>" +
                        "<a href=\"Testcase_Summary_Report.html#status_" + key +
                                          "\">" + groupNames.get(key) +
                                          "</a></td>");
                    sameResultTags.append("<td align=\"center\">" +
                                          decimalFormat.format(baseValue) +
                                          "</td>");
                    sameResultTags.append("<td align=\"center\">" +
                                          decimalFormat.format(targetValue) +
                                          "</td>");
                    sameResultTags.append("<td align=\"center\">" +
                                          decimalFormat.format(speedup) +
                                          "</td>");
                    sameResultTags.append("</tr>");
                    break;
                case 2:
                    worseResultTags.append("<tr bgcolor=\""+
                                           color[selColorIndex] + "\">");
                    worseResultTags.append("<td>" +
                        "<a href=\"Testcase_Summary_Report.html#status_" + key +
                                           "\">" + groupNames.get(key) +
                                           "</a></td>");
                    worseResultTags.append("<td align=\"center\">" +
                                           decimalFormat.format(baseValue) +
                                           "</td>");
                    worseResultTags.append("<td align=\"center\">" +
                                           decimalFormat.format(targetValue) +
                                           "</td>");
                    worseResultTags.append("<td align=\"center\">" +
                                           decimalFormat.format(speedup) +
                                           "</td>");
                    worseResultTags.append("</tr>");
                    break;
            }
        }

        writer.println(betterResultTags.toString());
        writer.flush();

        writer.println(sameResultTags.toString());
        writer.flush();

        writer.println(worseResultTags.toString());
        writer.flush();

        writer.println("</table>");

        writer.println(getFooter());
        writer.flush();
        writer.close();
    }

    /**
     * Generate Testcase Summary Report - Testcase_Summary_Report.html
     */
    private static void generateTestCaseSummaryReport(
        J2DAnalyzer.SingleResultSetHolder baseSRSH,
        J2DAnalyzer.SingleResultSetHolder targetSRSH,
        Map consolBaseResult,
        Map consolTargetResult,
        Map testCaseBaseResult,
        Map testCaseResultCount,
        Map testCaseTargetResult) {

        File tcSummaryReportFile =
            new File(resultsDir, "Testcase_Summary_Report.html");
        PrintWriter writer =
            openFile(tcSummaryReportFile.getAbsolutePath(), HTMLGEN_FILE_NEW);

        String header = getHeader(baseSRSH, targetSRSH,
                                  "J2DBench - Testcase Summary Report",
                                  "System_Properties.html");
        writer.println(header);
        writer.flush();

        StringBuffer testResultsStartBuffer = new StringBuffer();
        testResultsStartBuffer.append("<TR BGCOLOR=\"#CCCCFF\">");
        testResultsStartBuffer.append("<TD><B>Testcase</B></TD>");
        testResultsStartBuffer.append("<TD align=\"center\"><B>Score for " +
                                      baseBuild + "</B></TD>");
        testResultsStartBuffer.append("<TD align=\"center\"><B>Score for " +
                                     targetBuild + "</B></TD>");
        testResultsStartBuffer.append("<TD align=\"center\"><B>% Speedup</TD>");
        testResultsStartBuffer.append("</TR>");

        StringBuffer testResultsScoreBuffer = new StringBuffer();
        testResultsScoreBuffer.append("<table cols=\"4\" cellspacing=\"0\" " +
                                      "cellpadding=\"3\" border=\"1\" " +
                                      "width=\"80%\">");

        StringBuffer betterResultTags = new StringBuffer();
        StringBuffer sameResultTags = new StringBuffer();
        StringBuffer worseResultTags = new StringBuffer();

        Double baseValue = null, targetValue = null;

        String curGroupName = null;
        String curTestName = null;

        Object[] groupNameArray = groups.toArray();
        Arrays.sort(groupNameArray);

        Object[] testCaseList = consolBaseResult.keySet().toArray();
        Arrays.sort(testCaseList);

        writer.println("<br><hr size=\"1\"><br>");
        writer.println("<A NAME=\"status\"></A><H3>Status:</H3>");

        writer.println("<table cellspacing=\"0\" " +
                       "cellpadding=\"3\" border=\"1\" width=\"80%\">");

        for(int j=0; j<groupNameArray.length; j++) {

            if(j != 0) {
                testResultsScoreBuffer.append("<tr><td colspan=\"4\">&nbsp;" +
                                              "<br>&nbsp;</td></tr>");
                writer.println("<tr><td colspan=\"5\">&nbsp;<br>&nbsp;" +
                               "</td></tr>");
            }

            curGroupName = groupNameArray[j].toString();

            writer.println("<tr><td colspan=\"5\" valign=\"center\" " +
                           "bgcolor=\"#f0f0f0\">" +
                           "<A NAME=\"status_" + curGroupName + "\"></A>" +
                           "<font size=\"+1\">Status - " +
                           groupNames.get(curGroupName) + "</font></td></tr>");
            writer.println("<tr>");
            writer.println("<td bgcolor=\"#CCCCFF\"><b>Tests " +
                           "Performance</b></td>");
            writer.println("<td bgcolor=\"#CCCCFF\" align=\"center\">" +
                           "<b>BETTER (Num / %)</b></td>");
            writer.println("<td bgcolor=\"#CCCCFF\" align=\"center\">" +
                           "<b>SAME (Num / %)</b></td>");
            writer.println("<td bgcolor=\"#CCCCFF\" align=\"center\">" +
                           "<b>WORSE (Num / %)</b></td>");
            writer.println("<td bgcolor=\"#CCCCFF\" align=\"center\">" +
                           "<b>Total</b></td>");
            writer.println("</tr>");
            writer.flush();

            testResultsScoreBuffer.append("<tr><td colspan=\"4\" " +
                                          "valign=\"center\" " +
                                          "bgcolor=\"#f0f0f0\">" +
                                          "<A NAME=\"test_result_" +
                                          curGroupName +
                                          "\"></A><font size=\"+1\">" +
                                          "Test Results - " +
                                          groupNames.get(curGroupName) +
                                          "</font></td></tr>");
            testResultsScoreBuffer.append(testResultsStartBuffer);

            String tableTags[] = null;

            for(int i=0; i<testCaseList.length; i++) {

                curTestName = testCaseList[i].toString();

                if(curTestName.startsWith(curGroupName)) {

                    tableTags = generateTestCaseReport(
                        curGroupName, curTestName, baseSRSH, targetSRSH,
                        testCaseResultCount, testCaseBaseResult,
                        testCaseTargetResult);

                    writer.println(tableTags[0]);
                    writer.flush();

                    testResultsScoreBuffer.append(tableTags[1]);
                }
            }
        }

        testResultsScoreBuffer.append("</table>");
        writer.println("</table>");

        writer.println("<br><hr size=\"1\"><br>");
        writer.println("<A NAME=\"test_results\"></A><H3>Test Results:</H3>");
        writer.println(testResultsScoreBuffer.toString());
        writer.flush();

        writer.println(getFooter());
        writer.flush();

        writer.close();
    }

    /**
     *|----------|------------------------|--------------------------|-----------|
     *| Testcase | Score for <base build> | Score for <target build> | % Speedup |
     *|----------|------------------------|--------------------------|-----------|
     *
     */
    private static String getTestResultsTableForSummary(String testName,
                                                        double baseScore,
                                                        double targetScore)
    {

        double totalScore = baseScore + targetScore;

        String fileName = testName.replace('.', '_');
        fileName = fileName.toLowerCase() + ".html";

        int selColorIndex = selectColor(baseScore, targetScore);

        StringBuffer buffer = new StringBuffer();

        buffer.append("<TR BGCOLOR=\"" + color[selColorIndex] + "\">");
        buffer.append("<TD><P><A HREF=\"testcases/" + fileName +
                      "\">" + testName + "</A></P></TD>");
        buffer.append("<TD align=\"center\"><P><A HREF=\"testcases/" +
                      fileName +
                      "\"><B>" + decimalFormat.format(baseScore) +
                      "</B></A></P></TD>");
        buffer.append("<TD align=\"center\"><P><A HREF=\"testcases/" +
                      fileName + "\"><B>" + decimalFormat.format(targetScore) +
                      "</B></A></P></TD>");
        buffer.append("<TD align=\"center\"><P><A HREF=\"testcases/" +
                      fileName + "\"><B>" +
                      decimalFormat.format(calculateSpeedupPercentage(
                          baseScore,
                          targetScore)) +
                      "</B></A></P></TD>");
        buffer.append("</TR>");

        return buffer.toString();
    }

    /**
     *|-------------------|-------------------|-----------------|-------------------|--------|
     *| Tests Performance | BETTER  (Num / %) | SAME  (Num / %) | WORSE  ( Num / %) | Total  |
     *|-------------------|-------------------|-----------------|-------------------|--------|
     *
     */
    private static String getStatusTableForSummary(
        String curGroupName, String testName, int nBetter,
        int nSame, int nWorse)
    {

        String fileName = testName.replace('.', '_');
        fileName = fileName.toLowerCase() + ".html";

        int totalTests = nBetter + nSame + nWorse;

        StringBuffer buffer = new StringBuffer();

        buffer.append("<TR>");
        buffer.append("<TD><P><A HREF=\"#test_result_" + curGroupName +
                      "\">" + testName + "</A></P></TD>");
        buffer.append("<TD BGCOLOR=\"#99FF99\" align=\"center\"><P>" +
                      "<A HREF=\"#test_result_" + curGroupName +
                      "\"><B>" + nBetter + "</A></B>&nbsp;&nbsp;&nbsp;&nbsp;(" +
                      (nBetter * 100)/totalTests + "%)</P></TD>");
        buffer.append("<TD BGCOLOR=\"#CCFFFF\" align=\"center\"><P>" +
                      "<A HREF=\"#test_result_" + curGroupName +
                      "\"><B>" + nSame + "</A></B>&nbsp;&nbsp;&nbsp;&nbsp;(" +
                      (nSame * 100)/totalTests + "%)</P></TD>");
        buffer.append("<TD BGCOLOR=\"#FFCC00\" align=\"center\"><P>" +
                      "<A HREF=\"#test_result_" + curGroupName +
                      "\"><B>" + nWorse + "</A></B>&nbsp;&nbsp;&nbsp;&nbsp;(" +
                      (nWorse * 100)/totalTests + "%)</P></TD>");
        buffer.append("<TD BGCOLOR=\"#FFFFFF\" align=\"center\"><P>" +
                      "<A HREF=\"#test_result_" + curGroupName +
                      "\"><B>" + totalTests + "</B></A></P></TD>");
        buffer.append("</TR>");

        return buffer.toString();
    }

    /**
     *  |-------------------|-----------------|------------------------------|
     *  | Tests performance | Number of tests | % from total number of tests |
     *  |-------------------|-----------------|------------------------------|
     *
     */
    private static String getPerformanceTableForTestcase(
        String testName, int nBetter, int nSame, int nWorse) {

        StringBuffer buffer = new StringBuffer();

        int totalTests = nBetter + nSame + nWorse;

        buffer.append("<hr size=\"1\">");
        buffer.append("<H3>Status:</H3>");

        buffer.append("<table cols=\"4\" cellspacing=\"0\" " +
                      "cellpadding=\"3\" border=\"1\" width=\"80%\">");
        buffer.append("<TR BGCOLOR=\"#CCCCFF\">");
        buffer.append("<TD align=\"center\"><B>Tests performance</B></TD>");
        buffer.append("<TD align=\"center\"><B>Number of tests</B></TD>");
        buffer.append("<TD align=\"center\"><B>% from total number of " +
                      "tests</B></TD>");
        buffer.append("</TR>");

        buffer.append("<TR BGCOLOR=\"#99FF99\">");
        buffer.append("<TD><P><A HREF=\"#better\">" +
                      "Target is at least 10 percent BETTER</A></P></TD>");
        buffer.append("<TD align=\"center\"><P><A HREF=\"#better\"><B>" +
                      nBetter + "</B></A></P></TD>");
        buffer.append("<TD align=\"center\"><P>" + (nBetter * 100/totalTests) +
                      "</P></TD>");
        buffer.append("</TR>");

        buffer.append("<TR BGCOLOR=\"#CCFFFF\">");
        buffer.append("<TD><P><A HREF=\"#same\">" +
                      "The same within 10 percent</A></P></TD>");
        buffer.append("<TD align=\"center\"><P><A HREF=\"#same\"><B>" +
                      nSame + "</B></A></P></TD>");
        buffer.append("<TD align=\"center\"><P>" + (nSame * 100/totalTests) +
                      "</P></TD>");
        buffer.append("</TR>");

        buffer.append("<TR BGCOLOR=\"#FFCC00\">");
        buffer.append("<TD><P><A HREF=\"#worse\">" +
                      "Target is at least 10 percent WORSE</A></P></TD>");
        buffer.append("<TD align=\"center\"><P><A HREF=\"#worse\"><B>" +
                      nWorse + "</B></A></P></TD>");
        buffer.append("<TD align=\"center\"><P>" + (nWorse * 100/totalTests) +
                      "</P></TD>");
        buffer.append("</TR>");

        buffer.append("</TABLE>");

        return buffer.toString();
    }

    /**
     *  |-----------|---------|--------------------|----------------------|------------|
     *  | Num Units | Options | <base build> Score | <target build> Score | % Speedup  |
     *  |-----------|---------|--------------------|----------------------|------------|
     *
     *  String[0] = getStatusTableForSummary()
     *  String[1] = getTestResultsTableForSummary()
     *
     * Generate Testcase Report - testcases/<testcase name>.html
     */
    private static String[] generateTestCaseReport(
        String curGroupName,
        Object key,
        J2DAnalyzer.SingleResultSetHolder baseSRSH,
        J2DAnalyzer.SingleResultSetHolder targetSRSH,
        Map testCaseResultCount,
        Map testCaseBaseResult,
        Map testCaseTargetResult) {

        int numBetterTestCases = 0;
        int numWorseTestCases = 0;
        int numSameTestCases = 0;

        StringBuffer tcStartTags = new StringBuffer();
        tcStartTags.append("<tr>");
        tcStartTags.append("<td bgcolor=\"#CCCCFF\" align=\"center\">" +
                           "<b>Num Units</b></td>");
        tcStartTags.append("<td bgcolor=\"#CCCCFF\" align=\"center\">" +
                           "<b>Options</b></td>");
        tcStartTags.append("<td bgcolor=\"#CCCCFF\" align=\"center\"><b>" +
                           baseBuild + " Score</b></td>");
        tcStartTags.append("<td bgcolor=\"#CCCCFF\" align=\"center\"><b>" +
                           targetBuild + " Score</b></td>");
        tcStartTags.append("<td bgcolor=\"#CCCCFF\" align=\"center\">" +
                           "<b>% Speedup</b></td>");
        tcStartTags.append("</tr>");

        StringBuffer worseTestcaseResultTags =
            new StringBuffer(tcStartTags.toString());
        StringBuffer sameTestcaseResultTags =
            new StringBuffer(tcStartTags.toString());
        StringBuffer betterTestcaseResultTags =
            new StringBuffer(tcStartTags.toString());

        Object curTestCountObj = testCaseResultCount.get(key.toString());
        int curTestCount = 0;
        if(curTestCountObj != null) {
            curTestCount = ((Integer) curTestCountObj).intValue();
        }

        String fileName = key.toString().replace('.', '_');
        fileName = fileName.toLowerCase() + ".html";
        File testcaseReportFile =
            new File(resultsDir + File.separator + "testcases", fileName);
        PrintWriter writer = openFile(
            testcaseReportFile.getAbsolutePath(), HTMLGEN_FILE_NEW);

        String header = getHeader(baseSRSH, targetSRSH,
                                  "J2DBench - " + key.toString(),
                                  "../System_Properties.html");
        writer.println(header);
        writer.flush();

        double totalBaseScore = 0;
        double totalTargetScore = 0;

        for(int i=0; i<curTestCount; i++) {

            J2DAnalyzer.ResultHolder baseTCR =
                (J2DAnalyzer.ResultHolder)testCaseBaseResult.get(
                    key.toString() + "_" + i);
            J2DAnalyzer.ResultHolder targetTCR =
                (J2DAnalyzer.ResultHolder) testCaseTargetResult.get(
                    key.toString() + "_" + i);

            double baseScore = baseTCR.getScore();
            double targetScore = targetTCR.getScore();

            StringBuffer tcTagBuffer = new StringBuffer();

            int selColorIndex = selectColor(baseScore, targetScore);
            tcTagBuffer.append("<tr bgcolor=\""+ color[selColorIndex] + "\">");
            tcTagBuffer.append("<td align=\"center\">" + baseTCR.getUnits() +
                               "</td>");
            tcTagBuffer.append("<td valign=\"center\">");

            Map map = baseTCR.getOptions();
            Iterator iter = map.keySet().iterator();
            Object subKey=null, subValue=null;
            tcTagBuffer.append("<ul>");
            while(iter.hasNext()) {
                subKey = iter.next().toString();
                subValue = map.get(subKey).toString();
                tcTagBuffer.append("<li>" + subKey + " = " +
                                   subValue + "</li>");
            }
            tcTagBuffer.append("</ul></td>");
            tcTagBuffer.append("<td valign=\"center\" align=\"center\">" +
                               decimalFormat.format(baseTCR.getScore()) +
                               "</td>");
            tcTagBuffer.append("<td valign=\"center\" align=\"center\">" +
                               decimalFormat.format(targetTCR.getScore()) +
                               "</td>");
            tcTagBuffer.append("<td valign=\"center\" align=\"center\">" +
                               decimalFormat.format(
                                   calculateSpeedupPercentage(
                                       baseTCR.getScore(),
                                       targetTCR.getScore())) +
                                   "</td>");
            tcTagBuffer.append("</tr>");

            totalBaseScore = totalBaseScore + baseTCR.getScore();
            totalTargetScore = totalTargetScore + targetTCR.getScore();

            switch(selColorIndex) {
                case 0:
                    betterTestcaseResultTags.append(tcTagBuffer.toString());
                    numBetterTestCases++;
                    break;
                case 1:
                    sameTestcaseResultTags.append(tcTagBuffer.toString());
                    numSameTestCases++;
                    break;
                case 2:
                    worseTestcaseResultTags.append(tcTagBuffer.toString());
                    numWorseTestCases++;
                    break;
            }
        }

        String performanceTable =
            getPerformanceTableForTestcase(key.toString(),
                                           numBetterTestCases, numSameTestCases,
                                           numWorseTestCases);

        writer.println(performanceTable);
        writer.flush();

        writer.println("<hr size=\"1\">");
        writer.println("<A NAME=\"details\"></A><H3>Details:</H3>");

        writer.println("<table cellspacing=\"0\" " +
                       "cellpadding=\"3\" border=\"1\" width=\"80%\">");

        writer.println("<tr><td colspan=\"5\" " +
                       "valign=\"center\" bgcolor=\"#f0f0f0\">" +
                       "<a name=\"better\"></a><font size=\"+1\">" +
                       key.toString() +
                       " Tests which run BETTER on target</font></td></tr>");
        writer.println(betterTestcaseResultTags.toString());
        writer.flush();

        writer.println("<tr><td colspan=\"5\">&nbsp;<br>&nbsp;</td></tr>");

        writer.println("<tr><td colspan=\"5\" " +
                       "valign=\"center\" bgcolor=\"#f0f0f0\">" +
                       "<a name=\"same\"></a><font size=\"+1\">" +
                       key.toString() +
                       " Tests which run SAME on target</font></td></tr>");
        writer.println(sameTestcaseResultTags.toString());
        writer.flush();

        writer.println("<tr><td colspan=\"5\">&nbsp;<br>&nbsp;</td></tr>");

        writer.println("<tr><td colspan=\"5\" " +
                       "valign=\"center\" bgcolor=\"#f0f0f0\">" +
                       "<a name=\"worse\"></a><font size=\"+1\">" +
                       key.toString() +
                       " Tests which run WORSE on target</font></td></tr>");
        writer.println(worseTestcaseResultTags.toString());
        writer.flush();

        writer.println("</table>");

        writer.println(getFooter());
        writer.flush();

        writer.close();

        String statusTable =
            getStatusTableForSummary(curGroupName, key.toString(),
                                     numBetterTestCases,
                                     numSameTestCases, numWorseTestCases);

        String testResultsTable =
            getTestResultsTableForSummary(key.toString(),
                                          totalBaseScore, totalTargetScore);

        return new String[] {statusTable, testResultsTable};
    }

    /**
     * Returns footer tag for HTML files
     */
    private static String getFooter() {

        StringBuffer buffer = new StringBuffer();

        buffer.append("<br><hr WIDTH=\"100%\" size=\"1\">");
        buffer.append("<A NAME=\"legend\"></A><H3>Legend:</H3>");
        buffer.append("<table cellspacing=\"0\" cellpadding=\"3\" " +
                      "border=\"1\" width=\"80%\">");
        buffer.append("<TR BGCOLOR=\"" + color[0] +
                      "\"><TD>The result for " + targetBuild +
                      " is at least 10 percent BETTER than for " + baseBuild +
                      "</TD></TR>");
        buffer.append("<TR BGCOLOR=\"" + color[1] +
                      "\"><TD>The results for " + targetBuild + " and " +
                      baseBuild + " are within 10 percent</TD></TR>");
        buffer.append("<TR BGCOLOR=\"" + color[2] +
                      "\"><TD>The result for " + targetBuild +
                      " is at least 10 percent WORSE than " + baseBuild +
                      "</TD></TR>");
        buffer.append("<TR><TD>The 'Score' is a number of " +
                      "successful rendering " +
                      "operations per second</TD></TR>");
        buffer.append("</table>");

        buffer.append("<br><hr WIDTH=\"100%\" size=\"1\">");
        buffer.append("</p><hr WIDTH=\"100%\" size=\"1\"></body></html>");

        return buffer.toString();
    }

    /**
     * Returns header tag for HTML files
     */
    private static String
        getHeader(J2DAnalyzer.SingleResultSetHolder baseSRSH,
                  J2DAnalyzer.SingleResultSetHolder targetSRSH,
                  String title,
                 String sysPropLoc)
    {

        StringBuffer buffer = new StringBuffer();

        String headerTitle = getHeaderTitle(title);
        buffer.append(headerTitle);

        //System Properties
        buffer.append("<tr><td bgcolor=\"#CCCCFF\">" +
                      "<b><A HREF=\"" + sysPropLoc + "\">System Property</A>" +
                      "</b></td>" +
                      "<td bgcolor=\"#CCCCFF\"><b><A HREF=\"" +
                      sysPropLoc + "\">Value<A></b></td></tr>");
        Map sysProps = targetSRSH.getProperties();
        buffer.append("<tr><td bgcolor=\"#f0f0f0\">os.name</td><td>" +
                      sysProps.get("os.name") + "</td></tr>");
        buffer.append("<tr><td bgcolor=\"#f0f0f0\">os.version</td><td>" +
                      sysProps.get("os.version") + "</td></tr>");
        buffer.append("<tr><td bgcolor=\"#f0f0f0\">os.arch</td><td>" +
                      sysProps.get("os.arch") + "</td></tr>");
        buffer.append("<tr><td bgcolor=\"#f0f0f0\">sun.desktop</td><td>" +
                      sysProps.get("sun.desktop") + "</td></tr>");

        buffer.append("</table>");

        return buffer.toString();
    }

    /**
     * Returns start tag and title tag for HTML files
     */
    private static String getHeaderTitle(String title) {

        StringBuffer buffer = new StringBuffer();

        buffer.append("<html><head><title>" + title + "</title></head>");
        buffer.append("<body bgcolor=\"#ffffff\"><hr size=\"1\">");
        buffer.append("<center><h2>" + title + "</h2>");
        buffer.append("</center><hr size=\"1\"><br>");
        buffer.append("<table cols=\"2\" cellspacing=\"2\" cellpadding=\"5\" " +
                      "border=\"0\" width=\"80%\">");
        buffer.append("<tr><td bgcolor=\"#CCCCFF\" colspan=\"2\">" +
                      "<b>Test Details</b></td></tr>");
        buffer.append("<tr><td bgcolor=\"#f0f0f0\">Base Build</td>");
        buffer.append("<td>" + baseBuild + "</td></tr>");
        buffer.append("<tr><td bgcolor=\"#f0f0f0\">Target Build</td>");
        buffer.append("<td>" + targetBuild + "</td></tr>");

        return buffer.toString();
    }

    /**
     * Generats System-Properties HTML file - System_Property.html
     */
    private static void
        generateSysPropsReport(J2DAnalyzer.SingleResultSetHolder srsh)
    {

        File sysPropsFile =
            new File(resultsDir, "System_Properties.html");
        PrintWriter writer =
            openFile(sysPropsFile.getAbsolutePath(), HTMLGEN_FILE_NEW);

        String headerTitle = getHeaderTitle("System Properties");
        writer.println(headerTitle);
        writer.flush();

        writer.println("<tr><td bgcolor=\"#CCCCFF\"><b>" +
                       "System Property</b></td><td bgcolor=\"#CCCCFF\">" +
                       "<b>Value</b></td></tr>");

        String key = null;
        String value = null;
        Map sysProps = srsh.getProperties();
        Iterator iter = sysProps.keySet().iterator();
        while(iter.hasNext()) {
            key = iter.next().toString();
            value = sysProps.get(key).toString();
            writer.println("<tr><td bgcolor=\"#f0f0f0\">" +
                           key + "</td><td>" + value + "</td></tr>");
        }
        writer.println("</table>");
        writer.flush();

        writer.println("<br><hr WIDTH=\"100%\" size=\"1\">");
        writer.println("</p><hr WIDTH=\"100%\" size=\"1\"></body></html>");

        writer.flush();
    }

    /**
     * Returns the index of color from color array based on the results
     * Can change this implementation so as to select based on some analysis.
     */
    private static int selectColor(double baseScore, double targetScore) {

        double res = calculateSpeedupPercentage(baseScore, targetScore);

        if (res < -10) {
            return 2;
        } else if (res > 10) {
            return 0;
        } else {
            return 1;
        }
    }

    /**
     * Calculate Speedup Percentage ->
     *     ((target_score - base_score) * 100) / baseScore
     * Can change this implementation so as to provide some analysis.
     */
    private static double calculateSpeedupPercentage(double baseScore,
                                                     double targetScore)
    {
        return ((targetScore - baseScore) * 100)/baseScore;
    }

    private static void printUsage() {
        String usage =
            "\njava XMLHTMLReporter [options]      "     +
            "                                      \n\n" +
            "where options include:                "     +
            "                                      \n"   +
            "    -r | -results <result directory>  "     +
            "directory to which reports are stored \n"   +
            "    -basexml | -b <xml file path>     "     +
            "path to base-build result             \n"   +
            "    -targetxml | -t <xml file path>   "     +
            "path to target-build result           \n"   +
            "    -resultxml | -xml <xml file path> "     +
            "path to result XML                    \n"   +
            "    -group | -g  <level>              "     +
            "group-level for tests                 \n"   +
            "                                      "     +
            " [ 1 , 2 , 3 or 4 ]                   \n"   +
            "    -analyzermode | -am               "     +
            "mode to be used for finding score     \n"   +
            "                                      "     +
            " [ BEST , WORST , AVERAGE , MIDAVG ]  ";
        System.out.println(usage);
        System.exit(0);
    }

    /**
     * main
     */
    public static void main(String args[]) {

        String resDir = ".";
        String baseXML = null;
        String targetXML = null;
        String resultXML = null;
        int group = 2;

        /* ---- Analysis Mode ----
            BEST    = 1;
            WORST   = 2;
            AVERAGE = 3;
            MIDAVG  = 4;
         ------------------------ */
        int analyzerMode = 4;

        try {

            for (int i = 0; i < args.length; i++) {
                if (args[i].startsWith("-results") ||
                    args[i].startsWith("-r"))
                {
                    i++;
                    resDir = args[i];
                } else if (args[i].startsWith("-basexml") ||
                           args[i].startsWith("-b"))
                {
                    i++;
                    baseXML = args[i];
                } else if (args[i].startsWith("-targetxml") ||
                           args[i].startsWith("-t"))
                {
                    i++;
                    targetXML = args[i];
                } else if (args[i].startsWith("-resultxml") ||
                           args[i].startsWith("-xml"))
                {
                    i++;
                    resultXML = args[i];
                } else if (args[i].startsWith("-group") ||
                           args[i].startsWith("-g"))
                {
                    i++;
                    group = Integer.parseInt(args[i]);
                    System.out.println("Grouping Level for tests: " + group);
                } else if (args[i].startsWith("-analyzermode") ||
                           args[i].startsWith("-am"))
                {
                    i++;
                    String strAnalyzerMode = args[i];
                    if(strAnalyzerMode.equalsIgnoreCase("BEST")) {
                        analyzerMode = 0;
                    } else if (strAnalyzerMode.equalsIgnoreCase("WORST")) {
                        analyzerMode = 1;
                    } else if (strAnalyzerMode.equalsIgnoreCase("AVERAGE")) {
                        analyzerMode = 2;
                    } else if (strAnalyzerMode.equalsIgnoreCase("MIDAVG")) {
                        analyzerMode = 3;
                    } else {
                        printUsage();
                    }
                    System.out.println("Analyzer-Mode: " + analyzerMode);
                }
            }
        }
        catch(Exception e) {
            printUsage();
        }

        if(resDir != null) {

            XMLHTMLReporter.setGroupLevel(group);
            J2DAnalyzer.setMode(analyzerMode);

            if(targetXML != null && baseXML != null) {
                XMLHTMLReporter.generateComparisonReport(resDir, baseXML,
                                                         targetXML);
            } else if (resultXML != null) {
                XMLHTMLReporter.generateReport(resDir, resultXML);
            } else {
                printUsage();
            }
        } else {
            printUsage();
        }
    }
}
