package com.fitbank.pdfmerger;

import lombok.extern.slf4j.Slf4j;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.xobject.PDJpeg;
import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage;

/**
 *
 * @author FitBank CI
 */
@Slf4j
public abstract class ImagePageSource implements PageSource {

    protected abstract BufferedImage getImage() throws Exception;

    public void write(PDDocument doc) throws Exception {
        BufferedImage image = getImage();

        int w = image.getWidth();
        int h = image.getHeight();

        PDPage page = new PDPage();
        page.setMediaBox(new PDRectangle(w, h));

        File tmpFile = File.createTempFile("pdfmerger-", ".jpg");
        if (image.getColorModel().getTransparency() == Transparency.OPAQUE) {
            ImageIO.write(image, "jpg", tmpFile);
        } else {
            ImageIO.write(getNonTransparentImage(image), "jpg", tmpFile);
        }
        PDXObjectImage img = new PDJpeg(doc, new FileInputStream(tmpFile));
        
        PDPageContentStream contentStream = new PDPageContentStream(doc, page);
        contentStream.drawImage(img, 0, 0);
        contentStream.close();

        doc.addPage(page);
    }

    /**
     * Crea una nueva imagen quitando los píxeles transparentes y pintándolos
     * de blanco.
     * @param img La imagen con transparencia
     * @return Un objeto BufferedImage con los píxeles transparentes pintados de blanco sólido.
     */
    private BufferedImage getNonTransparentImage(BufferedImage img) {
        int w = img.getWidth();
        int h = img.getHeight();

        BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = bi.createGraphics();
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, w, h);
        g.drawRenderedImage(img, null);
        g.dispose();

        return bi;
    }

    public Component getPreview() {
        try {
            Image image = getImage();

            JLabel label = new JLabel(new ImageIcon(image));
            label.setSize(image.getWidth(null), image.getHeight(null));

            return label;
        } catch (Exception e) {
            log.error("", e);
            return new JLabel("Error cargando previsualización: " + e.
                    getLocalizedMessage());
        }
    }

    public void writeJPG(OutputStream out) throws Exception {
        ImageIO.write(getImage(), "jpg", out);
    }
    
}
