import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FileNotFoundException;
import java.io.BufferedReader;

import java.net.URL;
import java.net.URLConnection;
import java.net.MalformedURLException;

import java.text.DateFormat;

import java.util.Hashtable;
import java.util.Vector;
import java.util.Enumeration;
import java.util.Date;
import java.util.TimeZone;
import java.util.Locale;
import java.util.TreeSet;
import java.util.Iterator;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;

import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;  
import org.xml.sax.SAXParseException;  
import org.xml.sax.EntityResolver;  

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.DOMException;
import org.w3c.dom.Text;

import org.w3c.dom.ls.LSSerializer;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSOutput;
import org.w3c.dom.DOMConfiguration;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;

// $Id: dashboard.java,v 1.28 2007/08/06 15:29:43 ylafon Exp $

public class dashboard implements EntityResolver {

    private static String EXAMPLEURI = 
	"http://www.w3.org/2002/ws/databinding/examples/6/09/";
    private static String EXAMPLENS =
	"http://www.w3.org/2002/ws/databinding/examples/6/09/";
    
    private static String BASICURI = 
	"http://www.w3.org/TR/xmlschema-patterns"; // maybe the fixed one 
    private static String ADVANCEDURI = 
	"http://www.w3.org/TR/xmlschema-patterns-advanced"; // see above
    
    Vector<File>     reportnames;
    Vector<Document> documents;
    Vector<String>   basictests;
    Vector<String>   advancedtests;
    Vector<String>   pendingtests;
    String[]         toolkitnames;
    String[]         toolkitversions;
    String[]         toolkitmappings;
    String[]         toolkitlinks;
    String[]         toolkitbindings;
    String           exampleuri      = null;
    String           reportmode      = "basic";
    Hashtable<String,String>         extable         = null;
    Hashtable<String,String>         instex          = null;

    Document         dashboard;

    int nbreports;
    int totalbasic, totaladvanced, totalpending;
    
    int testspassed[];
    int testsfailed[];
    int testsskipped[];
    boolean doctored[];

    File outputfile = null;
    File templatef  = null;

    // hack to cache dtds
    public InputSource resolveEntity(String publicId, String systemId) {
	InputSource is = new InputSource();
	if (systemId.equals("http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd")) {
	    try {
		is.setSystemId((new File("dtdcache/xhtml1-transitional.dtd")).toURI().toString());
	    } catch (Exception ex) {
		ex.printStackTrace();
		return null;
	    }
	} else {
	    is.setSystemId(systemId);
	}
	return is;
    }

    /***
     *** Reads all the test to classify as advanced or basic
     *** It also builds a list of all the examples relative to basic or
     *** advanced (see command line option)
     *** 
     ***/

