/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id$ */

package image.writer;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.font.TextAttribute;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.text.AttributedString;

import org.apache.commons.io.IOUtils;
import org.apache.xmlgraphics.image.writer.ImageWriter;
import org.apache.xmlgraphics.image.writer.ImageWriterParams;
import org.apache.xmlgraphics.image.writer.ImageWriterRegistry;

public class ImageWriterExample1 {

    /**
     * Paints a few things on a Graphics2D instance.
     * @param g2d the Graphics2D instance
     * @param pageNum a page number
     */
    protected void paintSome(Graphics2D g2d, int pageNum) {
        //Paint a bounding box
        g2d.drawRect(0, 0, 400, 200);

        //A few rectangles rotated and with different color
        Graphics2D copy = (Graphics2D)g2d.create();
        int c = 12;
        for (int i = 0; i < c; i++) {
            float f = ((i + 1) / (float)c);
            Color col = new Color(0.0f, 1 - f, 0.0f);
            copy.setColor(col);
            copy.fillRect(70, 90, 50, 50);
            copy.rotate(-2 * Math.PI / (double)c, 70, 90);
        }
        copy.dispose();

        //Some text
        copy = (Graphics2D)g2d.create();
        copy.rotate(-0.25);
        copy.setColor(Color.RED);
        copy.setFont(new Font("sans-serif", Font.PLAIN, 36));
        copy.drawString("Hello world!", 140, 140);
        copy.setColor(Color.RED.darker());
        copy.setFont(new Font("serif", Font.PLAIN, 36));
        copy.drawString("Hello world!", 140, 180);
        copy.dispose();

        //Try attributed text
        AttributedString aString = new AttributedString("This is attributed text.");
        aString.addAttribute(TextAttribute.FAMILY, "SansSerif");
        aString.addAttribute(TextAttribute.FAMILY, "Serif", 8, 18);
        aString.addAttribute(TextAttribute.FOREGROUND, Color.orange, 8, 18);
        g2d.drawString(aString.getIterator(), 250, 170);

        g2d.drawString("Page: " + pageNum, 250, 190);
    }

    /**
     * Creates a bitmap file. We paint a few things on a bitmap and then save the bitmap using
     * an ImageWriter.
     * @param outputFile the target file
     * @param format the target format (a MIME type, ex. "image/png")
     * @throws IOException In case of an I/O error
     */
    public void generateBitmapUsingJava2D(File outputFile, String format)
                throws IOException {
        //String compression = "CCITT T.6";
        String compression = "PackBits";
        boolean monochrome = compression.startsWith("CCITT"); //CCITT is for 1bit b/w only

        BufferedImage bimg;
        if (monochrome) {
            bimg = new BufferedImage(400, 200, BufferedImage.TYPE_BYTE_BINARY);
        } else {
            bimg = new BufferedImage(400, 200, BufferedImage.TYPE_INT_RGB);
        }

        Graphics2D g2d = bimg.createGraphics();
        g2d.setBackground(Color.white);
        g2d.clearRect(0, 0, 400, 200);
        g2d.setColor(Color.black);

        //Paint something
        paintSome(g2d, 1);

        OutputStream out = new java.io.FileOutputStream(outputFile);
        out = new java.io.BufferedOutputStream(out);
        try {

            ImageWriter writer = ImageWriterRegistry.getInstance().getWriterFor(format);
            ImageWriterParams params = new ImageWriterParams();
            params.setCompressionMethod(compression);
            params.setResolution(72);
            writer.writeImage(bimg, out, params);

        } finally {
            IOUtils.closeQuietly(out);
        }
    }

    /**
     * Command-line interface
     * @param args command-line arguments
     */
    public static void main(String[] args) {
        try {
            File targetDir;
            if (args.length >= 1) {
                targetDir = new File(args[0]);
            } else {
                targetDir = new File(".");
            }
            if (!targetDir.exists()) {
                System.err.println("Target Directory does not exist: " + targetDir);
            }
            File outputFile = new File(targetDir, "eps-example1.tif");
            ImageWriterExample1 app = new ImageWriterExample1();
            app.generateBitmapUsingJava2D(outputFile, "image/tiff");
            System.out.println("File written: " + outputFile.getCanonicalPath());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
