/**
*
*/
package cz.cuni.mff.peckam.java.origamist.modelstate.arguments;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.ResourceBundle;
import javax.swing.JOptionPane;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import cz.cuni.mff.peckam.java.origamist.gui.editor.OperationsTree;
import cz.cuni.mff.peckam.java.origamist.gui.editor.PickMode;
import cz.cuni.mff.peckam.java.origamist.model.Operation;
import cz.cuni.mff.peckam.java.origamist.model.OperationContainer;
import cz.cuni.mff.peckam.java.origamist.services.ServiceLocator;
import cz.cuni.mff.peckam.java.origamist.services.interfaces.ConfigurationManager;
import cz.cuni.mff.peckam.java.origamist.utils.LocalizedString;
/**
* Argument that fetches the selected operations.
*
* @author Martin Pecka
*/
public class OperationsArgument extends OperationArgument implements OperationsTreeDataReceiver
{
protected List<Operation> operations = null;
/**
* @param required If true, this argument is required.
* @param resourceBundleKey The key in "editor" resource bundle describing this operation argument.
*/
public OperationsArgument(boolean required, String resourceBundleKey)
{
super(required, resourceBundleKey);
}
@Override
public boolean isComplete()
{
return operations != null && operations.size() > 0;
}
@Override
public PickMode preferredPickMode()
{
return null;
}
public List<Operation> getOperations()
{
if (!isComplete())
throw new IllegalStateException("Cannot query properties of a non-completed argument.");
return operations;
}
@Override
public void readDataFromObject(OperationsTree tree)
{
if (tree.getSelectionCount() > 0) {
operations = new LinkedList<Operation>();
final Map<Operation, TreePath> paths = new HashMap<Operation, TreePath>();
LinkedHashMap<OperationContainer, TreePath> selectedContainers = new LinkedHashMap<OperationContainer, TreePath>();
for (TreePath path : tree.getSelectionPaths()) {
Object userObject = ((DefaultMutableTreeNode) path.getLastPathComponent()).getUserObject();
if (!(userObject instanceof OperationContainer)) {
operations.add((Operation) userObject);
paths.put((Operation) userObject, path);
} else {
selectedContainers.put((OperationContainer) userObject, path);
}
}
for (Entry<OperationContainer, TreePath> entry : selectedContainers.entrySet()) {
for (Operation o : entry.getKey().getOperations()) {
if (!operations.contains(o)) {
operations.add(o);
DefaultMutableTreeNode node = (DefaultMutableTreeNode) entry.getValue().getLastPathComponent();
TreeNode child = null;
@SuppressWarnings("unchecked")
Enumeration<TreeNode> enu = node.children();
while (enu.hasMoreElements()) {
TreeNode childNode = enu.nextElement();
if (((DefaultMutableTreeNode) childNode).getUserObject() == o) {
child = (DefaultMutableTreeNode) childNode;
break;
}
}
paths.put(o, entry.getValue().pathByAddingChild(child));
}
}
}
TreeSelectionModel oldSelModel = tree.getSelectionModel();
tree.setSelectionModel(new DefaultTreeSelectionModel());
tree.getSelectionModel().setSelectionMode(DefaultTreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
tree.setSelectionPaths(paths.values().toArray(new TreePath[] {}));
if (operations.size() == 0)
return;
Collections.sort(operations, new Comparator<Operation>() {
@Override
public int compare(Operation o1, Operation o2)
{
TreePath path1 = paths.get(o1);
TreePath path2 = paths.get(o2);
while (path1.getPathCount() > path2.getPathCount())
path1 = path1.getParentPath();
while (path2.getPathCount() > path1.getPathCount())
path2 = path2.getParentPath();
while (path1.getPathCount() > 0
&& path2.getPathCount() > 0
&& path1.getParentPath().getLastPathComponent() != path2.getParentPath()
.getLastPathComponent()) {
path1 = path1.getParentPath();
path2 = path2.getParentPath();
}
DefaultMutableTreeNode node1 = (DefaultMutableTreeNode) path1.getLastPathComponent();
DefaultMutableTreeNode node2 = (DefaultMutableTreeNode) path2.getLastPathComponent();
int index1 = node1.getParent().getIndex(node1);
int index2 = node2.getParent().getIndex(node2);
if (index1 < index2)
return -1;
else if (index1 > index2)
return 1;
else
return 0;
}
});
ResourceBundle messages = ResourceBundle.getBundle("editor", ServiceLocator.get(ConfigurationManager.class)
.get().getLocale());
if (JOptionPane.showConfirmDialog(null,
messages.getString("operation.argument.last.operations.confirm.message"),
messages.getString("operation.argument.last.operations.confirm.title"), JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) {
operations = null;
tree.setSelectionModel(oldSelModel);
return;
}
tree.setSelectionModel(oldSelModel);
support.firePropertyChange(COMPLETE_PROPERTY, false, true);
} else {
operations = null;
}
}
@Override
public String getL7dUserTip()
{
return new LocalizedString(OperationArgument.class.getName(), "operations.user.tip").toString() + "<br/>"
+ super.getL7dUserTip();
}
}