import java.io.*;
/**
 * This class represents the result of a comparison between a system result for one video and the reference.
 * It typically permits to save results of one segmentation in a directory named wiht the system Id and
 * a sub-directory named with the overlapping rates used in this run of comparison.
 * 
 * @author NIST-ITL-IAD-Retrieval Group
 * This software was produced by NIST, an agency of the
 * U.S. government, and by statute is not subject to copyright in the
 * United States. Recipients of this software assume all
 * responsibilities associated with its operation, modification and
 * maintenance.
 *
 */
public class comparisonResult {

	/**
     * The output Xml file.
     *     
     */
    private File outputXmlFile = null;
	/**
     * The file writer.
     *     
     */
	private FileWriter out = null;
	/**
     * The related segmentation.
     *     
     */
	private SysSegmentation systemSegmentation = null;
	
	/**
     * Constructs comparisonResult object for the given segmentation.
     * It creates directories as explained in class description.
     *
     */
	public comparisonResult(SysSegmentation systemSegmentation){
		
		this.systemSegmentation = systemSegmentation;
		File resultsDir = new File(System.getProperty("user.dir")+System.getProperty("file.separator")+
								 "ComparisonResult"+System.getProperty("file.separator"));
		resultsDir.mkdir();
		File sysIdDir = new File(resultsDir, systemSegmentation.getSysId());
		sysIdDir.mkdir();
		File runDir = new File(sysIdDir, System.getProperty("file.separator")+
								 trimPrecision(new Double(OverlapComparator.getPRef()))+"_"+
								 trimPrecision(new Double(OverlapComparator.getPSys())));
		runDir.mkdir();
		
		this.outputXmlFile = new File(runDir, systemSegmentation.getSysId()+"_"+
										systemSegmentation.getTopicNumber()+".xml");
		try{
			this.out = new FileWriter(outputXmlFile);
		}
		catch(IOException i){
			System.out.println("A problem occured while preparing to write results");
		}
	}
	/**
     * Given the parameter, this method writes in the file the results.
     *
     * @param     knownItemCount The known-items (or reference items) count in the reference for the related topic.
     * @param     matchingRefItem The matching reference items count for the comparison.
     * @param     matchingSysItem The matching system items count for the comparison.
     * @param     matchingSection A ready to write XML formatted section for the matching items results.
     * @param     notRetrievedKnownItemsSection A ready to write XML formatted section for not retrieved known-items.
     * @param     pRef Double representation of the reference overlapping parameter used for comparison.
     * @param     pSys Double representation of the system overlapping parameter used for comparison.
     * @param     MAP Double representation of the mean average precision.
     */
	public void setResults(int knownItemCount, int matchingRefItem, int matchingSysItem,
						   String matchingSection, String notRetrievedKnownItemsSection,
						   double pRef, double pSys, double MAP, int maxAllowedItems){
		try{
			String nl = System.getProperty("line.separator");
			out.write("<!DOCTYPE kiComparisonResult>"+nl);
			out.write("<kiComparisonResult sysId=\""+this.systemSegmentation.getSysId()+"\" "+nl);
			out.write("                    topicNumber=\""+this.systemSegmentation.getTopicNumber()+"\" "+nl);
			out.write("                    pType=\""+this.systemSegmentation.getPType()+"\" "+nl);
			out.write("                    knownItemsCount=\""+knownItemCount+"\" "+nl);
			out.write("                    matchingKnownItemsCount=\""+matchingRefItem+"\" "+nl);
			out.write("                    matchingResultItemsCount=\""+matchingSysItem+"\" "+nl);
			out.write("                    referenceOverlappingRate=\""+pRef+"\" "+nl);
			out.write("                    systemOverlappingRate=\""+pSys+"\" "+nl);

			if(knownItemCount != 0 && matchingRefItem != 0)
				out.write("                    recall=\""+
						trimPrecision(new Double((double)matchingRefItem / (double)knownItemCount))+"\" "+nl);
			else
				out.write("                    recall=\"0.0\""+nl);
			if(matchingSysItem != 0 && this.systemSegmentation.getItemCount() != 0)
				out.write("                    precision=\""+
						trimPrecision(new Double((double)matchingSysItem / 
								(double)this.systemSegmentation.getItemCount()))+"\""+nl);
			else
				out.write("                    precision=\"0.0\""+nl);
			out.write("                    averagePrecision=\""+trimPrecision2(new Double(MAP)) + "\" "+nl);
			out.write("                    precisionAt"+maxAllowedItems+"=\""+
					trimPrecision(new Double((double)matchingSysItem / (double)maxAllowedItems))+"\">"+nl);
			
			out.write(nl);
			out.write(matchingSection);
			out.write(nl);
			out.write(notRetrievedKnownItemsSection);
			out.write(nl+"</kiComparisonResult>");
			out.close();
		} catch(IOException i){
			i.printStackTrace();
			System.out.println("A problem occured while writing results");
		}
	}	
    /**
     * Private method that only trim precision of a double until the first 3 decimals and returns it as a String.
     * 
     */
	private String trimPrecision(Double d){
	
		String toReturn = d.toString();
		if(toReturn.length() >= 6)
			toReturn = toReturn.substring(0,5);
		return toReturn;		
	}
    /**
     * Private method that only trim precision of a double until the first 3 decimals and returns it as a String.
     * 
     */
	private String trimPrecision2(Double d){
	
		return new PrintfFormat("%0.4f").sprintf(d);	
	}
}

