package test;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.AffineTransform;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SpringLayout;

import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.BridgeException;
import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.bridge.UserAgentAdapter;
import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.swing.gvt.GVTTreeRendererAdapter;
import org.apache.batik.swing.gvt.GVTTreeRendererEvent;
import org.apache.batik.swing.gvt.JGVTComponent;
import org.apache.batik.util.XMLResourceDescriptor;
import org.w3c.dom.svg.SVGDocument;
public class SVGApplication {

    public static void main(String[] args) {
        // Create a new JFrame.
        JFrame f = new JFrame("Batik");
        SVGApplication app = new SVGApplication(f);

        // Add components to the frame.
        f.getContentPane().add(app.createComponents());

        // Display the frame.
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        f.setSize(870, 700);
        f.setVisible(true);
    }
    
    // The frame.
    protected JFrame frame;

    // The "Load" button, which displays up a file chooser upon clicking.
    protected JButton button = new JButton("Load...");

    // The status label.
    protected JLabel label = new JLabel();

    protected JScrollPane scrollContainer;
    
    // The SVG canvas.
    private JGVTComponent svgCanvas = new MyJSVGCanvas(false, false);
    
    JPanel chartCanvas;

    public SVGApplication(JFrame f) {
        frame = f;
    }

    double zooms[] = { 1.0, 1.5, 2.6, 3.7 };
    
    int currentZoom = 0;
    
    SpringLayout layout;
    
    public JComponent createComponents() {
        // Create a panel and add the button, status label and the SVG canvas.
        final JPanel panel = new JPanel(new BorderLayout());

        JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT));
        p.add(button);
        JButton zoomButton = new JButton("zoom");
                
        zoomButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {

            	// zooms cycle
            	currentZoom++;
            	currentZoom %= zooms.length;
            	double scale = zooms[currentZoom];
            	AffineTransform  transform = AffineTransform.getScaleInstance(scale, scale);
            	
            	// resize svgCanvas to match current chart size
            	Rectangle rect = svgCanvas.getGraphicsNode().getTransformedBounds(transform).getBounds();
            	svgCanvas.setPreferredSize(rect.getSize());
            	svgCanvas.setRenderingTransform(transform);
            	svgCanvas.invalidate();
                
            	}
            }
        );
        
        p.add(zoomButton);
        
        p.add(label);

        panel.add("North", p);
        
        layout = new SpringLayout();
        svgCanvas.setLayout(layout);
        
        // create scroll container
        scrollContainer = new JScrollPane(svgCanvas, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
        		JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        
        scrollContainer.setBorder(BorderFactory.createLineBorder(new Color(254, 159, 0), 2));
        svgCanvas.setBorder(BorderFactory.createLineBorder(new Color(254, 0, 0), 2));
                
        panel.add(BorderLayout.CENTER, scrollContainer);

        // Set the button action.
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                JFileChooser fc = new JFileChooser(".");
                int choice = fc.showOpenDialog(panel);
                if (choice == JFileChooser.APPROVE_OPTION) {
                    File f = fc.getSelectedFile();
                    try {
                    	
                    	GVTBuilder builder = new GVTBuilder();
                        GraphicsNode gvtRoot = null;

                        SVGDocument document = null;
                        BridgeContext bridgeContext = null;
                        try {
                        	InputStream is = new FileInputStream(f); 
                        	
                        	String css = f.getAbsolutePath().substring(0, f.getAbsolutePath().lastIndexOf(File.separator) + 1);
                			document = new SAXSVGDocumentFactory(
                					XMLResourceDescriptor.getXMLParserClassName())
                					.createSVGDocument("file:///" + css, is);
                			
                        	bridgeContext = new BridgeContext(new UserAgentAdapter());
                            bridgeContext.setDynamicState(BridgeContext.DYNAMIC);
                            gvtRoot = builder.build(bridgeContext, document);
                            is.close();
                            
                        } catch (BridgeException e) {
                        	String msg = "Error building GVT tree";
                        }
                        
                    	svgCanvas.setGraphicsNode(gvtRoot);
                    	svgCanvas.setPreferredSize(gvtRoot.getBounds().getBounds().getSize());
                    	svgCanvas.setRenderingTransform(svgCanvas.getRenderingTransform());
                    	svgCanvas.revalidate();
                    	
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        });

        svgCanvas.addGVTTreeRendererListener(new GVTTreeRendererAdapter() {
            public void gvtRenderingPrepare(GVTTreeRendererEvent e) {
                label.setText("Rendering Started...");
            }
            public void gvtRenderingCompleted(GVTTreeRendererEvent e) {
            	
            	label.setText("");
                
            }
        });

        return panel;
    }

    class MyJSVGCanvas extends JGVTComponent {
    	
    	/**
		 * @param b
		 * @param c
		 */
		public MyJSVGCanvas(boolean eventsEnabled, boolean selectableText) {
			super(eventsEnabled, selectableText);
		}
    	/**
    	 * {@inheritDoc}
    	 */
    	@Override
    	public Rectangle getRenderRect() {
    		
    		// set visible rectangle to be repainted on canvas - doesn't work
    		return new Rectangle(50, 50, 500, 500);
    	}
    }
}