package tim.prune.function;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import tim.prune.App;
import tim.prune.GenericFunction;
import tim.prune.I18nManager;
import tim.prune.data.sort.SortMode;
/**
* Abstract superclass for the functions which rearrange points,
* such as waypoints or photo points
*/
public abstract class RearrangeFunction extends GenericFunction
{
/** Function dialog */
private JDialog _dialog = null;
/** Radio buttons for start/end/nearest */
private JRadioButton[] _positionRadios = null;
/** Radio buttons for sorting */
private JRadioButton[] _sortRadios = null;
/** Is the "nearest" option available? */
private boolean _nearestAvailable = false;
/** Enumeration for rearrange commands */
protected enum Rearrange
{
/** Rearrange all waypoints to start */
TO_START,
/** Rearrange all waypoints to end */
TO_END,
/** Rearrange each waypoint to nearest track point */
TO_NEAREST
}
/**
* Constructor
* @param inApp app object
* @param isNearestAvailable true if nearest option is visible
*/
public RearrangeFunction(App inApp, boolean isNearestAvailable)
{
super(inApp);
_nearestAvailable = isNearestAvailable;
}
/**
* Begin the function by showing the dialog
*/
public void begin()
{
// Make dialog window
if (_dialog == null)
{
_dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true);
_dialog.setLocationRelativeTo(_parentFrame);
_dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
_dialog.getContentPane().add(makeDialogComponents());
_dialog.pack();
}
// If sorting by time isn't available, then disable radio button
_sortRadios[2].setEnabled(isSortByTimeAllowed());
// Show dialog
_dialog.setVisible(true);
}
/**
* Create dialog components
* @return Panel containing all gui elements in dialog
*/
private JPanel makeDialogComponents()
{
JPanel dialogPanel = new JPanel();
dialogPanel.setLayout(new BorderLayout());
JLabel descLabel = new JLabel(I18nManager.getText(getDescriptionKey()));
descLabel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
dialogPanel.add(descLabel, BorderLayout.NORTH);
// Radios for position (start / end / nearest)
_positionRadios = new JRadioButton[3];
final String[] posNames = {"tostart", "toend", "tonearest"};
ButtonGroup posGroup = new ButtonGroup();
JPanel posPanel = new JPanel();
posPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
for (int i=0; i<posNames.length; i++)
{
_positionRadios[i] = new JRadioButton(I18nManager.getText("dialog.rearrange." + posNames[i]));
posGroup.add(_positionRadios[i]);
posPanel.add(_positionRadios[i]);
}
_positionRadios[0].setSelected(true);
_positionRadios[2].setVisible(_nearestAvailable);
// Radios for sort (none / filename / time)
_sortRadios = new JRadioButton[3];
final String[] sortNames = {"nosort", getSortNameKey(), "sortbytime"};
ButtonGroup sortGroup = new ButtonGroup();
JPanel sortPanel = new JPanel();
sortPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
for (int i=0; i<3; i++)
{
_sortRadios[i] = new JRadioButton(I18nManager.getText("dialog.rearrange." + sortNames[i]));
sortGroup.add(_sortRadios[i]);
sortPanel.add(_sortRadios[i]);
}
_sortRadios[0].setSelected(true);
// Use listener to disable all sort options if nearest type chosen, re-enable otherwise
ActionListener rearrListener = new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
final boolean sortAvailable = !_positionRadios[2].isSelected();
for (int i=0; i<_sortRadios.length; i++) {
_sortRadios[i].setEnabled(sortAvailable);
}
}
};
for (int i=0; i<_positionRadios.length; i++) {
_positionRadios[i].addActionListener(rearrListener);
}
// add to middle of dialog
JPanel centrePanel = new JPanel();
centrePanel.setLayout(new BoxLayout(centrePanel, BoxLayout.Y_AXIS));
centrePanel.add(posPanel);
centrePanel.add(sortPanel);
dialogPanel.add(centrePanel, BorderLayout.CENTER);
// button panel at bottom
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
JButton okButton = new JButton(I18nManager.getText("button.ok"));
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
finish();
_dialog.dispose();
}
});
buttonPanel.add(okButton);
JButton cancelButton = new JButton(I18nManager.getText("button.cancel"));
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
_dialog.dispose();
}
});
buttonPanel.add(cancelButton);
dialogPanel.add(buttonPanel, BorderLayout.SOUTH);
return dialogPanel;
}
/**
* @return true if sorting by time is allowed, false otherwise
*/
protected boolean isSortByTimeAllowed()
{
return true;
}
/**
* @return the selected rearrange option
*/
protected Rearrange getRearrangeOption()
{
if (_positionRadios[0].isSelected()) {
return Rearrange.TO_START;
}
if (_positionRadios[1].isSelected()) {
return Rearrange.TO_END;
}
return Rearrange.TO_NEAREST;
}
/**
* @return the selected sort mode
*/
protected SortMode getSortMode()
{
if (_sortRadios[0].isSelected()) {
return SortMode.DONT_SORT;
}
if (_sortRadios[1].isSelected()) {
return SortMode.SORTBY_NAME;
}
return SortMode.SORTBY_TIME;
}
/** @return key for description */
protected abstract String getDescriptionKey();
/** @return partial key for the sort by name radio */
protected abstract String getSortNameKey();
/**
* Perform the rearrange
*/
protected abstract void finish();
}