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

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

import java.net.URL;

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.util.XMLResourceDescriptor;

import org.apache.batik.swing.JSVGCanvas;

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

import org.w3c.dom.Element;

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 TextTest extends JPanel implements GVTTreeBuilderListener {
    
    public static void main(String[] args) throws Throwable {
        JFrame frame = new JFrame("Text Test");
        TextTest ui = new TextTest();
        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_;
    
    TextTest() throws Exception {
        canvas_ = new JSVGCanvas();
        canvas_.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC);
        canvas_.addGVTTreeBuilderListener(this);
        
        setLayout(new BorderLayout());
        add(canvas_, BorderLayout.CENTER);
    }
    
    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());
        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) {
        System.out.println(
            "client coord: " + event.getClientX() + ", " + event.getClientY()
        );
        SVGTextElement text = (SVGTextElement) event.getTarget();
        SVGMatrix transform = text.getScreenCTM();
        SVGMatrix inverse = transform.inverse();
        SVGDocument document = canvas_.getSVGDocument();
        SVGSVGElement root = document.getRootElement();
        SVGPoint point = root.createSVGPoint();
        point.setX(event.getClientX());
        point.setY(event.getClientY());
        point = point.matrixTransform(inverse);
        System.out.println("text coord: " + point.getX() + ", " + point.getY());
        int index = text.getCharNumAtPosition(point);
        System.out.println("text index: " + index);
    }
    
}

