package kiyut.alkitab.swing;

import java.awt.ComponentOrientation;
import java.net.URISyntaxException;
import javax.swing.ActionMap;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.text.html.HTMLEditorKit;
import kiyut.alkitab.api.SwordURI;
import kiyut.alkitab.api.SwingHTMLConverter;
import org.crosswire.common.xml.Converter;
import org.crosswire.common.xml.SAXEventProvider;
import org.crosswire.common.xml.TransformingSAXEventProvider;
import org.crosswire.common.xml.XMLUtil;
import org.crosswire.jsword.book.Book;
import org.crosswire.jsword.book.BookData;
import org.crosswire.jsword.book.BookMetaData;
import org.crosswire.jsword.passage.Key;

/**
 * Simple and Single Book Viewer that use {@link javax.swing.JTextPane JTextPane} HTML mode
 * 
 * @see ParallelBookTextPane
 */
public class BookTextPane extends JTextPane {
    
    protected Book book;
    protected Key key;
    protected Converter converter;

    public BookTextPane() {
        setEditable(false);
        setEditorKit(new HTMLEditorKit());
        addHyperlinkListener(new HyperlinkListener() {
            public void hyperlinkUpdate(HyperlinkEvent evt) {
                BookTextPane.this.hyperlinkUpdate(evt);
            }
        });
        
        setConverter(new SwingHTMLConverter());
    }
    
    /** Redisplay or refresh content */
    public void refresh() {
        refresh(false);
    }
    
    /** Redisplay or refresh content 
     * @param invokeLater using Event Dispatch Thread
     */
    public void refresh(boolean invokeLater) {
        if (invokeLater) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    refreshImpl();
                }
            });
        } else {
            refreshImpl();
        }
    }
    
    /** Redisplay or refresh content */
    protected void refreshImpl() {
        if (key == null) {
            setText("");
            return;
        }
        
        BookMetaData bmd = book.getBookMetaData();
        boolean ltr = bmd.isLeftToRight();
        
        String text = "";
        try {
            //System.out.println(tKey);
            BookData bookData = new BookData(book,key);
            SAXEventProvider osissep = bookData.getSAXEventProvider();
            TransformingSAXEventProvider htmlsep = (TransformingSAXEventProvider) converter.convert(osissep);
            
            htmlsep.setParameter("direction", ltr ? "ltr" : "rtl"); 
            text = XMLUtil.writeToString(htmlsep);
            
            
        } catch (Exception ex) {
            // TODO need error reporting here
            //System.out.println(ex.getMessage());
        }
        
        setText(text);
        select(0,0);
    }
    
    public void setBook(Book book) {
        this.book = book;
        
        if (book == null) { 
            return;
        }
        
        BookMetaData bmd = book.getBookMetaData();
        boolean ltr = bmd.isLeftToRight();
        if (ltr) {
            applyComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
        } else {
            applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
        }
    }
    
    public Book getBook() {
        return this.book;
    }
    
    public void setKey(Key key) {
        this.key = key;
    }
    
    public Key getKey() {
        return this.key;
    }
    
    public void setConverter(Converter converter) {
        this.converter = converter;
    }
    
    /** 
     * If it is in the same document, then scroll to the referenced URI
     * 
     * @param evt the Event
     */
    protected void hyperlinkUpdate(HyperlinkEvent evt) {
        if (evt.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) {
            String uri = evt.getDescription();
            try {
                String[] parts = SwordURI.parseParts(uri);
                if (parts[2].length() > 0) {
                    if (parts[2].charAt(0) == '#') {
                        scrollToReference(uri);
                    }
                }
            } catch (URISyntaxException ex) {
                // TODO add logging here
            }
        }
    }
}
