package org.docear.plugin.bibtex.dialogs;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.io.StringReader;
import java.util.Collection;
import java.util.Iterator;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.border.BevelBorder;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.MatteBorder;
import javax.swing.border.SoftBevelBorder;
import javax.ws.rs.core.MultivaluedMap;
import net.sf.jabref.BibtexEntry;
import net.sf.jabref.Globals;
import net.sf.jabref.export.ExportFormats;
import net.sf.jabref.export.layout.LayoutHelper;
import net.sf.jabref.imports.BibtexParser;
import org.docear.plugin.bibtex.ReferencesController;
import org.docear.plugin.bibtex.jabref.JabRefCommons;
import org.docear.plugin.bibtex.jabref.JabRefCommons.MetadataCallableResult;
import org.freeplane.core.ui.components.UITools;
import org.freeplane.core.util.TextUtils;
import com.jgoodies.forms.factories.FormFactory;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.RowSpec;
public class PdfMetadataListDialog extends JPanel {
private static final long serialVersionUID = -627410651667772600L;
private JList list;
private BibtexEntryListModel listModel;
private Collection<BibtexEntry> entries;
private boolean requesting;
private boolean remoteBib;
private boolean hasError;
private JScrollPane scrollPane;
private boolean bibResults;
public PdfMetadataListDialog() {
setPreferredSize(new Dimension(640, 200));
setLayout(new FormLayout(new ColumnSpec[] {
ColumnSpec.decode("434px:grow"),},
new RowSpec[] {
RowSpec.decode("max(30dlu;default)"),
RowSpec.decode("fill:151px:grow"),}));
JPanel panel = new JPanel();
panel.setBackground(Color.WHITE);
add(panel, "1, 1, fill, fill");
panel.setLayout(new FormLayout(new ColumnSpec[] {
FormFactory.RELATED_GAP_COLSPEC,
ColumnSpec.decode("default:grow"),
FormFactory.RELATED_GAP_COLSPEC,},
new RowSpec[] {
RowSpec.decode("max(20dlu;default)"),}));
JLabel lblNewLabel = new JLabel(TextUtils.getText("docear.metadata.import.help"));
panel.add(lblNewLabel, "2, 1");
scrollPane = new JScrollPane();
scrollPane.setViewportBorder(new SoftBevelBorder(BevelBorder.LOWERED, null, null, null, null));
add(scrollPane, "1, 2, fill, fill");
JLabel lblWaiting = new JLabel(new ImageIcon(this.getClass().getResource("/ajax-loader.gif")), JLabel.CENTER);
lblWaiting.setBackground(Color.WHITE);
scrollPane.setViewportView(lblWaiting);
}
public BibtexEntry getSelectedEntry() {
if(list.getSelectedIndex() > -1) {
return listModel.getEntry(list.getSelectedIndex());
}
return null;
}
private void updateResults() {
if(entries != null && !bibResults) {
bibResults = true;
listModel = new BibtexEntryListModel();
list = new JList(listModel);
list.setSelectedIndex(0);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.setCellRenderer(new DefaultListCellRenderer() {
private static final long serialVersionUID = 4805846114365117400L;
public Component getListCellRendererComponent(JList table, Object value, int index, final boolean isSelected, boolean hasFocus) {
StringBuilder sb = new StringBuilder();
sb.append("<html><body>");
sb.append(value);
sb.append("</body></html>");
final JLabel label = (JLabel) super.getListCellRendererComponent(table, sb, index, isSelected, hasFocus);
if(index > 0) {
label.setBorder(new CompoundBorder(new MatteBorder(2, 0, 0, 0, (Color) new Color(0, 0, 0)), new EmptyBorder(10, 8, 10, 8)));
}
else {
label.setBorder(new EmptyBorder(10, 8, 10, 8));
}
return label;
}
});
scrollPane.setViewportView(list);
listModel.fireDataChanged();
}
}
public void runServiceRequest(final String hash, final MultivaluedMap<String, String> params) {
if(!requesting) {
requesting = true;
new Thread() {
public void run() {
remoteBib = true;
try {
MetadataCallableResult ret = JabRefCommons.requestBibTeX(hash, params);
if (ret.hasError()) {
//Replace with local presentation
JOptionPane.showMessageDialog(UITools.getFrame(), ret.getError(), TextUtils.getText("docear.metadata.import.error"), JOptionPane.ERROR_MESSAGE);
hasError = true;
}
String bib = ret.getResult();
// if no bibtex found -> create misc entry with title only
if (bib == null) {
remoteBib = false;
StringBuilder sb = new StringBuilder();
sb.append("@ARTICLE{,\n title = {");
sb.append(params.get("title"));
sb.append("}\n}");
bib = sb.toString();
}
entries = BibtexParser.fromString(bib);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
updateResults();
}
});
} catch (Exception e) {
hasError = true;
}
}
}.start();
}
}
class BibtexEntryListModel extends DefaultListModel {
private static final long serialVersionUID = 2610007578887026651L;
public BibtexEntryListModel() {
}
public void fireDataChanged() {
fireContentsChanged(this, 0, entries.size()-1);
}
public BibtexEntry getEntry(int rowIndex) {
if(rowIndex < 0 || rowIndex >= entries.size()) {
throw new IndexOutOfBoundsException();
}
int i=0;
for (Iterator<BibtexEntry> iterator = entries.iterator(); iterator.hasNext(); i++) {
if(i==rowIndex) {
return iterator.next();
}
iterator.next();
}
return null;
}
public boolean isCellEditable(int row, int column) {
return false;
}
public int getSize() {
if(entries == null) {
return 0;
}
return entries.size();
}
public Object getElementAt(int index) {
BibtexEntry entry = getEntry(index);
if(entry == null) {
return null;
}
StringBuffer sb = new StringBuffer();
StringReader sr = new StringReader(Globals.prefs.get("preview0").replaceAll("__NEWLINE__", "\n"));
ExportFormats.entryNumber = 1; // Set entry number in case that is included in the preview layout.
try {
sb.append(new LayoutHelper(sr).getLayoutFromText(Globals.FORMATTER_PACKAGE).doLayout(entry,ReferencesController.getController().getJabrefWrapper().getDatabase()));
}
catch (Exception e) {
}
return sb.toString();
}
}
public Collection<BibtexEntry> getEntries() {
return this.entries;
}
public boolean hasRemoteBib() {
return remoteBib;
}
public boolean wasSuccessful() {
return !hasError;
}
}