import java.awt.BorderLayout;
import java.awt.Container;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

import java.io.InputStream;

import java.net.URL;

import java.text.DateFormat;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.JFrame;
import javax.swing.JPanel;

import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.UpdateManager;

import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
import org.apache.batik.dom.svg.SVGDOMImplementation;

import org.apache.batik.gvt.GraphicsNode;

import org.apache.batik.util.XMLResourceDescriptor;

import org.apache.batik.swing.JSVGCanvas;

import org.apache.batik.swing.svg.GVTTreeBuilderListener;
import org.apache.batik.swing.svg.GVTTreeBuilderEvent;

import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;

import org.apache.batik.transcoder.svg2svg.SVGTranscoder;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget;
import org.w3c.dom.events.MouseEvent;

import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.svg.SVGElement;
import org.w3c.dom.svg.SVGMatrix;
import org.w3c.dom.svg.SVGPoint;
import org.w3c.dom.svg.SVGRect;
import org.w3c.dom.svg.SVGSVGElement;
import org.w3c.dom.svg.SVGTextElement;
import org.w3c.dom.svg.SVGTSpanElement;

public class ClassTest extends JPanel implements GVTTreeBuilderListener {
    
    public static void main(String[] args) throws Throwable {
        JFrame frame = new JFrame("Class Test");
        ClassTest ui = new ClassTest();
        Container content = frame.getContentPane();
        content.add(ui);

        frame.addWindowListener(
            new WindowAdapter() {
                public void windowClosing(WindowEvent event) {
                    System.exit(0);
                }
            }
        );
        frame.setSize(400, 400);
        ui.initialize();
        frame.setVisible(true);
    }
    
    JSVGCanvas canvas_;
    
    ClassTest() throws Exception {
        canvas_ = new JSVGCanvas();
        canvas_.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC);
        canvas_.addGVTTreeBuilderListener(this);
        
        setLayout(new BorderLayout());
        add(canvas_, BorderLayout.CENTER);
    }
    
    void removeAllChildNodes(Element element) {
        NodeList children = element.getChildNodes();
        for (int i = children.getLength() - 1; i >= 0; --i) {
            Node child = children.item(i);
            element.removeChild(child);
        }
    }
    
    Element appendTSpan(SVGDocument document, Element element, String text) {
        Element tspan = document.createElementNS(
            SVGDOMImplementation.SVG_NAMESPACE_URI, "tspan"
        );
        tspan.appendChild(document.createCDATASection(text));
        element.appendChild(tspan);
        return tspan;
    }
    
    void initialize() throws Throwable {
        String parser = XMLResourceDescriptor.getXMLParserClassName();
        SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(parser);
        Class c = getClass();
        URL url = c.getResource("TextTest.svg");
        SVGDocument document = factory.createSVGDocument(url.toString());
        Element element = document.getElementById("expression.0");
        removeAllChildNodes(element);
        appendTSpan(document, element, "mouse over me");
        canvas_.setSVGDocument(document);
    }
    
    public void gvtBuildStarted(GVTTreeBuilderEvent event) {
    }
    
    public void gvtBuildFailed(GVTTreeBuilderEvent event) {
    }
    
    public void gvtBuildCancelled(GVTTreeBuilderEvent event) {
    }
    
    public void gvtBuildCompleted(GVTTreeBuilderEvent event) {
        SVGDocument document = canvas_.getSVGDocument();
        
        EventTarget target = (EventTarget) document.getElementById(
            "expression.0"
        );
        target.addEventListener(
            "mousemove", 
            new EventListener() {
                public void handleEvent(Event event) {
                    mouseMove((MouseEvent) event);
                }
            },
            false
        );
    }
    
    void mouseMove(MouseEvent event) {
        if (! (event.getTarget() instanceof SVGTSpanElement)) {
            return;
        }
        
        SVGTSpanElement span = (SVGTSpanElement) event.getTarget();
        span.setAttributeNS(null, "class", "highlight");
    }
    
}

