/******************************************************************************
 * Copyright (c) 2002, 2010 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    IBM Corporation - initial API and implementation 
 ****************************************************************************/

package org.eclipse.gmf.runtime.draw2d.ui.render.awt.internal.svg;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.batik.transcoder.Transcoder;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.ImageTranscoder;
import org.apache.fop.svg.PDFTranscoder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.gmf.runtime.common.core.util.Log;
import org.eclipse.gmf.runtime.draw2d.ui.render.RenderInfo;
import org.eclipse.gmf.runtime.draw2d.ui.render.awt.internal.Draw2dRenderPlugin;
import org.eclipse.swt.graphics.Image;
import org.w3c.dom.Document;


/**
 * @author sshaw
 *
 * Class for conversion of SVG to different Image formats
 */
public class SVGImageConverter {
	/**
	 * Consructor to create a new instance of SVGtoBufferedImageConverter
	 */
	public SVGImageConverter() {
		// empty constructor
	}

	/**
	 * renderSVGToAWTImage
	 * Given a filename, will render the SVG file into an SWT Image
	 * 
	 * @param document Document of svg file
	 * @param RenderInfo object containing information about the size and 
	 * general data regarding how the image will be rendered.
	 * @return BufferedImage AWT image containing the rendered SVG file.
	 * @throws Exception
	 */
	public BufferedImage renderSVGToAWTImage(Document document, RenderInfo info)
		throws Exception {
		ImageTranscoderEx transcoder = new ImageTranscoderEx();
		setUpTranscoders(document, transcoder, info);
		
		return transcoder.getBufferedImage();
	}
	
	/**
	 * renderSVGtoSWTImage
	 * Given an InputStream, will render the SVG file into an SWT Image
	 * 
	 * @param document Document of svg file
	 * @param RenderInfo object containing information about the size and 
	 * general data regarding how the image will be rendered.
	 * @return Image SWT image containing the rendered SVG file.
	 * @throws Exception
	 */
	public Image renderSVGtoSWTImage(Document document, RenderInfo info)
		throws Exception {
		SWTImageTranscoder transcoder = new SWTImageTranscoder();
		try {			
			setUpTranscoders(document, transcoder, info);
			return transcoder.getSWTImage();
		} catch (Exception e) {
			Image image = transcoder.getSWTImage();
			if (image != null && !image.isDisposed()) {
				image.dispose();
			}
			throw e;
		}
	}
	
	/**
	 * renderSVGToAWTImage
	 * Given a filename, will render the SVG file into an SWT Image
	 * 
	 * @param strFileName String file path of svg file
	 * @param RenderInfo object containing information about the size and 
	 * general data regarding how the image will be rendered.
	 * @return BufferedImage AWT image containing the rendered SVG file.
	 * @throws Exception
	 */
	public BufferedImage renderSVGToAWTImage(String strFileName, RenderInfo info)
		throws Exception {
		InputStream in = new FileInputStream(strFileName);
		return renderSVGToAWTImage(in, info);
	}

	/**
	 * renderSVGToAWTImage
	 * Given a buffer, will render the SVG file into an SWT Image
	 * 
	 * @param buffer byte[] array containing an cached SVG image file.
	 * @param RenderInfo object containing information about the size and 
	 * general data regarding how the image will be rendered.
	 * @return BufferedImage AWT iimage containing the rendered SVG file.
	 * @throws Exception
	 */
	public BufferedImage renderSVGToAWTImage(byte[] buffer, RenderInfo info)
		throws Exception {
		InputStream in = new ByteArrayInputStream(buffer);
		return renderSVGToAWTImage(in, info);
	}
	
	/**
	 * setUpTranscoders
	 * sets up the transcoders with the hints based on the RenderInfo structure.
	 * 
	 * @param in
	 * @param transcoder
	 * @param info
	 */
	private void setUpTranscoders(InputStream in, Transcoder transcoder, RenderInfo info)
		throws Exception {
		initializeTranscoderFromInfo(transcoder, info);
		
		TranscoderInput input = null;
		TranscoderOutput output = null;

		input = new TranscoderInput(in);
		output = new ImageTranscoderOutput(); 
		transcoder.transcode(input, output);
	}
	
	/**
	 * setUpTranscoders
	 * sets up the transcoders with the hints based on the RenderInfo structure.
	 * 
	 * @param document
	 * @param transcoder
	 * @param info
	 */
	private void setUpTranscoders(Document document, Transcoder transcoder, RenderInfo info)
		throws Exception {
		initializeTranscoderFromInfo(transcoder, info);
		
		TranscoderInput input = null;
		TranscoderOutput output = null;

		input = new TranscoderInput(document);
		output = new ImageTranscoderOutput(); 
		transcoder.transcode(input, output);
	}

