/*
 * Copyright (C) 2005, 2006 Mikhail A. Kryshen
 *
 * $Id: ImageConverter.java,v 1.1.1.1 2006/05/16 14:04:09 mikhail Exp $
 */

package kryshen.tema;

import java.util.*;
import java.io.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.AffineTransform;
import javax.imageio.*;
import javax.imageio.stream.*;

/**
 * Class defines static method to convert images to specified format.
 *
 * @author Mikhail A. Kryshen
 */
class ImageConverter {    

    static void convert(File source, File dest, String format,
		 int maxWidth, int maxHeight) 
	throws IOException, InterruptedException {
	
	System.err.print("Converting image " + source + "... ");

	if (source.lastModified() < dest.lastModified()) {
	    System.err.println(dest + " is up to date.");
	    return;
	}

	BufferedImage image = ImageIO.read(source);

	//int type = image.getType();
	//final int type = BufferedImage.TYPE_INT_RGB;
	//ColorModel cm = image.getColorModel();

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

	//boolean scale = false;

	float scale = 1f;

	if (maxWidth > 0 && w > maxWidth)
	    scale = (float)maxWidth / w;
	
	if (maxHeight > 0 && h * scale > maxHeight)
	    scale = (float)maxHeight / h;

	if (scale != 1f) {
	    w *= scale; h *= scale;

// 	    ColorModel cm = image.getColorModel();	    
// 	    boolean alphaPremultiplied = cm.isAlphaPremultiplied();
// 	    WritableRaster raster = cm.createCompatibleWritableRaster(w, h);
// 	    BufferedImage scaled = new BufferedImage
// 		(cm, raster, alphaPremultiplied, null);

// 	    BufferedImage scaled = new BufferedImage(w, h, image.getType());
	    

 	    Image scaled = image.getScaledInstance(w, h, Image.SCALE_SMOOTH);

 	    ColorModel cm = image.getColorModel();	    
 	    boolean alphaPremultiplied = image.isAlphaPremultiplied();
 	    WritableRaster raster = cm.createCompatibleWritableRaster(w, h);
 	    image = new BufferedImage(cm, raster, alphaPremultiplied, null);

	    Graphics g = image.getGraphics();
	    g.drawImage(scaled, 0, 0, null);
	    g.dispose();

//	    image = scale(image, scaled, scale);
//	    Graphics2D g = scaled.createGraphics();
//	    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
// 			       RenderingHints.VALUE_INTERPOLATION_BILINEAR);
// 	    System.err.print(" " + g.drawImage(image, 0, 0, w, h, null) + " ");
// 	    g.dispose();
// 	    image = scaled;
	}
       
	File parent = dest.getParentFile();
	if (parent != null) parent.mkdirs();

 	ImageIO.write(image, format, dest);
	System.err.println("saved " + dest + ".");	
    }

//     public static ColorModel getColorModel(Image image) 
// 	throws InterruptedException {

// 	PixelGrabber grabby = new PixelGrabber(image, 0, 0, 1, 1, false);
// 	if (!grabby.grabPixels())
// 	    throw new RuntimeException("pixel grab fails");
// 	return grabby.getColorModel();
//     }

//     private static BufferedImage scale(BufferedImage image, 
// 				       BufferedImage dest, 
// 				       float scale) {

// 	AffineTransform tx = new AffineTransform();
// 	tx.scale(scale, scale);

//  	AffineTransformOp op = new AffineTransformOp
//  	    (tx, AffineTransformOp.TYPE_BILINEAR);

// 	return op.filter(image, dest);
//     }

    // TEST
    
    public static void main(String[] args) 
	throws IOException, InterruptedException {

	convert(new File(args[0]), new File(args[1]), "png", 300, 300);
    }


//     public static BufferedImage toBufferedImage(Image image, ColorModel cm) {
// 	if (image instanceof BufferedImage)
// 	    return (BufferedImage)image;

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

// 	boolean alphaPremultiplied = cm.isAlphaPremultiplied();
// 	WritableRaster raster = cm.createCompatibleWritableRaster(w, h);
// 	BufferedImage result = new BufferedImage(cm, raster, alphaPremultiplied, null);
// 	Graphics2D g = result.createGraphics();

// 	g.drawImage(image, 0, 0, null);
// 	g.dispose();

// 	return result;
//     }
}


// This is how I'd recommend it in JDK1.4 using javax.imageio.ImageIO to
// do the reading/writing and Java2D to do the scaling.

// // read in the original image
// BufferedImage in = ImageIO.read(new File("in.jpg"));

// // create a new image of the smaller size
// BufferedImage out = new BufferedImage(newWidth, newHeight);

// // get the graphics associated with the new image
// Graphics g = out.getGraphics();

// // draw the original image into the new image, scaling
// // on the fly
// g.drawImage(in, newWidth, newHeight, null);

// // dispose the graphics object
// g.dispose();

// // write out the new image
// ImagIO.write("out.jpg", "jpeg", new File("out.jpg"));

// ------------------------------------------

// For nicer scaling, you could add a rendering hint to the graphics
// object before painting.

// ie.

// Graphics2D g2d = (Graphics2D)g;
// g2d.setRenderingHint(RenderingHints.KEY_INTEPOLATION,
//                      RenderingHints.VALUE_INTERPOLATION_BILINEAR);

// or use VALUE_INTERPOLATION_BICUBIC for the best.

// But as you can guess, nicer == slower.

// Shannon Hickey
// shann...@swingteam.com
// Swing Team  http://TheSwingConnection.com  http://TheJavaTutorial.com
// Java Software,  a division of Sun Microsystems, Inc.