package com.robonobo.gui.panels;
import static com.robonobo.common.util.TextUtil.*;
import static com.robonobo.gui.GuiUtil.*;
import info.clearthought.layout.TableLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
import com.robonobo.common.concurrent.CatchingRunnable;
import com.robonobo.core.Platform;
import com.robonobo.core.api.*;
import com.robonobo.core.api.model.*;
import com.robonobo.core.metadata.CommentCallback;
import com.robonobo.gui.components.base.*;
import com.robonobo.gui.frames.RobonoboFrame;
import com.robonobo.gui.model.MyLibraryTableModel;
@SuppressWarnings("serial")
public class MyLibraryContentPanel extends ContentPanel implements UserListener, LibraryListener {
private RCheckBox shareLibCheckBox;
private Document searchDoc;
private TrackListSearchPanel searchPanel;
CommentsPanel commentsPanel;
boolean unreadComments = false;
public MyLibraryContentPanel(RobonoboFrame f) {
this(f, new PlainDocument());
}
private MyLibraryContentPanel(RobonoboFrame f, Document searchDoc) {
super(f, MyLibraryTableModel.create(f, searchDoc));
this.searchDoc = searchDoc;
tabPane.insertTab("library", null, new LibraryTabPanel(), null, 0);
commentsPanel = new CommentsPanel(f);
tabPane.insertTab("comments", null, commentsPanel, null, 1);
tabPane.setSelectedIndex(0);
tabPane.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
if (tabPane.getSelectedIndex() == 1) {
if (unreadComments) {
unreadComments = false;
removeBangFromTab(1);
final long myUid = frame.ctrl.getMyUser().getUserId();
frame.leftSidebar.markMyLibraryCommentsAsRead();
frame.ctrl.getExecutor().execute(new CatchingRunnable() {
public void doRun() throws Exception {
frame.ctrl.markLibraryCommentsAsSeen(myUid);
}
});
}
}
}
});
frame.ctrl.addUserListener(this);
// Wait til we're shown before getting comments as they need to know our width
User me = frame.ctrl.getMyUser();
if (me != null) {
// Unlikely
addComponentListener(new ComponentAdapter() {
public void componentShown(ComponentEvent e) {
log.debug("MyLibraryContentPanel shown!");
fetchComments();
}
});
} else {
frame.ctrl.addLoginListener(new LoginAdapter() {
public void loginSucceeded(User me) {
fetchComments();
}
});
}
// Clear our comments if we relogin
frame.ctrl.addLoginListener(new LoginAdapter() {
@Override
public void loginSucceeded(User me) {
commentsPanel.clear();
}
});
// Fetch our update msg (if any)
frame.ctrl.getExecutor().schedule(new CatchingRunnable() {
public void doRun() throws Exception {
final UpdateInfo updateInfo = frame.ctrl.getUpdateInfo();
if (isNonEmpty(updateInfo.getUpdateHtml())) {
runOnUiThread(new CatchingRunnable() {
public void doRun() throws Exception {
showMessage(updateInfo.getUpdateTitle(), updateInfo.getUpdateHtml(), null);
}
});
}
}
}, 10, TimeUnit.SECONDS);
}
@Override
public JComponent defaultComponent() {
return searchPanel.getSearchField();
}
@Override
public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
return Platform.getPlatform().canDnDImport(transferFlavors);
}
@Override
public boolean importData(JComponent comp, Transferable t) {
List<File> l = null;
try {
l = Platform.getPlatform().getDnDImportFiles(t);
} catch (IOException e) {
log.error("Caught exception dropping files", e);
return false;
}
final List<File> fl = l;
frame.ctrl.getExecutor().execute(new CatchingRunnable() {
public void doRun() throws Exception {
frame.shareFilesOrDirectories(fl);
}
});
return true;
}
@Override
public void userChanged(User u) {
// Do nothing
}
@Override
public void userConfigChanged(UserConfig cfg) {
boolean libShared = true;
if (cfg.getItems().containsKey("sharelibrary"))
libShared = ("true".equalsIgnoreCase(cfg.getItems().get("sharelibrary")));
final boolean flarp = libShared;
SwingUtilities.invokeLater(new CatchingRunnable() {
public void doRun() throws Exception {
shareLibCheckBox.setEnabled(true);
shareLibCheckBox.setSelected(flarp);
}
});
}
@Override
public void myLibraryUpdated() {
// Do nothing
}
@Override
public void gotLibraryComments(long userId, boolean anyUnread, Map<Comment, Boolean> comments) {
long myUid = frame.ctrl.getMyUser().getUserId();
if (userId != myUid)
return;
if (anyUnread && !(tabPane.getSelectedIndex() == 1)) {
unreadComments = true;
runOnUiThread(new CatchingRunnable() {
public void doRun() throws Exception {
addBangToTab(1);
}
});
}
List<Comment> cl = new ArrayList<Comment>(comments.keySet());
Collections.sort(cl);
commentsPanel.addComments(cl);
}
@Override
public void friendLibraryReady(long userId, int numUnseen) {
// Do nothing
}
@Override
public void friendLibraryUpdated(long userId, int numUnseen, Map<String, Date> newTracks) {
// Do nothing
}
private void fetchComments() {
final long myUid = frame.ctrl.getMyUser().getUserId();
frame.ctrl.addLibraryListener(this);
frame.ctrl.getExistingCommentsForLibrary(myUid, this);
}
class CommentsPanel extends CommentsTabPanel {
public CommentsPanel(RobonoboFrame frame) {
super(frame);
}
@Override
protected boolean canRemoveComment(Comment c) {
return true;
}
@Override
protected void newComment(long parentCmtId, String text, CommentCallback cb) {
long myUid = frame.ctrl.getMyUser().getUserId();
frame.ctrl.newCommentForLibrary(myUid, parentCmtId, text, cb);
}
}
class LibraryTabPanel extends JPanel {
public LibraryTabPanel() {
double[][] cellSizen = { { 10, 400, TableLayout.FILL, 240, 30 }, { TableLayout.FILL } };
setLayout(new TableLayout(cellSizen));
JPanel lPanel = new JPanel();
lPanel.setLayout(new BoxLayout(lPanel, BoxLayout.Y_AXIS));
lPanel.add(Box.createVerticalStrut(5));
searchPanel = new TrackListSearchPanel(frame, trackList, "library", searchDoc);
searchPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 30));
searchPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
lPanel.add(searchPanel);
lPanel.add(Box.createVerticalStrut(15));
RLabel optsLbl = new RLabel16B("Library options");
optsLbl.setAlignmentX(Component.LEFT_ALIGNMENT);
lPanel.add(optsLbl);
lPanel.add(Box.createVerticalStrut(5));
shareLibCheckBox = new RCheckBox("Allow friends to see library");
shareLibCheckBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
final boolean sel = shareLibCheckBox.isSelected();
frame.ctrl.getExecutor().execute(new CatchingRunnable() {
public void doRun() throws Exception {
frame.ctrl.saveUserConfigItem("sharelibrary", sel ? "true" : "false");
}
});
}
});
shareLibCheckBox.setAlignmentX(Component.LEFT_ALIGNMENT);
shareLibCheckBox.setSelected(false);
// We disable it first, it gets re-enabled when we get our user config
shareLibCheckBox.setEnabled(false);
lPanel.add(shareLibCheckBox);
add(lPanel, "1,0");
JPanel rPanel = new JPanel();
rPanel.setLayout(new BoxLayout(rPanel, BoxLayout.Y_AXIS));
rPanel.add(Box.createVerticalStrut(10));
rPanel.add(new RLabel16B("Share more tracks"));
rPanel.add(Box.createVerticalStrut(10));
RButton shareFilesBtn = new RGlassButton("Share MP3 files...");
shareFilesBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
frame.showAddSharesDialog();
}
});
shareFilesBtn.setMaximumSize(new Dimension(200, 30));
rPanel.add(shareFilesBtn);
rPanel.add(Box.createVerticalStrut(10));
if (Platform.getPlatform().iTunesAvailable()) {
RButton shareITunesBtn = new RGlassButton("Share from iTunes...");
shareITunesBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
frame.shareFromITunes();
}
});
shareITunesBtn.setMaximumSize(new Dimension(200, 30));
rPanel.add(shareITunesBtn);
}
add(rPanel, "3,0");
onStartup();
}
private void onStartup() {
// Deal with concurrency issues arising from controller and ui starting independently
frame.ctrl.getExecutor().execute(new CatchingRunnable() {
public void doRun() throws Exception {
if (frame.ctrl.haveAllSharesStarted())
myLibraryUpdated();
}
});
}
}
@Override
public void allUsersAndPlaylistsLoaded() {
}
}