	private void initializeTranscoderFromInfo(Transcoder transcoder, RenderInfo info) {
		if (info.getWidth() > 0)
			transcoder.addTranscodingHint(
				ImageTranscoder.KEY_WIDTH,
				new Float(info.getWidth()));
		if (info.getHeight() > 0)
			transcoder.addTranscodingHint(
				ImageTranscoder.KEY_HEIGHT,
				new Float(info.getHeight()));
		
		transcoder.addTranscodingHint(
			ImageTranscoderEx.KEY_MAINTAIN_ASPECT_RATIO,
				Boolean.valueOf(info.shouldMaintainAspectRatio()));
	
		transcoder.addTranscodingHint(
			ImageTranscoderEx.KEY_ANTI_ALIASING,
				Boolean.valueOf(info.shouldAntiAlias()));
				
		if (info.getBackgroundColor() != null) {
			transcoder.addTranscodingHint(
				ImageTranscoderEx.KEY_FILL_COLOR,
				new Color(info.getBackgroundColor().red, 
						  info.getBackgroundColor().green,
						  info.getBackgroundColor().blue));
		}
		
		if (info.getForegroundColor() != null) {
					transcoder.addTranscodingHint(
						ImageTranscoderEx.KEY_OUTLINE_COLOR,
						new Color(info.getForegroundColor().red, 
								  info.getForegroundColor().green,
								  info.getForegroundColor().blue));
		}

	}
	
	/**
	 * renderSVG
	 * Given an InputStream, will render the SVG file into an SWT Image
	 * 
	 * @param in InputSteam which contains the SVG file data
	 * @param RenderInfo object containing information about the size and 
	 * general data regarding how the image will be rendered.
	 * @return BufferedImage AWT iimage containing the rendered SVG file.
	 * @throws Exception
	 */
	public BufferedImage renderSVGToAWTImage(InputStream in, RenderInfo info)
		throws Exception {
		ImageTranscoderEx transcoder = new ImageTranscoderEx();
		setUpTranscoders(in, transcoder, info);

		return transcoder.getBufferedImage();
	}
	
	/**
	 * renderSVGtoSWTImage
	 * Given a filename, will render the SVG file into an SWT Image
	 * 
	 * @param strFileName String file path of svg file
	 * @param RenderInfo object containing information about the size and 
	 * general data regarding how the image will be rendered.
	 * @return Image SWT image containing the rendered SVG file.
	 * @throws Exception
	 */
	public Image renderSVGtoSWTImage(String strFileName, RenderInfo info)
		throws Exception {
		InputStream in = new FileInputStream(strFileName);
		return renderSVGtoSWTImage(in, info);
	}

	/**
	 * renderSVGtoSWTImage
	 * Given a buffer, will render the SVG file into an SWT Image
	 * 
	 * @param buffer byte[] array containing an cached SVG image file.
	 * @param RenderInfo object containing information about the size and 
	 * general data regarding how the image will be rendered.
	 * @return Image SWT image containing the rendered SVG file.
	 * @throws Exception
	 */
	public Image renderSVGtoSWTImage(byte[] buffer, RenderInfo info)
		throws Exception {
		InputStream in = new ByteArrayInputStream(buffer);
		return renderSVGtoSWTImage(in, info);
	}

	/**
	 * renderSVGtoSWTImage
	 * Given an InputStream, will render the SVG file into an SWT Image
	 * 
	 * @param in InputSteam which contains the SVG file data
	 * @param RenderInfo object containing information about the size and 
	 * general data regarding how the image will be rendered.
	 * @return Image SWT image containing the rendered SVG file.
	 * @throws Exception
	 */
	public Image renderSVGtoSWTImage(InputStream in, RenderInfo info)
		throws Exception {
		
		SWTImageTranscoder transcoder = new SWTImageTranscoder();
		setUpTranscoders(in, transcoder, info);
		
		return transcoder.getSWTImage();
	}
	
	 /**
	 * Export SVG image to PDF file format.
	 * 
	 * @param SVGImage The input SVG image.
	 * @param fileOutputStream The output stream to write the PDF to.
	 * @throws CoreException
	 */
    public static void exportToPDF(SVGImage svgImage,
			OutputStream fileOutputStream)
			throws CoreException {
    	
		try {
			TranscoderOutput transcoderOutput = new TranscoderOutput(fileOutputStream);
			TranscoderInput transcoderInput = new TranscoderInput(svgImage
					.getDocument());

			PDFTranscoder pdfTranscoder = new PDFTranscoder();
			pdfTranscoder.transcode(transcoderInput, transcoderOutput);

		} catch (TranscoderException e) {
			Log.error(Draw2dRenderPlugin.getInstance(), IStatus.ERROR, e
					.getMessage(), e);
			IStatus status = new Status(IStatus.ERROR,
					"exportToPDF", IStatus.OK, //$NON-NLS-1$
					e.getMessage(), null);
			throw new CoreException(status);
		} 
	}
}
