package org.limewire.ui.swing.options;
import java.awt.Dimension;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JRadioButton;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import net.miginfocom.swing.MigLayout;
import org.limewire.bittorrent.TorrentManager;
import org.limewire.bittorrent.TorrentManagerSettings;
import org.limewire.bittorrent.TorrentSettingsAnnotation;
import org.limewire.core.settings.BittorrentSettings;
import org.limewire.ui.swing.components.MultiLineLabel;
import org.limewire.ui.swing.components.PeriodicFieldValidator;
import org.limewire.ui.swing.options.actions.CancelDialogAction;
import org.limewire.ui.swing.options.actions.OKDialogAction;
import org.limewire.ui.swing.util.BackgroundExecutorService;
import org.limewire.ui.swing.util.I18n;
import com.google.inject.Inject;
import com.google.inject.Provider;
/**
* BitTorrent Option View.
*/
public class BitTorrentOptionPanel extends OptionPanel {
private final Provider<TorrentManager> torrentManager;
private final TorrentManagerSettings torrentSettings;
private final JRadioButton uploadTorrentsForeverButton;
private final JRadioButton uploadTorrentsControlButton;
private final SpinnerNumberModel seedRatioModel;
private final JSpinner seedRatioSpinner;
private final SpinnerNumberModel seedDaysModel;
private final SpinnerNumberModel seedHoursModel;
private final JSpinner seedDaysSpinner;
private final JSpinner seedHoursSpinner;
private final JCheckBox chooseTorrentsCheckBox;
@Inject
public BitTorrentOptionPanel(Provider<TorrentManager> torrentManager,
@TorrentSettingsAnnotation TorrentManagerSettings torrentSettings) {
this.torrentManager = torrentManager;
this.torrentSettings = torrentSettings;
setLayout(new MigLayout("fill"));
setOpaque(false);
uploadTorrentsForeverButton = new JRadioButton(I18n.tr("Upload torrents forever"));
uploadTorrentsForeverButton.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
updateState(uploadTorrentsForeverButton.isSelected());
}
});
uploadTorrentsControlButton = new JRadioButton(I18n.tr("Upload torrents until either of the following:"));
uploadTorrentsControlButton.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
updateState(uploadTorrentsForeverButton.isSelected());
}
});
uploadTorrentsForeverButton.setOpaque(false);
uploadTorrentsControlButton.setOpaque(false);
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(uploadTorrentsForeverButton);
buttonGroup.add(uploadTorrentsControlButton);
seedRatioModel = new SpinnerNumberModel(BittorrentSettings.LIBTORRENT_SEED_RATIO_LIMIT
.get().doubleValue(), BittorrentSettings.LIBTORRENT_SEED_RATIO_LIMIT.getMinValue()
.doubleValue(), BittorrentSettings.LIBTORRENT_SEED_RATIO_LIMIT.getMaxValue()
.doubleValue(), .05);
seedRatioSpinner = new JSpinner(seedRatioModel);
seedRatioSpinner.setPreferredSize(new Dimension(50, 20));
seedRatioSpinner.setMaximumSize(new Dimension(60, 20));
int wholeDays = getWholeDays(BittorrentSettings.LIBTORRENT_SEED_TIME_LIMIT.get());
seedDaysModel = new SpinnerNumberModel(
wholeDays,
getWholeDays(BittorrentSettings.LIBTORRENT_SEED_TIME_LIMIT.getMinValue()),
getWholeDays(BittorrentSettings.LIBTORRENT_SEED_TIME_LIMIT.getMaxValue()), 1);
seedHoursModel = new SpinnerNumberModel(
getRemainderHours(BittorrentSettings.LIBTORRENT_SEED_TIME_LIMIT.get(), wholeDays),
0,
24, 1);
seedDaysSpinner = new JSpinner(seedDaysModel);
seedDaysSpinner.setPreferredSize(new Dimension(50, 20));
seedDaysSpinner.setMaximumSize(new Dimension(60, 20));
seedHoursSpinner = new JSpinner(seedHoursModel);
seedHoursSpinner.setPreferredSize(new Dimension(50, 20));
seedHoursSpinner.setMaximumSize(new Dimension(60, 20));
JFormattedTextField seedDaysField = ((JSpinner.DefaultEditor)seedDaysSpinner.getEditor()).getTextField();
seedDaysField.addKeyListener(new PeriodicFieldValidator(seedDaysField));
JFormattedTextField seedHoursField = ((JSpinner.DefaultEditor)seedHoursSpinner.getEditor()).getTextField();
seedHoursField.addKeyListener(new PeriodicFieldValidator(seedHoursField));
chooseTorrentsCheckBox = new JCheckBox(I18n.tr("Let me choose files to download when starting a torrent"));
chooseTorrentsCheckBox.setOpaque(false);
if (torrentManager.get().isValid()) {
add(uploadTorrentsForeverButton, "span 3, wrap");
add(uploadTorrentsControlButton, "span 3, wrap");
add(new JLabel(I18n.tr("Ratio:")), "split 2, gapleft 20");
add(seedRatioSpinner, "span, wrap");
add(new JLabel(I18n.tr("Maximum days:")), "gapleft 20, split 4");
add(seedDaysSpinner, "");
add(new JLabel("Hours:"), "gapleft 20");
add(seedHoursSpinner, "wrap");
add(chooseTorrentsCheckBox, "span, gaptop 10, gapbottom 5, wrap");
} else {
add(new MultiLineLabel(I18n.tr("There was an error loading bittorrent. You will not be able to use bittorrent capabilities until this is resolved."),
500), "wrap");
}
add(new JButton(new OKDialogAction()), "span, tag ok, alignx right, split 2");
add(new JButton(new CancelDialogAction()), "tag cancel");
}
@Override
ApplyOptionResult applyOptions() {
BittorrentSettings.UPLOAD_TORRENTS_FOREVER.setValue(uploadTorrentsForeverButton.isSelected());
if (!uploadTorrentsForeverButton.isSelected()) {
BittorrentSettings.LIBTORRENT_SEED_RATIO_LIMIT.setValue(seedRatioModel.getNumber().floatValue());
BittorrentSettings.LIBTORRENT_SEED_TIME_LIMIT.setValue(
getSeconds((Integer)seedDaysSpinner.getValue(), (Integer)seedHoursSpinner.getValue()));
}
BittorrentSettings.TORRENT_SHOW_POPUP_BEFORE_DOWNLOADING.setValue(chooseTorrentsCheckBox
.isSelected());
if (torrentManager.get().isInitialized() && torrentManager.get().isValid()) {
BackgroundExecutorService.execute(new Runnable() {
@Override
public void run() {
torrentManager.get().setTorrentManagerSettings(torrentSettings);
}
});
}
return new ApplyOptionResult(false, true);
}
@Override
boolean hasChanged() {
return BittorrentSettings.UPLOAD_TORRENTS_FOREVER.getValue() != uploadTorrentsForeverButton.isSelected()
|| ((Float) seedRatioSpinner.getValue()).floatValue() != BittorrentSettings.LIBTORRENT_SEED_RATIO_LIMIT.getValue()
|| getSeconds((Integer)seedDaysSpinner.getValue(), (Integer)seedHoursSpinner.getValue())
!= BittorrentSettings.LIBTORRENT_SEED_TIME_LIMIT.getValue()
|| chooseTorrentsCheckBox.isSelected() != BittorrentSettings.TORRENT_SHOW_POPUP_BEFORE_DOWNLOADING.getValue();
}
@Override
public void initOptions() {
boolean auto = BittorrentSettings.UPLOAD_TORRENTS_FOREVER.getValue();
if (auto) {
uploadTorrentsForeverButton.setSelected(true);
}
else {
uploadTorrentsControlButton.setSelected(true);
}
seedRatioSpinner.setValue(BittorrentSettings.LIBTORRENT_SEED_RATIO_LIMIT.get().doubleValue());
seedDaysSpinner.setValue(getWholeDays(BittorrentSettings.LIBTORRENT_SEED_TIME_LIMIT.get()));
chooseTorrentsCheckBox.setSelected(BittorrentSettings.TORRENT_SHOW_POPUP_BEFORE_DOWNLOADING.getValue());
}
private static int getWholeDays(Integer integer) {
return (int) Math.floor(integer.doubleValue() / (60 * 60 * 24));
}
private static int getRemainderHours(Integer totalSeconds, int days) {
return (int)Math.round(totalSeconds.doubleValue() / (60 *60) - days*24);
}
private static int getSeconds(int days, int hours) {
return days*24*60*60 + hours*60*60;
}
/**
* Updates the state of the components based on whether the user has opted
* to control the bittorrent settings manually, or let limewire control
* them.
*/
private void updateState(boolean uploadForever) {
seedRatioSpinner.setEnabled(!uploadForever);
seedDaysSpinner.setEnabled(!uploadForever);
seedHoursSpinner.setEnabled(!uploadForever);
}
}