    void initTests() {
	InputStream is = null;
	URL tests = null;
	URL test = null;
	String examplefile,testfile,id,classification;
	int i;
	if (exampleuri == null) {
	    examplefile=EXAMPLEURI+"examples.xml";
	} else {
	    examplefile=exampleuri+"examples.xml";
	}
	System.err.println("*** fetching examples.xml to extract the number of tests");
	try {
	    tests = new URL(examplefile);
	} catch (MalformedURLException muex) {
	    muex.printStackTrace();
	    System.exit(1);
	}
	try {
	    is = tests.openStream();
	} catch (IOException ioex) {
	    ioex.printStackTrace();
	    System.exit(1);
	}
	DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
	dbf.setValidating(false);
	dbf.setNamespaceAware(true);
	DocumentBuilder parser = null;

	BufferedReader bf = new BufferedReader(new InputStreamReader(is));
	InputSource ins = new InputSource(bf);
	Document exdoc = null;
	try {
	    parser = dbf.newDocumentBuilder();
	    exdoc = parser.parse(ins);
	} catch (org.xml.sax.SAXException saxex) {
	    saxex.printStackTrace();
	    System.exit(1);
	} catch (Exception ioex) {
	    ioex.printStackTrace();
	    System.exit(1);
	}
	NodeList inl = exdoc.getElementsByTagNameNS(EXAMPLENS, "instance");
	int totalTestsCount = inl.getLength();

	System.err.println("*** got "+totalTestsCount+" tests total");
	NodeList nl = exdoc.getElementsByTagNameNS(EXAMPLENS, "example");
	extable = new Hashtable<String,String>();
	Document testdoc = null;
	for (i=0; i<nl.getLength(); i++) {
	    String exname = ((Element)nl.item(i)).getAttribute("xml:id");
	    // now go to exampleuri/exname/exname-patterns.xml
	    // and fetch <detected... status>
	    if (exampleuri == null) {
		testfile=EXAMPLEURI+exname+"/"+exname+"-patterns.xml";
	    } else {
	        testfile=exampleuri+exname+"/"+exname+"-patterns.xml";
	    }
	    try {
	        test = new URL(testfile);
	    } catch (MalformedURLException muex) {
		muex.printStackTrace();
		System.exit(1);
	    }
	    try {
		parser = dbf.newDocumentBuilder();
		bf = new BufferedReader(new 
					InputStreamReader(test.openStream()));
		ins = new InputSource(bf);
		testdoc = parser.parse(ins);
	    } catch (org.xml.sax.SAXException saxex) {
		System.err.println("*** error processing "+testfile);
		saxex.printStackTrace();
		System.exit(1);
	    } catch (Exception ioex) {
		System.err.println("*** error processing "+testfile);
		ioex.printStackTrace();
		System.exit(1);
	    }
	    NodeList tnl = testdoc.getElementsByTagName("detected");
	    if (tnl.getLength() == 0) {
		System.err.println("Error, no info on pattern "+exname);
		System.exit(3);
	    }
	    classification = ((Element)tnl.item(0)).getAttribute("status");
	    extable.put(exname, classification);
	}
	// now check the breakdown of all instances
	totalbasic    = 0;
	totaladvanced = 0;
	totalpending  = 0;
	basictests    = new Vector<String>();
	advancedtests = new Vector<String>();
	pendingtests  = new Vector<String>();

	instex = new Hashtable<String, String>();

	for (i=0; i<inl.getLength(); i++) {
	    Element testinstance = (Element) inl.item(i);
	    Node parent = testinstance.getParentNode();
	    // should be an example...
	    id      = ((Element)parent).getAttribute("xml:id");
	    String instname = testinstance.getAttribute("xml:id");
	    instex.put(instname, id);
	    classification = extable.get(id); 
	    if (classification.equals("basic")) {
		basictests.add(instname);
		totalbasic++;
	    } else if (classification.equals("advanced")) {
		advancedtests.add(instname);
		totaladvanced++;
	    } else if (classification.equals("pending")) {
		pendingtests.add(instname);
		totalpending++;
	    } else {
		System.err.println("Wrong classification for "+id+": "+classification);
		totalpending++;
	    }
	}
    }

    void initDashboard() {
	dashboard = parseTemplate();
	Element meta = dashboard.createElement("meta");
	meta.setAttribute("name", "version");
	meta.setAttribute("content","$Id: dashboard.java,v 1.28 2007/08/06 15:29:43 ylafon Exp $");
	
	NodeList n = dashboard.getDocumentElement().getElementsByTagName("title");
	Element title = (Element) n.item(0);
	title.getParentNode().insertBefore(meta,title);
    }
     
    void printDashboard() {
	DOMImplementationRegistry domReg;
	DOMImplementationLS domImpl;
	LSSerializer serializer = null;
	LSOutput lso = null;

	try {
	    domReg  = DOMImplementationRegistry.newInstance();
	    domImpl = (DOMImplementationLS) domReg.getDOMImplementation("LS");
	    serializer = domImpl.createLSSerializer();
	    DOMConfiguration domc = serializer.getDomConfig();
	    domc.setParameter("format-pretty-print", true);
	    lso = domImpl.createLSOutput();
	    lso.setEncoding("UTF-8");
	    if (outputfile != null) {
		lso.setCharacterStream(new FileWriter(outputfile));
	    } else {
		lso.setByteStream(System.out);
	    }
	} catch (Exception ex) {
	}
	serializer.write(dashboard, lso);
    }
    
