/*
 *  Draco Econometrics
 *  Copyright (C) 2008-2009 Approximatrix, LLC
 *  http://www.approximatrix.com
 *  
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.approximatrix.draco.utility;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;

public class ResultsUtilities {
	
	public static final int OUTNUMBER_FIELD_WIDTH = 10;
	public static final boolean USE_HTML = true;
	
	/** A text flag to add to a table entry to signify monospacing */
	protected static final String NUMERIC_FLAG = "<!-- $$NUMERIC -->";
	
	private static final String NUMERIC_PREFIX = "<div class=\"font-family: monospaced\">";
	private static final String NUMERIC_SUFFIX = "</div>";
	
	public static String OutText(String text) {
		String spaces = "         ";
		String internal_text = new String(text);
		if(internal_text.length() > OUTNUMBER_FIELD_WIDTH) 
			internal_text = internal_text.substring(0, 10);
		
		String return_val = spaces.substring(0,Math.max(OUTNUMBER_FIELD_WIDTH-internal_text.length(),0));
		return return_val+internal_text;
	}
	
	public static String OutNumber(Number value) {
		if(value == null)
			return "Error";
		
		if(value instanceof Double)
			return OutNumber(value.doubleValue());
		else
			return value.toString();
	}
	
	public static String OutNumber(double value) {
		if(Double.isNaN(value))
			return "NaN";
		
		NumberFormat nf = NumberFormat.getNumberInstance(Locale.getDefault());
		DecimalFormat df = (DecimalFormat)nf;
		df.setPositivePrefix(" ");
		if(Math.abs(value) > 999.0 || Math.abs(value) < 0.0001) {
			df.applyPattern("0.####E00");
		} else {
			df.applyPattern("##0.#####");
		}
		String spaces = "         ";
		String return_val = spaces.substring(0,Math.max(OUTNUMBER_FIELD_WIDTH-df.format(value).length(),0));
		String cell_val = return_val+df.format(value);
		if(USE_HTML)
			return NUMERIC_FLAG+cell_val;
		else
			return cell_val; 
	}
	
	public static String SeparatorLine() {
		if (ResultsUtilities.USE_HTML)
			return "<HR>";
		else
			return "---------------------------------------------------------------\n";
	}
	
	public static String GenHTMLHeader() {
		StringBuffer return_val = new StringBuffer();
		return_val.append("<HTML><BODY CLASS=\"font-family: Helvetica,Arial,sans-serif;\">");
		return return_val.toString();
	}
	
	public static String GenHTMLFooter() {
		StringBuffer return_val = new StringBuffer();
		return_val.append("</BODY></HTML>");
		return return_val.toString();
	}
	
	/** Generates an HTML table from an array of strings 
	 * 
	 * @param data a 2D array of strings to include in the table
	 * @param header_row flag indicating whether the first row is a header
	 * @return a String containing the properly formatted HTML table
	 */
	public static String GenerateTable(String[][] data, boolean header_row) {
		return GenerateTable(data,header_row,false);
	}
	
	/** Generates an HTML table from an array of strings 
	 * 
	 * @param data a 2D array of strings to include in the table
	 * @param header_row flag indicating whether the first row is a header
	 * @param header_col flag indicating whether the first column is a header
	 * @return a String containing the properly formatted HTML table
	 */
	public static String GenerateTable(String[][] data, boolean header_row, boolean header_col) {
		StringBuffer rv = new StringBuffer("<TABLE BORDER=0 WIDTH=\"75%\">");
		boolean header_row_flag = true;
		for(String[] row : data) {
			boolean header_col_flag = true;
			rv.append("<TR>");
			for(String entry : row) {
				rv.append("<TD>");
				if((header_row && header_row_flag) || (header_col_flag && header_col)) {
					rv.append("<B>");
				}
				if(entry.startsWith(NUMERIC_FLAG)) {
					entry = entry.replace(NUMERIC_FLAG, NUMERIC_PREFIX)+NUMERIC_SUFFIX;
				} 
				rv.append(entry);
				if((header_row && header_row_flag) || (header_col_flag && header_col)) {
					rv.append("</B>");
				}
				rv.append("</TD>");
				header_col_flag = false;
			}
			header_row_flag = false;
			rv.append("</TR>");
		}
		rv.append("</TABLE>");
		return rv.toString();
	}
	
	/** Returns the formatted title text for inclusion in results
	 * 
	 * @param text the title text
	 * @return a String containing the title
	 */
	public static String GetTitle(String text) {
		if(USE_HTML)
			return "<H2>"+text+"</H2>";
		else
			return text;
	}
	
	public static String PrepStringForOutput(String value) {
		if(ResultsUtilities.USE_HTML)
			return value.replaceAll("\n", "<BR>\n");
		else
			return value.replace("<BR>", "");
	}
	
	public static String GenerateList(String[] values) {
		StringBuffer ret = new StringBuffer();
		
		if(values == null) return "";
		
		if(USE_HTML)
			ret.append("<ul>");
		
		for(int i=0;i<values.length;i++) {
			if(USE_HTML)
				ret.append("<li>");
			else
				ret.append("\t");
			
			ret.append(values[i]);
			
			if(USE_HTML)
				ret.append("</li>");
			else
				ret.append("\n");
		}
		
		if(USE_HTML)
			ret.append("</ul>");
			
		return ret.toString();
	}
	
}
