/*
 *  Copyright (C) 2005, 2006 Mikhail A. Kryshen
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *  $Id: ImageConverter.java,v 1.4 2006/12/14 19:44:32 mikhail Exp $
 */

package kryshen.tema.functions;

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.*;

import kryshen.tema.*;

/**
 * Convert images to specified format.
 *
 * @author Mikhail A. Kryshen
 */
public class ImageConverter extends Function {    

    public static final Function IMAGE = new ImageConverter();

    public int invoke(FunctionDataParser fdp, Writer out)
        throws IOException, TemplateException {
        
        String arg0 = fdp.getNextArg();
        String arg1 = fdp.getNextArg();
        String arg2 = fdp.getNextArg();
        int arg3 = fdp.hasMoreData() ? 
            Integer.parseInt(fdp.getNextArg()) : -1;
        int arg4 = fdp.hasMoreData() ? 
            Integer.parseInt(fdp.getNextArg()) : -1;
        
        File source = new File
            (Tema.getProperty("resource_base"), arg0);
        
        try {
            convert
                (source,                  /* source file */
                 new File(arg1),          /* dest file */
                 arg2,                    /* format */
                 arg3,                    /* max width */
                 arg4);                   /* max height */
        } catch (Exception e) {
            System.err.println(e);
            return 0;
        }
        
        out.write(arg1);
        return 1;
    }    
    
    public 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;
//     }
}