    Document parseTemplate() {
	DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
	dbf.setValidating(false);
	dbf.setNamespaceAware(true);
	DocumentBuilder parser = null;
	try { 
	    parser = dbf.newDocumentBuilder(); 
	    parser.setEntityResolver(this);
	    if (templatef == null) {
		templatef = new File("dashboardTemplate.html");
	    }
	    BufferedReader bf;
	    InputSource is = null;
	    bf = new BufferedReader(new FileReader(templatef));
	    is = new InputSource(bf);
	    is.setEncoding("UTF-8");
	    return parser.parse(is);
	} catch (Exception e) {
	    e.printStackTrace();
	}
	return null;
    }

    void parseReports() {
	documents = new Vector<Document>();
	DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
	dbf.setValidating(false);
	dbf.setNamespaceAware(true);
	DocumentBuilder parser = null;
	try { 
	    parser = dbf.newDocumentBuilder(); 
	    parser.setEntityResolver(this);
	} catch (Exception ex) {
	    ex.printStackTrace();
	}
	for (int i=0; i<reportnames.size(); i++) {
	    BufferedReader bf;
	    InputSource is = null;
	    try {
		FileReader fr = new FileReader(reportnames.elementAt(i));
		bf = new BufferedReader(fr);
		is = new InputSource(bf);
		documents.add(parser.parse(is));
	    } catch (org.xml.sax.SAXException saxex) {
		saxex.printStackTrace();
		System.exit(1);
	    } catch (Exception ioex) {
		ioex.printStackTrace();
		System.exit(1);
	    }
	}
	nbreports = documents.size();
    }
    
    Element addTagValue(Node n, String tag, String value) {
	Element e = dashboard.createElement(tag);
	Text t = dashboard.createTextNode(value);
	e.appendChild(t);
	n.appendChild(e);
	return e;
    }
    
    Element addTag(Node n, String tag) {
	Element e = dashboard.createElement(tag);
	n.appendChild(e);
	return e;
    }

