/*
 *  Draco Econometrics
 *  Copyright (C) 2006-2007 Approximatrix, LLC
 *  http://www.approximatrix.com
 *  
 *  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 3 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, see <http://www.gnu.org/licenses/>.
 */

package com.approximatrix.draco.io;

import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.awt.Container;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.FileOutputStream;
import java.io.Writer;

import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

import com.approximatrix.draco.io.filters.PNGFilter;
import com.approximatrix.draco.io.filters.JPEGFilter;
import com.approximatrix.draco.io.filters.SVGFilter;

// These are our imports necessary for writing the SVG file
import org.apache.batik.svggen.SVGGraphics2D;
import org.apache.batik.svggen.SVGGeneratorContext;
import org.apache.batik.dom.GenericDOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.DOMImplementation;

/** Provides basic support of image loading (not implemented...) and saving,
 * including PNG, JPEG, and SVG files.
 */
public class ImageSupport {
	
	private static String LastFile = null;
	
	private static final boolean SVG_FONTS_AS_SHAPES = false;
	
	/** Saves an image based on the component passed in
	 * 
	 * @param data the component to save as an image
	 */
	public static void RequestSave(JComponent data) {

		// Get a filename
        JFileChooser chooser = new JFileChooser();
		chooser.setMultiSelectionEnabled(false);
		chooser.setFileFilter(new PNGFilter());
		chooser.setFileFilter(new JPEGFilter());
		chooser.setFileFilter(new SVGFilter());
		
		String type = "png";
		if(LastFile != null) {
			chooser.setCurrentDirectory(new java.io.File(LastFile));
		}
	    chooser.setDialogTitle("Save image as...");
	    if (chooser.showSaveDialog(chooser) == JFileChooser.APPROVE_OPTION) {
	    	
	    	File selected = chooser.getSelectedFile();
	    	
	    	if(new JPEGFilter().accept(selected)) {
	    		type = "jpg";
	    	} else if(new SVGFilter().accept(selected)) {
	    		type = "svg";
	    	} else if(new PNGFilter().accept(selected)) {
	    		type = "png";
	    	} else {
	    		type = "png";
	    		String text = selected.getPath()+".png";
	    		selected = new File(text);
			}	    		
	    	
			if(type.compareTo("svg") != 0) {	    	
	    		try {
		        	ImageIO.write(generateImage(data), type, selected);
		        } catch(IOException ioe) {
	        		JOptionPane.showMessageDialog(data, ioe.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
	        	}
	        } else {
		        
		        // Write the SVG file instead
		        WriteSVG(data,selected);
	        }
				        
	    }
	}

	/** Writes an SVG file containing the contents of a valid Swing
	 * component to the specified file.
	 *
	 * @param data a valid Swing JComponent to save as an SVG
	 * @param file a File object where the SVG will be saved
	 */
	private static void WriteSVG(JComponent data, File file) {
		// Get a DOMImplementation
	    DOMImplementation domImpl =
            GenericDOMImplementation.getDOMImplementation();
		                            
        // Create an instance of org.w3c.dom.Document
        Document document = domImpl.createDocument(null, "svg", null);
				                                                    
        // Create an instance of the SVG Generator
        SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(document);
        ctx.setComment("Created by Batik for Draco Econometrics - from Approximatrix, LLC (www.approximatrix.com)");
        SVGGraphics2D svgGenerator = new SVGGraphics2D(ctx,SVG_FONTS_AS_SHAPES);
        
		// Paint our component to the SVG Generator
        data.paint(svgGenerator);
        
        // Attempt to write the file
        try {
        	// Open a writer
        	Writer filewriter = new OutputStreamWriter(new FileOutputStream(file), "UTF8");
	        	
        	// Generate the stream
        	boolean useCSS = true; // we want to use CSS style attribute
        	svgGenerator.stream(filewriter, useCSS);
	        	
        	// Close the file
        	filewriter.close();
        
        } catch(IOException ioe) {
	    	JOptionPane.showMessageDialog(data, ioe.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
		}        	
	
	}
	
	
	/** Returns a BufferedImage representing the contents of the component passed in
	 * 
	 * @param data the component to use to paint an image
	 * @return a valid BufferedImage
	 */
	public static BufferedImage generateImage(JComponent data) {
		
		Rectangle bounds = data.getBounds();
		int width = (int)bounds.getWidth();
		int height = (int)bounds.getHeight();
		
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		
		Graphics2D g = image.createGraphics();
		data.paint(g);
        g.dispose();
        
        return image;
	}

}
