/*
 * JasperReports - Free Java Reporting Library.
 * Copyright (C) 2001 - 2013 Jaspersoft Corporation. All rights reserved.
 * http://www.jaspersoft.com
 *
 * Unless you have purchased a commercial license agreement from Jaspersoft,
 * the following license terms apply:
 *
 * This program is part of JasperReports.
 *
 * JasperReports is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * JasperReports 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with JasperReports. If not, see <http://www.gnu.org/licenses/>.
 */

import java.io.File;
import java.lang.reflect.Method;
import java.net.URI;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperPrintManager;
import net.sf.jasperreports.engine.export.JRCsvExporter;
import net.sf.jasperreports.engine.export.JRRtfExporter;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.export.JRXml4SwfExporter;
import net.sf.jasperreports.engine.export.oasis.JROdsExporter;
import net.sf.jasperreports.engine.export.oasis.JROdtExporter;
import net.sf.jasperreports.engine.export.ooxml.JRDocxExporter;
import net.sf.jasperreports.engine.export.ooxml.JRPptxExporter;
import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.export.SimpleExporterInput;
import net.sf.jasperreports.export.SimpleHtmlExporterOutput;
import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput;
import net.sf.jasperreports.export.SimpleWriterExporterOutput;
import net.sf.jasperreports.export.SimpleXlsReportConfiguration;
import net.sf.jasperreports.export.SimpleXlsxReportConfiguration;
import edu.stanford.ejalbert.BrowserLauncher;

/**
 * @author Lucian Chirita (lucianc@users.sourceforge.net)
 * @version $Id: OFCApp.java 6805 2014-01-10 12:42:19Z teodord $
 */
public class OFCApp
{

	private static final int HTTP_PORT = 7162;

	/**
	 *
	 */
	private static final String TASK_FILL = "fill";
	private static final String TASK_PRINT = "print";
	private static final String TASK_PDF = "pdf";
	private static final String TASK_XML = "xml";
	private static final String TASK_XML_EMBED = "xmlEmbed";
	private static final String TASK_HTML = "html";
	private static final String TASK_RTF = "rtf";
	private static final String TASK_XLS = "xls";
	private static final String TASK_JXL = "jxl";
	private static final String TASK_CSV = "csv";
	private static final String TASK_ODT = "odt";
	private static final String TASK_ODS = "ods";
	private static final String TASK_DOCX = "docx";
	private static final String TASK_XLSX = "xlsx";
	private static final String TASK_PPTX = "pptx";
	private static final String TASK_XHTML = "xhtml";
	private static final String TASK_XML4SWF = "xml4swf";
	private static final String TASK_VIEW_HTML = "viewHtml";
	
	
	/**
	 *
	 */
	@SuppressWarnings("deprecation")
	public static void main(String[] args)
	{
		if(args.length == 0)
		{
			usage();
			return;
		}
				
		String taskName = args.length > 0 ? args[0] : null;
		String fileName = args.length > 1 ? args[1] : null;

		try
		{
			long start = System.currentTimeMillis();
			if (TASK_FILL.equals(taskName))
			{
				JasperFillManager.fillReportToFile(fileName, null, getConnection());
				System.err.println("Filling time : " + (System.currentTimeMillis() - start));
			}
			else if (TASK_PRINT.equals(taskName))
			{
				JasperPrintManager.printReport(fileName, true);
				System.err.println("Printing time : " + (System.currentTimeMillis() - start));
			}
			else if (TASK_PDF.equals(taskName))
			{
				JasperExportManager.exportReportToPdfFile(fileName);
				System.err.println("PDF creation time : " + (System.currentTimeMillis() - start));
			}
			else if (TASK_RTF.equals(taskName))
			{
				File sourceFile = new File(fileName);
		
				JasperPrint jasperPrint = (JasperPrint)JRLoader.loadObject(sourceFile);
		
				File destFile = new File(sourceFile.getParent(), jasperPrint.getName() + ".rtf");
				
				JRRtfExporter exporter = new JRRtfExporter();
				
				exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
				exporter.setExporterOutput(new SimpleWriterExporterOutput(destFile));
				
				exporter.exportReport();

				System.err.println("RTF creation time : " + (System.currentTimeMillis() - start));
			}
			else if (TASK_XML.equals(taskName))
			{
				JasperExportManager.exportReportToXmlFile(fileName, false);
				System.err.println("XML creation time : " + (System.currentTimeMillis() - start));
			}
			else if (TASK_XML_EMBED.equals(taskName))
			{
				JasperExportManager.exportReportToXmlFile(fileName, true);
				System.err.println("XML creation time : " + (System.currentTimeMillis() - start));
			}
			else if (TASK_HTML.equals(taskName))
			{
				JasperExportManager.exportReportToHtmlFile(fileName);
				System.err.println("HTML creation time : " + (System.currentTimeMillis() - start));
			}
			else if (TASK_XLS.equals(taskName))
			{
				File sourceFile = new File(fileName);
		
				JasperPrint jasperPrint = (JasperPrint)JRLoader.loadObject(sourceFile);
		
				File destFile = new File(sourceFile.getParent(), jasperPrint.getName() + ".xls");
				
				JRXlsExporter exporter = new JRXlsExporter();
				
				exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
				exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(destFile));
				SimpleXlsReportConfiguration configuration = new SimpleXlsReportConfiguration();
				configuration.setOnePagePerSheet(true);
				exporter.setConfiguration(configuration);
				
				exporter.exportReport();

				System.err.println("XLS creation time : " + (System.currentTimeMillis() - start));
			}
			else if (TASK_JXL.equals(taskName))
			{
				File sourceFile = new File(fileName);

				JasperPrint jasperPrint = (JasperPrint)JRLoader.loadObject(sourceFile);

				File destFile = new File(sourceFile.getParent(), jasperPrint.getName() + ".jxl.xls");

				net.sf.jasperreports.engine.export.JExcelApiExporter exporter = 
					new net.sf.jasperreports.engine.export.JExcelApiExporter();

				exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
				exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(destFile));
				net.sf.jasperreports.export.SimpleJxlReportConfiguration configuration = 
					new net.sf.jasperreports.export.SimpleJxlReportConfiguration();
				configuration.setOnePagePerSheet(true);
				exporter.setConfiguration(configuration);

				exporter.exportReport();

				System.err.println("XLS creation time : " + (System.currentTimeMillis() - start));
			}
			else if (TASK_CSV.equals(taskName))
			{
				File sourceFile = new File(fileName);
		
				JasperPrint jasperPrint = (JasperPrint)JRLoader.loadObject(sourceFile);
		
				File destFile = new File(sourceFile.getParent(), jasperPrint.getName() + ".csv");
				
				JRCsvExporter exporter = new JRCsvExporter();
				
				exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
				exporter.setExporterOutput(new SimpleWriterExporterOutput(destFile));
				
				exporter.exportReport();

				System.err.println("CSV creation time : " + (System.currentTimeMillis() - start));
			}
			else if (TASK_ODT.equals(taskName))
			{
				File sourceFile = new File(fileName);
		
				JasperPrint jasperPrint = (JasperPrint)JRLoader.loadObject(sourceFile);
		
				File destFile = new File(sourceFile.getParent(), jasperPrint.getName() + ".odt");
				
				JROdtExporter exporter = new JROdtExporter();
				
				exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
				exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(destFile));
				
