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 CombinePuzzleBlock extends PuzzleBlock { private PuzzleBlock _ingredientBlock1, _ingredientBlock2; private static int nextIndex = 0; public static void reset() { nextIndex = 0; } private String _ingredientName1, _ingredientName2; public void setIngredientName1(String value) { _ingredientName1 = value; } public void setIngredientName2(String value) { _ingredientName2 = value; } private JComboBox _ingredientSelect1, _ingredientSelect2; public CombinePuzzleBlock() { _name = "Combine-Puzzle-" + ++nextIndex; _type = "Combine Puzzle"; JPanel editPanel = new JPanel(); editPanel.setLayout(new BoxLayout(editPanel, BoxLayout.Y_AXIS)); // First combobox panel JPanel ingredientPanel1 = new JPanel(); ingredientPanel1.setLayout(new BoxLayout(ingredientPanel1, BoxLayout.X_AXIS)); JLabel ingredientLabel1 = new JLabel("Ingredient 1:"); ingredientPanel1.add(ingredientLabel1); _ingredientSelect1 = new JComboBox(); _ingredientSelect1.setMaximumSize(new Dimension(Integer.MAX_VALUE, _ingredientSelect1.getPreferredSize().height)); ingredientPanel1.add(_ingredientSelect1); editPanel.add(ingredientPanel1); JPanel ingredientPanel2 = new JPanel(); ingredientPanel2.setLayout(new BoxLayout(ingredientPanel2, BoxLayout.X_AXIS)); JLabel ingredientLabel2 = new JLabel("Ingredient 2:"); ingredientPanel2.add(ingredientLabel2); _ingredientSelect2 = new JComboBox(); _ingredientSelect2.setMaximumSize(new Dimension(Integer.MAX_VALUE, _ingredientSelect2.getPreferredSize().height)); ingredientPanel2.add(_ingredientSelect2); editPanel.add(ingredientPanel2); _editUI = editPanel; _ingredientSelect1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { if(_ingredientBlock1 == _ingredientSelect1.getSelectedItem() || _ingredientBlock1 == null && _ingredientSelect1.getSelectedItem().equals("None")) return; mxGraph puzzleGraph = WindowMain.getPuzzleGraph(); // Before anything, check for a cycle if (_ingredientSelect1.getSelectedItem() != null && !_ingredientSelect1.getSelectedItem().equals("None")) { PuzzleBlock block = (PuzzleBlock)_ingredientSelect1.getSelectedItem(); if (block.canReachBlockBackwards(CombinePuzzleBlock.this)) { SwingUtilities.invokeLater(new Runnable() { public void run() { JOptionPane.showMessageDialog(null, "Error: Cannot add cycle to puzzle graph."); } }); if (_ingredientBlock1 != null) _ingredientSelect1.setSelectedItem(_ingredientBlock1); else _ingredientSelect1.setSelectedIndex(0); return; } } // first, see if we need to remove a previous edge if(_ingredientBlock1 != null) { puzzleGraph.getModel().beginUpdate(); try { puzzleGraph.removeCells(puzzleGraph.getEdgesBetween(_ingredientBlock1.getGraphCell(), _graphCell, false));} finally {puzzleGraph.getModel().endUpdate();} } if (_ingredientSelect1.getSelectedItem() == null) _ingredientSelect1.setSelectedIndex(0); if(_ingredientSelect1.getSelectedItem().equals("None")) _ingredientBlock1 = null; else { _ingredientBlock1 = (PuzzleBlock)_ingredientSelect1.getSelectedItem(); // update the graph with a new edge puzzleGraph.getModel().beginUpdate(); try { puzzleGraph.insertEdge(puzzleGraph.getDefaultParent(), null, null, _ingredientBlock1.getGraphCell(), _graphCell); } finally {puzzleGraph.getModel().endUpdate();} } // Need to update our other ingredient list _ingredientSelect2.setModel(new DefaultComboBoxModel(makeComboBoxList2())); // Update our selected values if (_ingredientBlock2 == null) _ingredientSelect2.setSelectedIndex(0); else _ingredientSelect2.setSelectedItem(_ingredientBlock2); PuzzleEditPanel.resetTextualDescription(); WindowMain.updatePuzzleGraph(); } }); _ingredientSelect2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { if(_ingredientBlock2 == _ingredientSelect2.getSelectedItem() || _ingredientBlock2 == null && _ingredientSelect2.getSelectedItem().equals("None")) return; mxGraph puzzleGraph = WindowMain.getPuzzleGraph(); // Before anything, check for a cycle if (_ingredientSelect2.getSelectedItem() != null && !_ingredientSelect2.getSelectedItem().equals("None")) { PuzzleBlock block = (PuzzleBlock)_ingredientSelect2.getSelectedItem(); if (block.canReachBlockBackwards(CombinePuzzleBlock.this)) { SwingUtilities.invokeLater(new Runnable() { public void run() { JOptionPane.showMessageDialog(null, "Error: Cannot add cycle to puzzle graph."); } }); if (_ingredientBlock2 != null) _ingredientSelect2.setSelectedItem(_ingredientBlock2); else _ingredientSelect2.setSelectedIndex(0); return; } } // first, see if we need to remove a previous edge if(_ingredientBlock2 != null) { puzzleGraph.getModel().beginUpdate(); try { puzzleGraph.removeCells(puzzleGraph.getEdgesBetween(_ingredientBlock2.getGraphCell(), _graphCell, false));} finally {puzzleGraph.getModel().endUpdate();} } if (_ingredientSelect2.getSelectedItem() == null) _ingredientSelect2.setSelectedIndex(0); if(_ingredientSelect2.getSelectedItem().equals("None")) _ingredientBlock2 = null; else { _ingredientBlock2 = (PuzzleBlock)_ingredientSelect2.getSelectedItem(); // update the graph with a new edge puzzleGraph.getModel().beginUpdate(); try { puzzleGraph.insertEdge(puzzleGraph.getDefaultParent(), null, null, _ingredientBlock2.getGraphCell(), _graphCell); } finally {puzzleGraph.getModel().endUpdate();} } _ingredientSelect1.setModel(new DefaultComboBoxModel(makeComboBoxList1())); // Update our selected values if (_ingredientBlock1 == null) _ingredientSelect1.setSelectedIndex(0); else _ingredientSelect1.setSelectedItem(_ingredientBlock1); PuzzleEditPanel.resetTextualDescription(); WindowMain.updatePuzzleGraph(); } }); } @Override public void update() { // Update the UI comboBoxes _ingredientSelect1.setModel(new DefaultComboBoxModel(makeComboBoxList1())); // Update our selected values if (_ingredientBlock1 == null) _ingredientSelect1.setSelectedIndex(0); else _ingredientSelect1.setSelectedItem(_ingredientBlock1); _ingredientSelect2.setModel(new DefaultComboBoxModel(makeComboBoxList2())); if(_ingredientBlock2 == null) _ingredientSelect2.setSelectedIndex(0); else _ingredientSelect2.setSelectedItem(_ingredientBlock2); } private Object[] makeComboBoxList1() { List<Object> retVal = new ArrayList<Object>(); PuzzleBlock[] blockList = PuzzleEditPanel.getBlockList(); retVal.add("None"); for(PuzzleBlock p : blockList) { if(!p.equals(_ingredientSelect2.getSelectedItem()) && !p.equals(this)) retVal.add(p); } return retVal.toArray(); } private Object[] makeComboBoxList2() { List<Object> retVal = new ArrayList<Object>(); PuzzleBlock[] blockList = PuzzleEditPanel.getBlockList(); retVal.add("None"); for(PuzzleBlock p : blockList) { if(!p.equals(_ingredientSelect1.getSelectedItem()) && !p.equals(this)) retVal.add(p); } return retVal.toArray(); } @Override public void maybeRemoveRef(PuzzleBlock block) { if(block.equals(_ingredientBlock1)) { _ingredientBlock1 = null; _ingredientSelect1.setSelectedIndex(0); } if(block.equals(_ingredientBlock2)) { _ingredientBlock2 = null; _ingredientSelect2.setSelectedIndex(0); } } @Override public String getTextualDescription() { String retVal = ""; if(_ingredientBlock1 != null) retVal += _ingredientBlock1.getTextualDescription(); if(_ingredientBlock2 != null) retVal += _ingredientBlock2.getTextualDescription(); _outputTempName = PuzzleEditPanel.nextItemName(); String input1 = (_ingredientBlock1 == null) ? "SOMETHING" : _ingredientBlock1.getOutputTempName(); String input2 = (_ingredientBlock2 == null) ? "SOMETHING" : _ingredientBlock2.getOutputTempName(); retVal += "The Player combines " + input1 + " with " + input2 + " to create " + _outputTempName + ". "; return retVal; } @Override public void attachBlocksToName(Map<String, AreaBlock> areas, Map<String, PuzzleBlock> puzzles) { mxGraph puzzleGraph = WindowMain.getPuzzleGraph(); if (_ingredientName1 != null) { _ingredientBlock1 = puzzles.get(_ingredientName1); puzzleGraph.getModel().beginUpdate(); try { puzzleGraph.insertEdge(puzzleGraph.getDefaultParent(), null, null, _ingredientBlock1.getGraphCell(), _graphCell); } finally {puzzleGraph.getModel().endUpdate();} } if (_ingredientName2 != null) { _ingredientBlock2 = puzzles.get(_ingredientName2); puzzleGraph.getModel().beginUpdate(); try { puzzleGraph.insertEdge(puzzleGraph.getDefaultParent(), null, null, _ingredientBlock2.getGraphCell(), _graphCell); } finally {puzzleGraph.getModel().endUpdate();} } this.update(); } @Override public PuzzleBlock[] getPuzzleInputs() { if (_ingredientBlock1 != null && _ingredientBlock2 != null) return new PuzzleBlock[] { _ingredientBlock1, _ingredientBlock2 }; else if (_ingredientBlock1 != null) return new PuzzleBlock[] { _ingredientBlock1 }; else if (_ingredientBlock2 != null) return new PuzzleBlock[] { _ingredientBlock2 }; else return new PuzzleBlock[0]; } @Override public String toXML() { String xml = "<CombinePuzzle name=\"" + _name + "\" "; if (_ingredientBlock1 != null) xml += "ingredient1=\"" + _ingredientBlock1.getName() + "\" "; if (_ingredientBlock2 != null) xml += "ingredient2=\"" + _ingredientBlock2.getName() + "\" "; xml += "/>"; return xml; } }