/* OdLib_Css- Copyright (c) 2008 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package net.mapeadores.opendocument.css.extraction;

import java.io.File;
import java.io.InputStream;
import java.io.IOException;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;


/**
 *
 * @author Vincent Calame
 */
public class CssExtraction {

    private OutputStream cssOutputStream;
    private OutputStream xmlOutputStream;
    private ZipInputStream zipInputStream;

    public CssExtraction(InputStream inputStream) {
        zipInputStream = new ZipInputStream(inputStream);
    }

    public void setCssOutputStream(OutputStream cssOutputStream) {
        this.cssOutputStream = cssOutputStream;
    }

    public void setXmlOutputStream(OutputStream xmlOutputStream) {
        this.xmlOutputStream = xmlOutputStream;
    }

    public static void extract(File odFile, File cssFile) throws IOException, TransformerException {
        extract(odFile, cssFile, null);
    }

    public static void extract(File odFile, File cssFile, File xmlFile) throws IOException, TransformerException {
        InputStream inputStream = new FileInputStream(odFile);
        OutputStream cssOutputStream = null;
        if (cssFile != null) {
            cssOutputStream = new BufferedOutputStream(new FileOutputStream(cssFile));
        }
        OutputStream xmlOutputStream = null;
        if (xmlFile != null) {
            xmlOutputStream = new BufferedOutputStream(new FileOutputStream(xmlFile));
        }
        extract(inputStream, cssOutputStream, xmlOutputStream);
        inputStream.close();
        if (xmlOutputStream != null) {
            xmlOutputStream.close();
        }
        if (cssOutputStream != null) {
            cssOutputStream.close();
        }
    }

    public static void extract(InputStream inputStream, OutputStream cssOutputStream, OutputStream xmlOutputStream) throws IOException, TransformerException {
        CssExtraction cssExtraction = new CssExtraction(inputStream);
        cssExtraction.setCssOutputStream(cssOutputStream);
        cssExtraction.setXmlOutputStream(xmlOutputStream);
        cssExtraction.extract();
    }

    public void extract() throws IOException, TransformerException {
        ZipEntry zipEntry = null;
        while ((zipEntry = zipInputStream.getNextEntry()) != null) {
            String name = zipEntry.getName();
            if (name.equals("styles.xml")) {
                byte[] content = getByteArray(zipInputStream);
                if (cssOutputStream != null) {
                    Transformer transformer = getTransformer();
                    Source source = new StreamSource(new ByteArrayInputStream(content));
                    Result result = new StreamResult(cssOutputStream);
                    transformer.transform(source, result);
                }
                if (xmlOutputStream != null) {
                    xmlOutputStream.write(content);
                }
                break;
            }
        }
    }

    private static byte[] getByteArray(ZipInputStream zipInputStream) throws IOException {
        int length = 1024;
        byte[] buffer = new byte[length];
        int p = 0;
        ByteArrayOutputStream beaos = new ByteArrayOutputStream();
        while ((p = zipInputStream.read(buffer)) != -1) {
            beaos.write(buffer, 0, p);
        }
        return beaos.toByteArray();
    }

    private static Transformer getTransformer() throws IOException {
        StreamSource streamSource = new StreamSource(CssExtraction.class.getResourceAsStream("styles.xsl"));
        TransformerFactory factory = TransformerFactory.newInstance();
        try {
            Transformer transformer = factory.newTransformer(streamSource);
            return transformer;
        } catch (TransformerConfigurationException tce) {
            throw new IllegalStateException(tce);
        }
    }

}
