package puzzledice; import gui.PuzzleEditPanel; import gui.WindowMain; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.swing.BoxLayout; import javax.swing.DefaultComboBoxModel; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.SwingUtilities; import com.mxgraph.view.mxGraph; public class InsertionPuzzleBlock extends PuzzleBlock { private PuzzleBlock _boxBlock, _boxeeBlock; private static int nextIndex = 0; public static void reset() { nextIndex = 0; } private String _boxName, _boxeeName; public void setBoxName(String value) { _boxName = value; } public void setBoxeeName(String value) { _boxeeName = value; } private JComboBox _boxSelect, _boxeeSelect; public InsertionPuzzleBlock() { _name = "Insertion-Puzzle-" + ++nextIndex; _type = "Insertion Puzzle"; JPanel editPanel = new JPanel(); editPanel.setLayout(new BoxLayout(editPanel, BoxLayout.Y_AXIS)); // Box Panel JPanel boxPanel = new JPanel(); boxPanel.setLayout(new BoxLayout(boxPanel, BoxLayout.X_AXIS)); JLabel boxLabel = new JLabel("Box:"); boxPanel.add(boxLabel); _boxSelect = new JComboBox(); _boxSelect.setMaximumSize(new Dimension(Integer.MAX_VALUE, _boxSelect.getPreferredSize().height)); boxPanel.add(_boxSelect); editPanel.add(boxPanel); // Boxee panel JPanel boxeePanel = new JPanel(); boxeePanel.setLayout(new BoxLayout(boxeePanel, BoxLayout.X_AXIS)); JLabel boxeeLabel = new JLabel("Item to Insert:"); boxeePanel.add(boxeeLabel); _boxeeSelect = new JComboBox(); _boxeeSelect.setMaximumSize(new Dimension(Integer.MAX_VALUE, _boxeeSelect.getPreferredSize().height)); boxeePanel.add(_boxeeSelect); editPanel.add(boxeePanel); _editUI = editPanel; _boxSelect.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { if(_boxBlock == _boxSelect.getSelectedItem() || _boxBlock == null && _boxSelect.getSelectedItem().equals("None")) return; mxGraph puzzleGraph = WindowMain.getPuzzleGraph(); // Before anything, check for a cycle if (_boxSelect.getSelectedItem() != null && !_boxSelect.getSelectedItem().equals("None")) { PuzzleBlock block = (PuzzleBlock)_boxSelect.getSelectedItem(); if (block.canReachBlockBackwards(InsertionPuzzleBlock.this)) { SwingUtilities.invokeLater(new Runnable() { public void run() { JOptionPane.showMessageDialog(null, "Error: Cannot add cycle to puzzle graph."); } }); if (_boxBlock != null) _boxSelect.setSelectedItem(_boxBlock); else _boxSelect.setSelectedIndex(0); return; } } // first, see if we need to remove a previous edge if(_boxBlock != null) { puzzleGraph.getModel().beginUpdate(); try { puzzleGraph.removeCells(puzzleGraph.getEdgesBetween(_boxBlock.getGraphCell(), _graphCell, false)); } finally { puzzleGraph.getModel().endUpdate(); } } if (_boxSelect.getSelectedItem() == null) _boxSelect.setSelectedIndex(0); if(_boxSelect.getSelectedItem().equals("None")) _boxBlock = null; else { _boxBlock = (PuzzleBlock)_boxSelect.getSelectedItem(); // update the graph with a new edge puzzleGraph.getModel().beginUpdate(); try { puzzleGraph.insertEdge(puzzleGraph.getDefaultParent(), null, null, _boxBlock.getGraphCell(), _graphCell);} finally { puzzleGraph.getModel().endUpdate();} } // Update the other list _boxeeSelect.setModel(new DefaultComboBoxModel(makeBoxeeList())); if (_boxeeBlock == null) _boxeeSelect.setSelectedIndex(0); else _boxeeSelect.setSelectedItem(_boxeeBlock); PuzzleEditPanel.resetTextualDescription(); WindowMain.updatePuzzleGraph(); } }); _boxeeSelect.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { if(_boxeeBlock == _boxeeSelect.getSelectedItem() || _boxeeBlock == null && _boxeeSelect.getSelectedItem().equals("None")) return; mxGraph puzzleGraph = WindowMain.getPuzzleGraph(); // Before anything, check for a cycle if (_boxeeSelect.getSelectedItem() != null && !_boxeeSelect.getSelectedItem().equals("None")) { PuzzleBlock block = (PuzzleBlock)_boxeeSelect.getSelectedItem(); if (block.canReachBlockBackwards(InsertionPuzzleBlock.this)) { SwingUtilities.invokeLater(new Runnable() { public void run() { JOptionPane.showMessageDialog(null, "Error: Cannot add cycle to puzzle graph."); } }); if (_boxeeBlock != null) _boxeeSelect.setSelectedItem(_boxeeBlock); else _boxeeSelect.setSelectedIndex(0); return; } } // first, see if we need to remove a previous edge if(_boxeeBlock != null) { puzzleGraph.getModel().beginUpdate(); try { puzzleGraph.removeCells(puzzleGraph.getEdgesBetween(_boxeeBlock.getGraphCell(), _graphCell, false)); } finally { puzzleGraph.getModel().endUpdate(); } } if (_boxeeSelect.getSelectedItem() == null) _boxeeSelect.setSelectedIndex(0); if(_boxeeSelect.getSelectedItem().equals("None")) _boxeeBlock = null; else { _boxeeBlock = (PuzzleBlock)_boxeeSelect.getSelectedItem(); puzzleGraph.getModel().beginUpdate(); try { puzzleGraph.insertEdge(puzzleGraph.getDefaultParent(), null, null, _boxeeBlock.getGraphCell(), _graphCell);} finally { puzzleGraph.getModel().endUpdate();} } // Update the other list _boxSelect.setModel(new DefaultComboBoxModel(makeBoxList())); if(_boxBlock == null) _boxSelect.setSelectedIndex(0); else _boxSelect.setSelectedItem(_boxBlock); PuzzleEditPanel.resetTextualDescription(); WindowMain.updatePuzzleGraph(); } }); } @Override public void update() { // Update the UI ComboBoxes and the selected values _boxSelect.setModel(new DefaultComboBoxModel(makeBoxList())); if(_boxBlock == null) _boxSelect.setSelectedIndex(0); else _boxSelect.setSelectedItem(_boxBlock); _boxeeSelect.setModel(new DefaultComboBoxModel(makeBoxeeList())); if(_boxeeBlock == null) _boxeeSelect.setSelectedIndex(0); else _boxeeSelect.setSelectedItem(_boxeeBlock); } private Object[] makeBoxList() { List<Object> retVal = new ArrayList<Object>(); PuzzleBlock[] blockList = PuzzleEditPanel.getBlockList(); retVal.add("None"); for(PuzzleBlock p : blockList) { if(!p.equals(_boxeeSelect.getSelectedItem()) && !p.equals(this)) retVal.add(p); } return retVal.toArray(); } private Object[] makeBoxeeList() { List<Object> retVal = new ArrayList<Object>(); PuzzleBlock[] blockList = PuzzleEditPanel.getBlockList(); retVal.add("None"); for(PuzzleBlock p : blockList) { if(!p.equals(_boxSelect.getSelectedItem()) && !p.equals(this)) retVal.add(p); } return retVal.toArray(); } @Override public void maybeRemoveRef(PuzzleBlock block) { if(block.equals(_boxBlock)) { _boxBlock = null; _boxSelect.setSelectedIndex(0); } if(block.equals(_boxeeBlock)) { _boxeeBlock = null; _boxeeSelect.setSelectedIndex(0); } } @Override public String getTextualDescription() { String retVal = ""; if(_boxeeBlock != null) retVal += _boxeeBlock.getTextualDescription(); if(_boxBlock != null) retVal += _boxBlock.getTextualDescription(); String box = (_boxBlock == null) ? "SOMETHING" : _boxBlock.getOutputTempName(); String boxee = (_boxeeBlock == null) ? "SOMETHING" : _boxeeBlock.getOutputTempName(); retVal += "The player puts " + boxee + " inside of " + box + ". "; _outputTempName = box + "(containing " + boxee + ")"; return retVal; } @Override public void attachBlocksToName(Map<String, AreaBlock> areas, Map<String, PuzzleBlock> puzzles) { mxGraph puzzleGraph = WindowMain.getPuzzleGraph(); if (_boxName != null) { _boxBlock = puzzles.get(_boxName); puzzleGraph.getModel().beginUpdate(); try { puzzleGraph.insertEdge(puzzleGraph.getDefaultParent(), null, null, _boxBlock.getGraphCell(), _graphCell);} finally { puzzleGraph.getModel().endUpdate();} } if (_boxeeName != null) { _boxeeBlock = puzzles.get(_boxeeName); puzzleGraph.getModel().beginUpdate(); try { puzzleGraph.insertEdge(puzzleGraph.getDefaultParent(), null, null, _boxeeBlock.getGraphCell(), _graphCell);} finally { puzzleGraph.getModel().endUpdate();} } this.update(); } @Override public PuzzleBlock[] getPuzzleInputs() { if (_boxBlock != null && _boxeeBlock != null) return new PuzzleBlock[] { _boxBlock, _boxeeBlock }; else if (_boxBlock != null) return new PuzzleBlock[] { _boxBlock }; else if (_boxeeBlock != null) return new PuzzleBlock[] { _boxeeBlock }; return new PuzzleBlock[0]; } @Override public String toXML() { String xml = "<InsertionPuzzle name=\"" + _name + "\" "; if (_boxeeBlock != null) xml += "boxee=\"" + _boxeeBlock.getName() + "\" "; if (_boxBlock != null) xml += "box=\"" + _boxBlock.getName() + "\" "; xml += "/>"; return xml; } }