package be.msyben.vinylManager.pdf;

import be.msyben.vinylManager.entities.Collection;
import be.msyben.vinylManager.exceptions.VinylManagerException;
import be.msyben.vinylManager.pdf.datasources.ListeCourt;
import be.msyben.vinylManager.pdf.datasources.ListeLong;
import be.msyben.vinylManager.properties.Language;
import be.msyben.vinylManager.tools.Tools;
import be.msyben.vinylManager.tools.log.VinylManagerLogger;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.export.JRPdfExporter;

/**
 * Cette classe permet de générer les rapports en pdf.
 *
 * @author Mathieu Syben
 */
public class ReportGenerator {

    /**
     * Le path des fichiers jrxml
     */
    private static String jrxmlPath = null;

    static {
        jrxmlPath = "/" + ReportGenerator.class.getPackage().getName().replaceAll("\\.", "/") + "/jrxml/";
    }

    /**
     * Permet de créer les rapport. Est utilisé MANUELLEMENT uniquement lors
     * d'un nouveau et d'un changement de rapport.
     */
    public static void createJasper() {
        try {
            String path = "src" + File.separator + ReportGenerator.class.getPackage().getName().replace(".", File.separator);
            path += File.separator + "jrxml" + File.separator;
            JasperCompileManager.compileReportToFile(path + "ListeVinyleCourt.jrxml", path + "ListeVinyleCourt.jasper");
            JasperCompileManager.compileReportToFile(path + "ListeVinyleLong.jrxml", path + "ListeVinyleLong.jasper");
        } catch (JRException ex) {
            VinylManagerLogger.log( ex);
        }

    }

    /**
     * Génère un document
     *
     * @param documentName Le nom du document (du fichier jrxml à charger)
     * @param reportParameters Les paramètres pour la génération du document
     * @param jrds la datasource pour le document
     * @return Le contenu du document
     */
    private static byte[] generateDocument(String documentName, Map reportParameters, JRDataSource jrds) throws JRException {


        JasperPrint jasperPrint;
        InputStream reportIS = ReportGenerator.class.getResourceAsStream(jrxmlPath + documentName + ".jasper");
        try {
            jasperPrint = JasperFillManager.fillReport(reportIS, reportParameters, jrds);
        } catch (JRException ex) {
            throw ex;
        } finally {
            Tools.closeQuietly(reportIS);
        }

        JRPdfExporter exporter = new JRPdfExporter();

        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
        exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, baos);

        exporter.exportReport();

        byte[] ret = baos.toByteArray();

        Tools.closeQuietly(baos);

        return ret;
    }

    /**
     * Génère le rapport court en pdf
     *
     * @param collection la collection
     * @return le contenu du pdf
     * @throws VinylManagerException en cas d'erreur
     */
    public static byte[] genererRapportCourt(Collection collection) throws VinylManagerException {

        Map<String, String> parameters = new HashMap<String, String>();
        parameters.put("TITRE", Language.getInstance().get("pdf.titre"));

        byte[] contenu;
        try {
            contenu = generateDocument("ListeVinyleCourt", parameters, new ListeCourt(collection));
        } catch (JRException ex) {
            VinylManagerLogger.log( ex);
            throw new VinylManagerException(Language.getInstance().get("pdf.error"), ex);
        }

        return contenu;

    }

    /**
     * Génère le rapport long en pdf
     *
     * @param collection la collection
     * @return le contenu du pdf
     * @throws VinylManagerException en cas d'erreur
     */
    public static byte[] genererRapportLong(Collection collection) throws VinylManagerException {

        Map<String, String> parameters = new HashMap<String, String>();
        parameters.put("TITRE", Language.getInstance().get("pdf.titre"));

        byte[] contenu;
        try {
            contenu = generateDocument("ListeVinyleLong", parameters, new ListeLong(collection));
        } catch (JRException ex) {
            VinylManagerLogger.log( ex);
            throw new VinylManagerException(Language.getInstance().get("pdf.error"), ex);
        }

        return contenu;

    }
}
