package com.instantiations.assist.eclipse.analysis.audit.writer;
 
import com.instantiations.assist.eclipse.analysis.audit.core.*;
import com.instantiations.assist.eclipse.analysis.audit.resolution.*;
import com.instantiations.assist.eclipse.analysis.audit.util.AuditResultGroup;
import com.instantiations.jlib.license.*;
import com.instantiations.jlib.xml.*;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
 
/**
 * Instances of the class HTMLAuditWriter implement a audit writer
 * that produces HTML formatted output.
 * 
 * Copyright (c) 2003, Google, Inc.
 * All Rights Reserved
 *
 * @author Dan Rubel
 * @author Brian Wilkerson
 * @version $Revision: 1.0 $
 */
public class HTMLAuditWriter extends AbstractAuditWriter
{
    /**
     * The string to be printed to represent a single level of indentation.
     */
    protected static final String INDENTATION = "    ";
 
    /**
     * The maximum number of columns in the TOC.
     */
    protected static final int MAX_TOC_COLUMNS = 4;
 
    /**
     * The maximum number of rows in the TOC.
     */
    protected static final int MAX_TOC_ROWS = 8;
 
    /**
     * The number of columns in the report.
     */
    protected int numColumns = 3;
	
    /**
     * @see com.instantiations.assist.eclipse.analysis.audit.core.AuditResultWriter#writeHeader(AuditViolationSet)
     */
    public void writeHeader(AuditViolationSet violationSet) {
        if (includeRecommendations) numColumns++;
        if (includeSeverities) numColumns++;
 		
        _writer.println("<html>");
        _writer.println("");
        _writer.println("<head>");
        _writer.println("");
        _writer.println("<style type=text/css>");
        _writer.println("\tbody {font: 70% verdana,arial,helvetica; color: #000000}");
        _writer.println("\tp {margin: 0.5em 2em 1em; line-height: 1.5em}");
        _writer.println("\th1 {margin: 0px 0px 5px; font: 175% verdana,arial,helvetica}");
        _writer.println("\th2 {margin: 0px 0px 5px; font: bold 175% verdana,arial,helvetica}");
        _writer.println("\th3 {margin: 0px 0px 5px; font: 125% verdana,arial,helvetica}");
        _writer.println("\th4 {margin-top: 1em; margin-bottom: 0.5em; font: bold 125% verdana,arial,helvetica}");
        _writer.println("\ttable tr th {font-size: 75%}");
        _writer.println("\ttable tr td {font-size: 75%} ");
        _writer.println("\ttable.details tr th {background: #a6d0e0; font-weight: bold; text-align: left}");
        _writer.println("\ttable.details tr td {background: #eeeeee; text-align: top; vertical-align: top}");
        _writer.println("\ttable.detailgroup tr th {background: #91d5ac; font-weight: bold; text-align: center; font-size: 80%}");
        _writer.println("</style>");
        _writer.println("");
        _writer.println("<meta name=\"GENERATOR\" content=\"" + Product.getMainProduct().getName() + "\">");
        _writer.println("<title>CodePro Code Audit for " + violationSet.getName() + "</title>");
        _writer.println("");
        _writer.println("</head>");
        _writer.println("");
        _writer.println("<body>");
        _writer.println("");
        _writer.println("<h1><a name=top>CodePro Code Audit</a></h1>");
        _writer.println("<h2 align=\"center\">" + violationSet.getName() + "</h2>");
 
        AuditRuleSet auditRuleSet = violationSet.getAuditRuleSet();
        if (auditRuleSet != null && !auditRuleSet.isDefault()) {
            _writer.println("<h2 align=\"center\">Computed using " + auditRuleSet.getName() + "</h2>");
        }
        _writer.println("<h3 align=\"center\">Violation Summary - " + violationSet.getSeveritySummary() + "</h3>");
        _writer.println("");
                   
        _writer.println("<p align=right>Powered by");
        _writer.println( Product.getMainProduct().getName() + " and");
        _writer.println("\t<a href=\"http://www.eclipse.org\">Eclipse</a>");
        _writer.println("</p>");
        _writer.println("");
    }
 
    /**
     * @see com.instantiations.assist.eclipse.analysis.audit.core.AuditResultWriter#writeTableOfContents(AuditResultGroup[])
     */
    public void writeTableOfContents(AuditResultGroup[] groups) {
        String groupName;
        int start, end;
        int columns = Math.max(Math.min(((groups.length - 1) / MAX_TOC_ROWS) + 1, MAX_TOC_COLUMNS), 1);
        int rows = ((groups.length - 1) / columns) + 1;
 
        _writer.println("<hr size=2>");
        _writer.println("<h4>Summary</h4>");
 
        _writer.println("<table>");
        _writer.println("\t<tr>");
 
        for (int i = 0; i < columns; i++) {
            start = Math.min(i * rows, groups.length - 1);
            end = Math.min(start + rows , groups.length);
 
            _writer.println("\t\t<td valign=\"top\">");
            _writer.println("\t\t\t<b>");
            for (int j = start; j < end; j++) {
                groupName = getViolationContainerName(groups[j].getElement());
                _writer.println("\t\t\t\t<a href=\"#" + groupName + "\">" + groupName + "</a><br>");
            }
            _writer.println("\t\t\t</b>");
            _writer.println("\t\t</td>");
               
            _writer.println("\t\t<td valign=\"top\" align=\"right\">");
            _writer.println("\t\t\t<b>");
            for (int j = start; j < end; j++) {
                _writer.println("\t\t\t\t" + groups[j].getTotalViolationCount() + "<br>");
            }
            _writer.println("\t\t\t</b>");
            _writer.println("\t\t</td>");
            _writer.println("\t\t<td width=\"10\"/>");
        }
 
        _writer.println("\t</tr>");
        _writer.println("</table>");
 
        _writer.println("");
 
        _writer.println("<hr size=2>");
        _writer.println("<h4>Details</h4>");
        _writer.println("<table class=details width=\"100%\">");
 
    }
 
