/* This work has been placed into the public domain. */

package kiyut.alkitab.bookviewer;

import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JComponent;
import javax.swing.ListSelectionModel;
import javax.swing.event.HyperlinkListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import kiyut.alkitab.navigator.KeyListModel;
import kiyut.alkitab.options.ViewerHintsOptions;
import kiyut.alkitab.util.ComponentOrientationSupport;
import org.crosswire.jsword.book.Book;
import org.crosswire.jsword.passage.Key;
import org.crosswire.jsword.passage.PreferredKey;

/**
 * Panel which display single book with list of key on the right side
 * 
 */
public class DefinitionPane extends javax.swing.JPanel {
    
    protected TextPaneRenderer bookRenderer;
    protected ViewerHints<ViewerHints.Key,Object> viewerHints;
    
    /** Creates new DefinitionPane */
    public DefinitionPane() {
        this(null);
    }
    
    public DefinitionPane(Book book) {
        this.viewerHints = new ViewerHints<>(ViewerHintsOptions.getInstance().getViewerHints());
        initComponents();
        initCustom();
        setBook(book);

        ComponentOrientationSupport.applyComponentOrientation(this);
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        splitPane = new javax.swing.JSplitPane();
        indexPane = new javax.swing.JPanel();
        indexScrollPane = new javax.swing.JScrollPane();
        indexList = new javax.swing.JList<>();
        bookScrollPane = new javax.swing.JScrollPane();

        setLayout(new java.awt.BorderLayout());

        splitPane.setResizeWeight(1.0);

        indexPane.setLayout(new java.awt.BorderLayout(0, 3));

        indexScrollPane.setViewportView(indexList);

        indexPane.add(indexScrollPane, java.awt.BorderLayout.CENTER);

        splitPane.setRightComponent(indexPane);
        splitPane.setLeftComponent(bookScrollPane);

        add(splitPane, java.awt.BorderLayout.CENTER);
    }// </editor-fold>//GEN-END:initComponents
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JScrollPane bookScrollPane;
    protected javax.swing.JList<Key> indexList;
    protected javax.swing.JPanel indexPane;
    private javax.swing.JScrollPane indexScrollPane;
    private javax.swing.JSplitPane splitPane;
    // End of variables declaration//GEN-END:variables
    
    protected void initCustom() {
        bookRenderer = new TextPaneRenderer (viewerHints);
        bookScrollPane.setViewportView(bookRenderer);
        //splitPane.setLeftComponent(bookRenderer);
        
        //getActionMap().setParent(bookRenderer.getActionMap());
        
        //indexList.setPrototypeCellValue("DICTIONARY INDEX TEXT");
        indexList.setModel(new KeyListModel());
        indexList.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        
        indexList.addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent evt) {
                keyValueChanged(evt);
            }
        });
    }
    
    public void setBook(Book book) {
        if (book != null) {
            List<Book> books = bookRenderer.getBooks();
            if (books.isEmpty()) {
                books.add(book);
            } else {
                books.set(0, book);
            }
            
            Key key = book.getGlobalKeyList();
            ((KeyListModel)indexList.getModel()).setKey(key);

            // for eg: DailyDevotions today key
            Key prefKey = null;
            if (book instanceof PreferredKey) {
                prefKey = ((PreferredKey)book).getPreferred();
            } 
            
            int index = 0;
            if (prefKey != null) {
                 index = key.indexOf(prefKey);
                 if (index < 0) { index = 0; }
            } 
            
            if (indexList.getModel().getSize() > index) {
                indexList.setSelectedIndex(index);
                indexList.ensureIndexIsVisible(index);
            }
        } else {
            bookRenderer.getBooks().clear();
        }
    }
    
    public Book getBook() {
        List<Book> books = bookRenderer.getBooks();
        if (books.isEmpty()) {
            return null;
        }
        return books.get(0);
    }
    
    public void setKey(Key key) {
        if (key == null) { return; }
        bookRenderer.setKey(key);
        bookRenderer.reload(true);

        // synchronize the List and the View
        int i = ((KeyListModel) indexList.getModel()).getKey().indexOf(key);

        if (i >= 0) {
            if (indexList.getSelectedIndex() != i) {
                indexList.setSelectedIndex(i);
            }
            indexList.ensureIndexIsVisible(i);
        }
    }

    /*public void setKey(keyString) {
        Book book = getBook();
        if (book == null) { return; }
        Key key = book.getValidKey(keyString);
        bookRenderer.setKey(key);
        bookRenderer.refresh(true);
    }*/
    
    public void viewSource() {
        try {
            SourceViewerPane sourcePane = new SourceViewerPane();
            sourcePane.initSource(bookRenderer);
            //sourcePane.initSource(bookRenderer.getBooks(), bookRenderer.getKey(), bookRenderer.getConverter(), bookRenderer.getViewerHints(), bookRenderer.isCompareView());
            sourcePane.showDialog(this,true);
        } catch (Exception ex) {
            Logger logger = Logger.getLogger(this.getClass().getName());
            logger.log(Level.WARNING, ex.getMessage(), ex);
        }
    }
    
    public ViewerHints<ViewerHints.Key,Object> getViewerHints() {
        if (viewerHints == null) {
            viewerHints = new ViewerHints<>();
        }
        return viewerHints;
    }

    /**
     * @return getBookRenderer().getComponent();
     * @deprecated replaced with #getBookRenderer() 
     */
    @Deprecated
    public JComponent getViewerComponent() {
        return getBookRenderer().getComponent();
    }
    
    public BookRenderer getBookRenderer() {
        return bookRenderer;
    }

    public void addHyperlinkListener(HyperlinkListener listener) {
        bookRenderer.addHyperlinkListener(listener);
    }
    
    public void removeHyperlinkListener(HyperlinkListener listener) {
        bookRenderer.removeHyperlinkListener(listener);
    }
    
    protected void keyValueChanged(ListSelectionEvent evt) {
        if (evt.getValueIsAdjusting()) { return; }
        int index = indexList.getSelectedIndex();
        if (index == -1) { return; }
        Key key = indexList.getModel().getElementAt(index);
        // XXX bug on JSword ?, if using string it will not find the key
        // eg: Daily Devotional
        /*System.out.println("key: " + key.toString());
        System.out.println("   : " + key.getName());
        System.out.println("   : " + key.getOsisID());
        System.out.println("   : " + key.getOsisRef());
         */
        //bookTextPane.setViewKey(key.toString());
        setKey(key);
        //System.out.println("DefinitionPane.keyValueChanged" + key);
    }
}