    void addTimeStamp() {
	Date now = new Date();
	DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL,
						       DateFormat.LONG,
						       Locale.UK);
	df.setTimeZone(TimeZone.getTimeZone("GMT"));
	Element span = dashboard.getElementById("timegenerated");
	Text t = dashboard.createTextNode(df.format(now));
	span.appendChild(t);
    }

    void addReportType() {
	Element span = dashboard.getElementById("type");
	Element a = addTagValue(span, "a", reportmode);
	if (reportmode.equals("basic")) {
	    a.setAttribute("href", BASICURI);
	} else {
	    a.setAttribute("href", ADVANCEDURI);
	}
    }

    void addSummary() {
	Element table = dashboard.createElement("table");
	Node n = addTag(table, "tr");
	Element e;
	e = addTagValue(n, "th", "Toolkit");
	e.setAttribute("class", "toolkit");

	e = addTagValue(n, "th", "Version");
	e.setAttribute("class", "version");

	e = addTagValue(n, "th", "Mapping");	
	e.setAttribute("class", "mapping");

	e = addTagValue(n, "th", "Passed");
	e.setAttribute("class", "passed");

	e = addTagValue(n, "th", "Failed");
	e.setAttribute("class", "failed");

	e = addTagValue(n, "th", "Skipped");
	e.setAttribute("class", "skipped");

	Element td;
	String passed, failed, skipped;
	String altpassed  = null;
	String altfailed   = null;
	String altskipped = null;

	if (reportmode.equals("basic")) {
	    passed  = "passedbasic";
	    failed  = "failedbasic";
	    skipped = "skippedbasic";
	} else if (reportmode.equals("advanced")) {
	    passed  = "passedadvanced";
	    failed  = "failedadvanced";
	    skipped = "skippedadvanced";
	} else if (reportmode.equals("all")) {
	    passed     = "passedbasic";
	    failed     = "failedbasic";
	    skipped    = "skippedbasic";
	    altpassed  = "passedadvanced";
	    altfailed  = "failedadvanced";
	    altskipped = "skippedadvanced";
	} else {
	    passed  = "passedpending";
	    failed  = "failedpending";
	    skipped = "skippedpending";
	}
	for (int i=0; i<nbreports; i++) {
	    int num = 0;
	    Document d = documents.elementAt(i);
	    Element tr = addTag(table, "tr");
	    td = dashboard.createElement("td");
	    Element a  = dashboard.createElement("a");
	    a.setAttribute("href", reportnames.elementAt(i).getName());
	    Text t = dashboard.createTextNode(toolkitnames[i]);
	    a.appendChild(t);
	    td.setAttribute("class","tname");
	    td.appendChild(a);
/*
	    t = dashboard.createTextNode(" ");
	    td.appendChild(t);
	    a = dashboard.createElement("a");
	    a.setAttribute("href", toolkitlinks[i]);
	    a.setAttribute("align", "right");
	    t = dashboard.createTextNode("[home]");
	    a.appendChild(t);
	    td.appendChild(a);
*/
	    if (toolkitbindings[i] != null) {
		t = dashboard.createTextNode(" ("+toolkitbindings[i]+")");
		td.appendChild(t);
	    }
	    tr.appendChild(td);

	    e = addTagValue(tr, "td", toolkitversions[i]);
	    e.setAttribute("class", "version");

	    e = addTagValue(tr, "td", toolkitmappings[i]);
	    e.setAttribute("class", "mapping");

	    n = d.getElementById(passed);
	    num = Integer.parseInt(n.getFirstChild().getNodeValue());
	    if (altpassed != null) {
		n = d.getElementById(altpassed);
		num += Integer.parseInt(n.getFirstChild().getNodeValue());
	    }
	    testspassed[i] = num;

	    e = addTagValue(tr, "td", ((Integer)num).toString());
	    e.setAttribute("class", "passed");

	    n = d.getElementById(failed);
	    num = Integer.parseInt(n.getFirstChild().getNodeValue());
	    if (altfailed != null) {
		n = d.getElementById(altfailed);
		num += Integer.parseInt(n.getFirstChild().getNodeValue());
	    }
	    testsfailed[i] = num;
	    e = addTagValue(tr, "td", ((Integer)num).toString());
	    e.setAttribute("class", "failed");

	    n = d.getElementById(skipped);
	    num = Integer.parseInt(n.getFirstChild().getNodeValue());
	    if (altskipped != null) {
		n = d.getElementById(altskipped);
		num += Integer.parseInt(n.getFirstChild().getNodeValue());
	    }
	    testsskipped[i] = num;
	    e = addTagValue(tr, "td", ((Integer)num).toString());
	    e.setAttribute("class", "failed");
	}
	e = dashboard.getElementById("toolkitnumbers");
	e.appendChild(table);
    }

    Element createProgressBar(int goodcalls, 
			      int failedcalls, 
			      int skippedcalls,
			      boolean wasdoctored) {
	int grandtotal    = goodcalls+failedcalls+skippedcalls;
	int pcentpassed   = goodcalls*100 / grandtotal;
	int pcentfailed   = failedcalls*100 / grandtotal;
	int pcentexcluded = 100 - pcentpassed - pcentfailed;

	Element table = dashboard.createElement("table");

	table.setAttribute("class", "progress");
	Element tr = dashboard.createElement("tr");
	table.appendChild(tr);
	Element td;
	Text t;
	if (pcentpassed > 0) {
	    td = dashboard.createElement("td");
	    tr.appendChild(td);
	    td.setAttribute("width", pcentpassed+"%");
	    td.setAttribute("class", (wasdoctored) ? "dpassed" : "cpassed");
	    t = dashboard.createTextNode(pcentpassed+"%");
	    td.appendChild(t);
	}
	if (pcentfailed > 0) {
	    td = dashboard.createElement("td");
	    tr.appendChild(td);
	    td.setAttribute("width", pcentfailed+"%");
	    td.setAttribute("class", "cfailed");
	    t = dashboard.createTextNode(pcentfailed+"%");
	    td.appendChild(t);
	}
	if (pcentexcluded > 0) {
	    td = dashboard.createElement("td");
	    tr.appendChild(td);
	    td.setAttribute("width", pcentexcluded+"%");
	    td.setAttribute("class", "cexcl");
	    t = dashboard.createTextNode(pcentexcluded+"%");
	    td.appendChild(t);
	}
	return table;
    }

    void addProgressBar() {
	Element table = dashboard.createElement("table");
	Element tr = addTag(table, "tr");
	Node n;
	addTagValue(tr, "th", "Toolkit");
	addTagValue(tr, "th", "Results");
	for (int i=0; i<nbreports; i++) {
	    Document d = documents.elementAt(i);
	    tr = addTag(table, "tr");
	    Element td = dashboard.createElement("td");
	    tr.appendChild(td);
	    Element a  = dashboard.createElement("a");
	    a.setAttribute("href", reportnames.elementAt(i).getName());
	    Text t = dashboard.createTextNode(toolkitnames[i]+" "+toolkitversions[i]);
	    a.appendChild(t);
	    td.appendChild(a);
	    if (toolkitbindings[i] != null) {
		t = dashboard.createTextNode(" ("+toolkitbindings[i]+")");
		td.appendChild(t);
	    }
	    td = dashboard.createElement("td");
	    td.appendChild(createProgressBar(testspassed[i], testsfailed[i], 
					     testsskipped[i], doctored[i]));
	    tr.appendChild(td);
	}
	Element e;
	e = dashboard.getElementById("toolkitgraphs");
	e.appendChild(table);
    }

    // TODO sort example names?
    void addReportTable() {
	Text t;
	Element table = dashboard.createElement("table");
	Element tr = addTag(table, "tr");
	addTagValue(tr, "th", " ");
	for (int i=0; i<nbreports; i++) {
	    if (toolkitbindings[i] == null) {
		addTagValue(tr, "th", toolkitnames[i]);
	    } else {
		Element e = addTagValue(tr, "th", toolkitnames[i]);
		Element br = dashboard.createElement("br");
		t = dashboard.createTextNode("("+toolkitbindings[i]+")");
		e.appendChild(br);
		e.appendChild(t);
	    }
	}
	tr = addTag(table, "tr");
	addTagValue(tr, "th", " ");
	for (int i=0; i<nbreports; i++) {
	    addTagValue(tr, "th", toolkitversions[i]);
	}
	Iterator<String> e;
	TreeSet<String> ts = null;
	Element td,a;
	String href;
	if (reportmode.equals("basic")) {
	    ts = new TreeSet<String>(basictests);
	} else if (reportmode.equals("advanced")) {
	    ts = new TreeSet<String>(advancedtests);
	} else if (reportmode.equals("all")) {
	    ts = new TreeSet<String>(basictests);
	    ts.addAll(advancedtests);
	} else {
	    ts = new TreeSet<String>(pendingtests);
	}
	e = ts.iterator();
	boolean odd = false;
	while (e.hasNext()) {
	    String displayname = null;
	    String testn = e.next();
	    tr = addTag(table, "tr");
	    tr.setAttribute("class", (odd ? "odd" : "even"));
	    tr.setAttribute("id", testn);
	    odd = !odd;
	    td = addTag(tr, "td");
	    td.setAttribute("class", "tname");
	    String pattern = instex.get(testn);
	    if (reportmode.equals("all")) {
		String classification = extable.get(pattern); 
		displayname = testn + " ["+classification+"]";
	    } else {
		displayname = testn;
	    }
	    a = addTagValue(td, "a", displayname);
	    href = EXAMPLENS+pattern+'/';
	    a.setAttribute("href", href);
	    for (int j=0; j<nbreports; j++) {
		Element reportresult;
		Document report = documents.elementAt(j);
		reportresult = report.getElementById(testn);
		if (reportresult == null) {
		    addTagValue(tr, "td", "skipped");
		    continue;
		}
		String outcome = reportresult.getAttribute("class");
		td = addTag(tr, "td");
		if ("passed".equals(outcome)) {
		    td.setAttribute("class", 
				    (doctored[j]) ? "dpassed" : "cpassed");
		    a = addTagValue(td, "a", "passed");
		} else {
		    td.setAttribute("class", "cfailed");
		    a = addTagValue(td, "a", "failed");
		}
		href = reportnames.elementAt(j).getName()+'#'+testn;
		a.setAttribute("href", href);
		a.setAttribute("title", toolkitnames[j]+" "+
			       toolkitversions[j] + (
			       (toolkitbindings[j] == null ) ? "" : 
			       " ("+toolkitbindings[j]+")"));
			       
	    }
	}
	Element el;
	el = dashboard.getElementById("resulttable");
	el.appendChild(table);
    }

    void processReports() {
	initDashboard();
	initTests();
	toolkitnames    = new String[nbreports];
	toolkitversions = new String[nbreports];
	toolkitmappings = new String[nbreports];
	toolkitlinks    = new String[nbreports];
	toolkitbindings = new String[nbreports];
	testspassed     = new int[nbreports];
	testsfailed     = new int[nbreports];
	testsskipped    = new int[nbreports];
	doctored        = new boolean[nbreports];

	for (int i=0; i<nbreports; i++) {
	    Element tname;
	    Node n;
	    Document curdoc;
	    
	    curdoc = documents.elementAt(i);
	    tname = curdoc.getElementById("doctored");
	    doctored[i] = (tname != null);

	    tname = curdoc.getElementById("toolkitname");
	    n = tname.getFirstChild();
	    if (n.getNodeType() != Node.TEXT_NODE) {
		System.err.println("*** Error processing: "+tname);
		continue;
	    }
	    toolkitnames[i] = n.getNodeValue();

	    tname = curdoc.getElementById("toolkitversion");
	    n = tname.getFirstChild();
	    if (n.getNodeType() != Node.TEXT_NODE) {
		System.err.println("*** Error processing: "+tname);
		continue;
	    }
	    toolkitversions[i] = n.getNodeValue();
	    
	    tname = curdoc.getElementById("toolkitmapping");
	    n = tname.getFirstChild();
	    if (n.getNodeType() != Node.TEXT_NODE) {
		System.err.println("*** Error processing: "+tname);
		continue;
	    }
	    toolkitmappings[i] = n.getNodeValue();

	    tname = curdoc.getElementById("toolkitbinding");
	    n = tname.getFirstChild();
	    if (n.getNodeType() != Node.TEXT_NODE) {
		System.err.println("*** Error processing: "+tname);
		continue;
	    }
	    String tval = n.getNodeValue();
	    toolkitbindings[i] = (tval.equals("n.a.") ? null : tval);

	    tname = curdoc.getElementById("toolkitlink");
	    NodeList nl = tname.getElementsByTagName("a");
	    tname = (Element) nl.item(0);
	    n = tname.getFirstChild();
	    if (n.getNodeType() != Node.TEXT_NODE) {
		System.err.println("*** Error processing: "+tname);
		continue;
	    }
	    toolkitlinks[i] = n.getNodeValue();
	    

	    System.err.println("*** toolkitname: "+toolkitnames[i] + " ("+
			       toolkitversions[i]+") "+ 
			       ((toolkitbindings[i] != null) ? "[" + 
				toolkitbindings[i]+"] " : ") " +
				toolkitmappings[i]));
	}
	System.err.println("*** Adding timestamp");
	addTimeStamp();
	System.err.println("*** Adding type of report");
	addReportType();
	System.err.println("*** Adding Test result numbers");
	addSummary();
	System.err.println("*** Adding progress bars for toolkits");
	addProgressBar();
	System.err.println("*** Adding report table");
	addReportTable();
    }

    void doStuff(String[] args) {
	reportnames = new Vector<File>();
	
        for (int i = 0 ; i < args.length ; i++) {
	    String filename;
	    if ( args[i].equals ("-root") ) {
		exampleuri = args[++i];
	    } else if ( args[i].equals ("-basic") ) {
		reportmode = "basic";
	    } else if ( args[i].equals ("-advanced") ) {	   
		reportmode = "advanced";
	    } else if ( args[i].equals ("-all") ) {	   
		reportmode = "all";
	    } else if (args[i].equals ("-o")) {
		filename = args[++i];
		outputfile = new File(filename);
		if (!outputfile.exists()) {
		    try {
			outputfile.createNewFile();
		    } catch (IOException ieox) {
			System.err.println("*** FATAL, can't create: "+filename);
			System.exit(1);
		    }
		}
		if (!outputfile.canWrite()) {
		    System.err.println("*** FATAL, can't write on: "+filename);
		    System.exit(1);
		}
	    } else {
		filename = args[i];
		File f = new File(filename);
		if (!f.exists()) {
		    System.err.println("*** FATAL, can't read: "+filename);
		    System.exit(1);
		}
		reportnames.add(f);
	    }
	}
	parseReports();
	processReports();
	printDashboard();
    }
	
    public static void main(String[] argv) {
	new dashboard().doStuff(argv);
    }
}