    /**
     * Write out information about the specified group of audit violations.
     *
     * @param violationContainer the violation container
     *        (e.g. an audit rule or a resource - not null)
     * @param violationCount the number of violations in this group
     * @param depth the depth of this group
     */
    public void writeGroupHeader(Object violationContainer, int violationCount, int depth, int maxDepth)
    {
        String violationText = getViolationContainerText(violationContainer, violationCount);
        violationText = XMLUtils.encodeData(violationText);
 
        _writer.println("\t<tr>");
        if (depth >= maxDepth) {
            _writer.println("\t\t<th>");
            _writer.print("\t\t\t<a name=\"");
            _writer.print(getViolationContainerName(violationContainer));
            _writer.print("\"/>");
            _writer.print(violationText);
        } else {
            _writer.println("\t\t<th colspan=\"" + numColumns + "\">");
            _writer.print("\t\t\t<table class=detailgroup width=\"100%\" cellspacing=\"2\" cellpadding=\"2\">");
            _writer.println("\t\t\t\t<th>");
            _writer.print("\t\t\t\t\t<a name=\"");
            _writer.print(getViolationContainerName(violationContainer));
            _writer.print("\"/>");
            _writer.print(violationText);
            _writer.println("\t\t\t\t</th>");
            _writer.print("\t\t\t</table>");
        }
        //for (int i = 1; i < depth; i++) {
        //    _writer.print(INDENTATION);
        //}
        if (depth == maxDepth) {
            _writer.println(" <a href=\"#top\">top</a>");
        } else {
            _writer.println("");
        }
        _writer.println("\t\t</th>");
 
        if (depth >= maxDepth) {
            if (includeRecommendations) {
                _writer.println("\t\t<th>");
                _writer.println("\t\t\tRecommendation");
                _writer.println("\t\t</th>");
            }
 
            if (includeSeverities) {
                _writer.println("\t\t<th>");
                _writer.println("\t\t\tSeverity");
                _writer.println("\t\t</th>");
            }
 
            _writer.println("\t\t<th>");
            _writer.println("\t\t\tJava File");
            _writer.println("\t\t</th>");
 
            _writer.println("\t\t<th>");
            _writer.println("\t\t\tLine");
            _writer.println("\t\t</th>");
        }
 
        _writer.println("\t</tr>");
    }
 
    /**
     * Write out information about the specified violation.
     *
     * @param violation the audit violation (not null)
     * @param depth the depth of this violation
     */
    public void writeViolation(AuditViolation violation, int depth)
    {
        AuditViolationResolution[] resolutions;
        IMarker marker;
        String colorText = "";
        String colorEndText = "";
        if (violation.getSeverity() >= AuditRule.HIGH_SEVERITY) {
            colorText = "<font color=\"red\">";
            colorEndText = "</font>";
        }
 
        _writer.println("\t<tr>");
 
        // Write violation description
        _writer.println("\t\t<td>");
        _writer.print("\t\t\t");
        //for (int i = 1; i < depth; i++) {
        //    _writer.print(INDENTATION);
        //}
        _writer.print(colorText + XMLUtils.encodeHtmlData(violation.getDescription()) + colorEndText);
        _writer.println("");
        _writer.println("\t\t</td>");
 
        // Write recommendation
        if (includeRecommendations) {
            resolutions = violation.getResolutions();
            _writer.println("\t\t<td>");
            _writer.print("\t\t\t");
            if (resolutions.length > 0) {
                _writer.println(colorText + XMLUtils.encodeHtmlData(resolutions[0].getDescription()) + colorEndText);
            } else {
                _writer.println(" ");
            }
            _writer.println("\t\t</td>");
        }
 
        // Write severity
        if (includeSeverities) {
            _writer.println("\t\t<td>");
            _writer.print("\t\t\t");
            _writer.println(colorText + AuditRule.SEVERITY_LABELS[violation.getSeverity()] + colorEndText);
            _writer.println("\t\t</td>");
        }
 
        // Write resource name
        _writer.println("\t\t<td>");
        _writer.print("\t\t\t");
        _writer.println(colorText + violation.getResource().getName() + colorEndText);
        _writer.println("\t\t</td>");
 
        // Write line
        _writer.println("\t\t<td>");
        _writer.print("\t\t\t");
        try {
            marker = violation.getMarker();
            if (marker == null) {
                _writer.println("??");
            } else {
                _writer.println(colorText + marker.getAttribute(IMarker.LINE_NUMBER) + colorEndText);
            }
        } catch (CoreException exception) {
            _writer.println("??");
        }
        _writer.println("\t\t</td>");
 
        _writer.println("\t</tr>");
    }
 
    /**
     * Write out information about the specified group of audit violations.
     *
     * @param violationContainer the violation container
     *        (e.g. an audit rule or a resource - not null)
     * @param depth the depth of this group
     */
    public void writeGroupFooter(Object violationContainer, int depth)
    {
    }
 
    /**
     * @see com.instantiations.assist.eclipse.analysis.audit.core.AuditResultWriter#writeFooter(AuditViolationSet)
     */
    public void writeFooter(AuditViolationSet violationSet)
    {
        _writer.println("</table>");
        _writer.println("");
        _writer.println("</body>");
        _writer.println("");
        _writer.println("</html>");
    }
}