				exporter.exportReport();

				System.err.println("ODT creation time : " + (System.currentTimeMillis() - start));
			}
			else if (TASK_ODS.equals(taskName))
			{
				File sourceFile = new File(fileName);
		
				JasperPrint jasperPrint = (JasperPrint)JRLoader.loadObject(sourceFile);
		
				File destFile = new File(sourceFile.getParent(), jasperPrint.getName() + ".ods");
				
				JROdsExporter exporter = new JROdsExporter();
				
				exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
				exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(destFile));
				
				exporter.exportReport();

				System.err.println("ODS creation time : " + (System.currentTimeMillis() - start));
			}
			else if (TASK_DOCX.equals(taskName))
			{
				File sourceFile = new File(fileName);
		
				JasperPrint jasperPrint = (JasperPrint)JRLoader.loadObject(sourceFile);
		
				File destFile = new File(sourceFile.getParent(), jasperPrint.getName() + ".docx");
				
				JRDocxExporter exporter = new JRDocxExporter();
				
				exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
				exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(destFile));
				
				exporter.exportReport();

				System.err.println("DOCX creation time : " + (System.currentTimeMillis() - start));
			}
			else if (TASK_XLSX.equals(taskName))
			{
				File sourceFile = new File(fileName);
		
				JasperPrint jasperPrint = (JasperPrint)JRLoader.loadObject(sourceFile);
		
				File destFile = new File(sourceFile.getParent(), jasperPrint.getName() + ".xlsx");
				
				JRXlsxExporter exporter = new JRXlsxExporter();
				
				exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
				exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(destFile));
				SimpleXlsxReportConfiguration configuration = new SimpleXlsxReportConfiguration();
				configuration.setOnePagePerSheet(true);
				exporter.setConfiguration(configuration);
				
				exporter.exportReport();

				System.err.println("XLSX creation time : " + (System.currentTimeMillis() - start));
			}
			else if (TASK_PPTX.equals(taskName))
			{
				File sourceFile = new File(fileName);
		
				JasperPrint jasperPrint = (JasperPrint)JRLoader.loadObject(sourceFile);
		
				File destFile = new File(sourceFile.getParent(), jasperPrint.getName() + ".pptx");
				
				JRPptxExporter exporter = new JRPptxExporter();
				
				exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
				exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(destFile));
				
				exporter.exportReport();

				System.err.println("PPTX creation time : " + (System.currentTimeMillis() - start));
			}
			else if (TASK_XHTML.equals(taskName))
			{
				File sourceFile = new File(fileName);
		
				JasperPrint jasperPrint = (JasperPrint)JRLoader.loadObject(sourceFile);
		
				File destFile = new File(sourceFile.getParent(), jasperPrint.getName() + ".x.html");
				
				net.sf.jasperreports.engine.export.JRXhtmlExporter exporter = 
					new net.sf.jasperreports.engine.export.JRXhtmlExporter();
				
				exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
				exporter.setExporterOutput(new SimpleHtmlExporterOutput(destFile));
				
				exporter.exportReport();

				System.err.println("XHTML creation time : " + (System.currentTimeMillis() - start));
			}
			else if (TASK_XML4SWF.equals(taskName))
			{
				File sourceFile = new File(fileName);
		
				JasperPrint jasperPrint = (JasperPrint)JRLoader.loadObject(sourceFile);
		
				File destFile = new File(sourceFile.getParent(), jasperPrint.getName() + ".xml4swf");
				
				JRXml4SwfExporter exporter = new JRXml4SwfExporter();
				
				exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
				exporter.setExporterOutput(new SimpleWriterExporterOutput(destFile));
				
				exporter.exportReport();

				System.err.println("XML4SWF creation time : " + (System.currentTimeMillis() - start));
			}
			else if (TASK_VIEW_HTML.equals(taskName))
			{
				launchReport();
			}
			else
			{
				usage();
			}
		}
		catch (JRException e)
		{
			e.printStackTrace();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	protected static void launchReport() throws Exception
	{
		System.out.println("Starting an embedded web server on port " + HTTP_PORT);
		System.out.println("Kill/interrupt this process to shutdown the server");
		
		//starting the web server
		new NanoHTTPD(HTTP_PORT);
		
		//launching the browser
		launchBrowser("html");
		launchBrowser("x.html");
		
		//waiting for a long time so that the server does not shut down
		try
		{
			Thread.sleep(48 * 60 * 60 * 1000);
		}
		catch (InterruptedException e)
		{
			//interrupted
		}
	}

	protected static void launchBrowser(String extension)
	{
		String reportURI = "http://localhost:" + HTTP_PORT + "/OpenFlashChartReport." + extension;
		
		System.out.println("Launching a browser to for " + reportURI);
		System.out.println("If a browser is not launched, please navigate to this URL manually");
		
		boolean launched = false;
		try
		{
			// attempting Java 1.6
			// ugly reflection code to avoid a dependency on Java 1.6
			Class desktopClass = Class.forName("java.awt.Desktop");
			Method isDesktopSupportedMethod = desktopClass.getMethod("isDesktopSupported", 
					(java.lang.Class[]) null);
			Boolean isDesktopSupported = (Boolean) isDesktopSupportedMethod.invoke(null, 
					(java.lang.Object[]) null);
			if (isDesktopSupported.booleanValue())
			{
				Method getDesktopMethod = desktopClass.getMethod("getDesktop", 
						(java.lang.Class[]) null);
				Object desktop = getDesktopMethod.invoke(null, (java.lang.Object[]) null);
				Method browseMethod = desktopClass.getMethod("browse", new Class[]{URI.class});
				browseMethod.invoke(desktop, new Object[]{new URI(reportURI)});
				launched = true;
			}
		}
		catch (Exception e)
		{
			// not Java 1.6?
			System.out.println("Failed to launch a browser using Java 1.6 APIs");
		}
		
		if (!launched)
		{
			try
			{
				new BrowserLauncher().openURLinBrowser(reportURI);
			}
			catch (Exception e)
			{
				System.out.println("Failed to launch a browser: " + e.getMessage());
			}
		}
	}
	
	/**
	 *
	 */
	private static void usage()
	{
		System.out.println( "OFCApp usage:" );
		System.out.println( "\tjava OFCApp task file" );
		System.out.println( "\tTasks : fill | print | pdf | xml | xmlEmbed | html | rtf | xls | jxl | csv | odt | ods | docx | xlsx | pptx | xhtml | xml4swf | viewHtml" );
	}


	private static Connection getConnection() throws ClassNotFoundException, SQLException
	{
		//Change these settings according to your local configuration
		String driver = "org.hsqldb.jdbcDriver";
		String connectString = "jdbc:hsqldb:hsql://localhost";
		String user = "sa";
		String password = "";


		Class.forName(driver);
		Connection conn = DriverManager.getConnection(connectString, user, password);
		return conn;
	}


}
