/**
 * @(#)PictImageReader.java  1.0  Mar 18, 2008
 *
 * Copyright (c) 2008 Werner Randelshofer, Immensee, Switzerland.
 * All rights reserved.
 *
 * You may not use, copy or modify this file, except in compliance with the
 * license agreement you entered into with Werner Randelshofer.
 * For details see accompanying license terms. 
 */

package ch.randelshofer.gui.datatransfer;

import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.lang.reflect.*;

/**
 * PictImageReader for reading clipboard images with the "images/x-pict"
 * data flavor.
 *
 * @author Werner Randelshofer
 * @version 1.0 Mar 18, 2008 Created.
 */
public class PictImageReader {
	// Converts a PICT to an AWT image using QuickTime for Java.
	// This code was contributed by Gord Peters.
	public Image getImageFromPictStream(InputStream is) {
		try {
			ByteArrayOutputStream baos= new ByteArrayOutputStream();
			// We need to strip the header from the data because a PICT file
			// has a 512 byte header and then the data, but in our case we only
			// need the data. --GP
			byte[] header= new byte[512];
			byte[] buf= new byte[4096];
			int retval= 0, size= 0;
			baos.write(header, 0, 512);
			while ( (retval= is.read(buf, 0, 4096)) > 0)
				baos.write(buf, 0, retval);		
			baos.close();
			size = baos.size();
			//IJ.log("size: "+size); IJ.wait(2000);
			if (size<=0)
				return null;
			byte[] imgBytes= baos.toByteArray();
			// Again with the uglyness.  Here we need to use the Quicktime
			// for Java code in order to create an Image object from
			// the PICT data we received on the clipboard.  However, in
			// order to get this to compile on other platforms, we use
			// the Java reflection API.
			//
			// For reference, here is the equivalent code without
			// reflection:
			//
			//
			// if (QTSession.isInitialized() == false) {
			//     QTSession.open();
			// }
			// QTHandle handle= new QTHandle(imgBytes);
			// GraphicsImporter gi=
			//     new GraphicsImporter(QTUtils.toOSType("PICT"));
			// gi.setDataHandle(handle);
			// QDRect qdRect= gi.getNaturalBounds();
			// GraphicsImporterDrawer gid= new GraphicsImporterDrawer(gi);
			// QTImageProducer qip= new QTImageProducer(gid,
			//                          new Dimension(qdRect.getWidth(),
			//                                        qdRect.getHeight()));
			// return(Toolkit.getDefaultToolkit().createImage(qip));
			//
			// --GP
			//IJ.log("quicktime.QTSession");
			Class c = Class.forName("quicktime.QTSession");
			Method m = c.getMethod("isInitialized");
			Boolean b= (Boolean)m.invoke(null, (Object[]) null);			
			if (b.booleanValue() == false) {
				m= c.getMethod("open");
				m.invoke(null);
			}
			c= Class.forName("quicktime.util.QTHandle");
			Constructor con = c.getConstructor(new Class[] {imgBytes.getClass() });
			Object handle= con.newInstance(new Object[] { imgBytes });
			String s= new String("PICT");
			c = Class.forName("quicktime.util.QTUtils");
			m = c.getMethod("toOSType", new Class[] { s.getClass() });
			Integer type= (Integer)m.invoke(null, new Object[] { s });
			c = Class.forName("quicktime.std.image.GraphicsImporter");
			con = c.getConstructor(new Class[] { type.TYPE });
			Object importer= con.newInstance(new Object[] { type });
			m = c.getMethod("setDataHandle",
			new Class[] { Class.forName("quicktime.util." + "QTHandleRef") });
			m.invoke(importer, new Object[] { handle });
			m = c.getMethod("getNaturalBounds");
			Object rect= m.invoke(importer);
			c = Class.forName("quicktime.app.view.GraphicsImporterDrawer");
			con = c.getConstructor(new Class[] { importer.getClass() });
			Object iDrawer = con.newInstance(new Object[] { importer });
			m = rect.getClass().getMethod("getWidth");
			Integer width= (Integer)m.invoke(rect);
			m = rect.getClass().getMethod("getHeight");
			Integer height= (Integer)m.invoke(rect);
			Dimension d= new Dimension(width.intValue(), height.intValue());
			c = Class.forName("quicktime.app.view.QTImageProducer");
			con = c.getConstructor(new Class[] { iDrawer.getClass(), d.getClass() });
			Object producer= con.newInstance(new Object[] { iDrawer, d });
			if (producer instanceof ImageProducer) {
				return(Toolkit.getDefaultToolkit().createImage((ImageProducer)producer));
                                }
		} catch (Exception e) {
                    //IJ.showStatus("QuickTime for java error");
                    e.printStackTrace();
                }
		return null;
    }

	// Retuns true if QuickTime for Java is installed.
	// This code was contributed by Gord Peters.
	public boolean isQTJavaInstalled() {
		boolean isInstalled = false;
		try {
			Class c= Class.forName("quicktime.QTSession");
			isInstalled = true;
		} catch (Exception e) {}
		return isInstalled;
	}
}
