/* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ package mage.client.deck.generator; import java.awt.*; import java.awt.event.ActionListener; import java.awt.event.ItemListener; import java.io.File; import java.text.SimpleDateFormat; import java.util.Date; import javax.swing.*; import javax.swing.border.CompoundBorder; import javax.swing.border.EmptyBorder; import javax.swing.border.EtchedBorder; import mage.cards.Sets; import mage.cards.decks.Deck; import mage.client.MageFrame; import mage.client.dialog.PreferencesDialog; import mage.client.util.gui.ColorsChooser; import mage.client.util.sets.ConstructedFormats; /** * * @author Simown */ public class DeckGeneratorDialog { private static JDialog dlg; private static String selectedColors; private static JComboBox cbSets, cbDeckSize, cbCMC; private static JButton btnGenerate, btnCancel, btnReset; private static JCheckBox cArtifacts, cSingleton, cNonBasicLands, cColorless, cAdvanced; private static JLabel averageCMCLabel; private static SimpleDateFormat dateFormat; private static RatioAdjustingSliderPanel adjustingSliderPanel; public DeckGeneratorDialog() { initDialog(); dateFormat = new SimpleDateFormat("dd-MM-yyyy-hh-mm-ss-SSS"); } private void initDialog() { JPanel mainPanel = new JPanel(); mainPanel.setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.insets = new Insets(0, 15, 0, 0); c.fill = GridBagConstraints.HORIZONTAL; c.gridx = 0; c.gridy = 0; c.weightx = 0.10; JLabel text = new JLabel("Choose color for your deck:"); mainPanel.add(text, c); // Color selector dropdown c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 0.80; c.ipadx = 30; c.insets = new Insets(5, 10, 0, 10); c.gridx = 1; c.gridy = 0; String chosen = MageFrame.getPreferences().get("genDeckColor", "u"); final ColorsChooser colorsChooser = new ColorsChooser(chosen); mainPanel.add(colorsChooser, c); c.insets = new Insets(0, 15, 0, 0); c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 0.10; c.gridx = 2; c.gridy = 0; c.ipadx = 0; JLabel text2 = new JLabel("(X = random color)"); mainPanel.add(text2); // Format/set label JLabel formatSetText = new JLabel("Choose format/set for your deck:"); c.fill = GridBagConstraints.HORIZONTAL; c.gridx = 0; c.gridy = 1; c.weightx = 0.10; mainPanel.add(formatSetText, c); // Format/set dropdown c.fill = GridBagConstraints.HORIZONTAL; c.gridx = 1; c.gridy = 1; c.ipadx = 30; c.insets = new Insets(5, 10, 0, 10); c.weightx = 0.90; cbSets = new JComboBox<>(ConstructedFormats.getTypes()); cbSets.setSelectedIndex(0); mainPanel.add(cbSets, c); String prefSet = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_SET, null); if (prefSet != null) { cbSets.setSelectedItem(prefSet); } // Deck size label c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(0, 15, 0, 0); c.ipadx = 0; c.gridx = 0; c.gridy = 2; c.weightx = 0.10; JLabel textDeckSize = new JLabel("Deck size:"); mainPanel.add(textDeckSize, c); // Deck size dropdown c.fill = GridBagConstraints.HORIZONTAL; c.gridx = 1; c.gridy = 2; c.ipadx = 30; c.insets = new Insets(5, 10, 0, 10); c.weightx = 0.90; cbDeckSize = new JComboBox<>(new String[]{"40", "60"}); cbDeckSize.setSelectedIndex(0); cbDeckSize.setAlignmentX(Component.LEFT_ALIGNMENT); mainPanel.add(cbDeckSize, c); String prefSize = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_DECK_SIZE, "60"); if (prefSet != null) { cbDeckSize.setSelectedItem(prefSize); } JPanel jCheckBoxes = new JPanel(new FlowLayout(FlowLayout.LEFT)); // Singletons cSingleton = new JCheckBox("Singleton", false); cSingleton.setToolTipText("Allow only a single copy of each non-land card in your deck."); String singletonEnabled = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_SINGLETON, "false"); cSingleton.setSelected(Boolean.valueOf(singletonEnabled)); jCheckBoxes.add(cSingleton); // Artifacts cArtifacts = new JCheckBox("Artifacts", false); cArtifacts.setToolTipText("Use artifacts and artifact creatures in your deck."); String artifactEnabled = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_ARTIFACTS, "false"); cArtifacts.setSelected(Boolean.valueOf(artifactEnabled)); jCheckBoxes.add(cArtifacts); // Non-basic lands cNonBasicLands = new JCheckBox("Non-basic Lands", false); cNonBasicLands.setToolTipText("Use non-basic lands in your deck (if applicable)."); String nonBasicEnabled = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_NON_BASIC_LANDS, "false"); cNonBasicLands.setSelected(Boolean.valueOf(nonBasicEnabled)); jCheckBoxes.add(cNonBasicLands); // Colorless mana cColorless = new JCheckBox("Colorless mana", false); cColorless.setToolTipText("Allow cards with colorless mana cost."); String colorlessEnabled = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_COLORLESS, "false"); cColorless.setSelected(Boolean.valueOf(colorlessEnabled)); jCheckBoxes.add(cColorless); c.ipadx = 0; c.gridx = 0; c.gridy = 3; c.weightx = 1; c.gridwidth = 3; mainPanel.add(jCheckBoxes, c); // Create the advanced configuration panel JPanel advancedPanel = createAdvancedPanel(); // Advanced checkbox (enable/disable advanced configuration) cAdvanced = new JCheckBox("Advanced"); cAdvanced.setToolTipText("Enable advanced configuration options"); cAdvanced.addItemListener(itemEvent -> { boolean enable = cAdvanced.isSelected(); enableAdvancedPanel(enable); }); // Advanced Checkbox String advancedSavedValue = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_ADVANCED, "false"); boolean advancedEnabled = Boolean.valueOf(advancedSavedValue); enableAdvancedPanel(advancedEnabled); cAdvanced.setSelected(advancedEnabled); c.gridy = 4; c.weightx = 0; c.insets = new Insets(10, 15, 10, 0); mainPanel.add(cAdvanced, c); c.gridy = 5; c.weightx = 1; c.insets = new Insets(5, 10, 0, 5); mainPanel.add(advancedPanel, c); btnGenerate = new JButton("Ok"); btnGenerate.addActionListener(e -> { btnGenerate.setEnabled(false); colorsChooser.setEnabled(false); selectedColors = (String) colorsChooser.getSelectedItem(); dlg.setVisible(false); MageFrame.getPreferences().put("genDeckColor", selectedColors); }); btnCancel = new JButton("Cancel"); btnCancel.addActionListener(e -> { dlg.setVisible(false); selectedColors = null; }); JButton[] options = {btnGenerate, btnCancel}; JOptionPane optionPane = new JOptionPane(mainPanel, JOptionPane.PLAIN_MESSAGE, JOptionPane.DEFAULT_OPTION, null, options, options[1]); dlg = optionPane.createDialog("Generating Deck"); dlg.setResizable(false); dlg.setVisible(true); dlg.dispose(); } private void enableAdvancedPanel(boolean enable) { adjustingSliderPanel.setEnabled(enable); btnReset.setEnabled(enable); cbCMC.setEnabled(enable); averageCMCLabel.setEnabled(enable); } private JPanel createAdvancedPanel() { JPanel advancedPanel = new JPanel(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); // Average CMC Label c.fill = GridBagConstraints.HORIZONTAL; c.gridx = 0; c.gridy = 0; c.weightx = 0.10; averageCMCLabel = new JLabel("Average CMC:"); advancedPanel.add(averageCMCLabel, c); // CMC selection dropdown c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 0.90; c.gridx = 2; c.gridy = 0; cbCMC = new JComboBox<>(DeckGeneratorCMC.values()); cbCMC.setSelectedItem(DeckGeneratorCMC.Default); String cmcSelected = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_ADVANCED_CMC, DeckGeneratorCMC.Default.name()); cbCMC.setSelectedItem(DeckGeneratorCMC.valueOf(cmcSelected)); advancedPanel.add(cbCMC, c); // Advanced percentage sliders c.fill = GridBagConstraints.HORIZONTAL; c.ipady = 20; c.ipadx = 40; c.weightx = 1; c.gridwidth = 3; c.gridx = 0; c.gridy = 1; c.insets = new Insets(10, 0, 0, 0); adjustingSliderPanel = new RatioAdjustingSliderPanel(); // Restore saved slider values String creaturePercentage = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_CREATURE_PERCENTAGE, Integer.toString(DeckGeneratorPool.DEFAULT_CREATURE_PERCENTAGE)); adjustingSliderPanel.setCreaturePercentage(Integer.parseInt(creaturePercentage)); String nonCreaturePercentage = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_NON_CREATURE_PERCENTAGE, Integer.toString(DeckGeneratorPool.DEFAULT_NON_CREATURE_PERCENTAGE)); adjustingSliderPanel.setNonCreaturePercentage(Integer.parseInt(nonCreaturePercentage)); String landPercentage = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_LAND_PERCENTAGE, Integer.toString(DeckGeneratorPool.DEFAULT_LAND_PERCENTAGE)); adjustingSliderPanel.setLandPercentage(Integer.parseInt(landPercentage)); advancedPanel.add(adjustingSliderPanel, c); // Reset c.fill = GridBagConstraints.NONE; c.ipadx = 0; c.ipady = 0; c.weightx = 1.0; c.anchor = GridBagConstraints.LAST_LINE_END; c.insets = new Insets(10, 10, 0, 0); c.gridx = 2; c.gridwidth = 1; c.gridy = 2; btnReset = new JButton("Reset"); btnReset.setToolTipText("Reset advanced dialog to default values"); btnReset.addActionListener(actionEvent -> { cbCMC.setSelectedItem(DeckGeneratorCMC.Default); adjustingSliderPanel.resetValues(); }); advancedPanel.add(btnReset, c); // Add a border around the advanced bits CompoundBorder border = BorderFactory.createCompoundBorder(new EtchedBorder(), new EmptyBorder(10, 10, 10, 10)); advancedPanel.setBorder(border); return advancedPanel; } public void cleanUp() { for (ActionListener al : btnGenerate.getActionListeners()) { btnGenerate.removeActionListener(al); } for (ActionListener al : btnCancel.getActionListeners()) { btnCancel.removeActionListener(al); } for (ActionListener al : btnReset.getActionListeners()) { btnReset.removeActionListener(al); } for (ItemListener il : cAdvanced.getItemListeners()) { cAdvanced.removeItemListener(il); } } public String saveDeck(Deck deck) { try { // Random directory through the system property to avoid random numeric string attached to temp files. String tempDir = System.getProperty("java.io.tmpdir"); // Generated deck has a nice unique name which corresponds to the timestamp at which it was created. String deckName = "Generated-Deck-" + dateFormat.format(new Date()); File tmp = new File(tempDir + File.separator + deckName + ".dck"); tmp.createNewFile(); deck.setName(deckName); Sets.saveDeck(tmp.getAbsolutePath(), deck.getDeckCardLists()); cleanUp(); return tmp.getAbsolutePath(); } catch (Exception e) { MageFrame.getInstance().showError("Couldn't generate deck. Try again."); } return null; } public String getSelectedFormat() { return (String) cbSets.getSelectedItem(); } public boolean isSingleton() { boolean selected = cSingleton.isSelected(); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_SINGLETON, Boolean.toString(selected)); return selected; } public boolean isColorless() { boolean selected = cColorless.isSelected(); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_COLORLESS, Boolean.toString(selected)); return selected; } public boolean useArtifacts() { boolean selected = cArtifacts.isSelected(); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_ARTIFACTS, Boolean.toString(selected)); return selected; } public boolean useNonBasicLand() { boolean selected = cNonBasicLands.isSelected(); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_NON_BASIC_LANDS, Boolean.toString(selected)); return selected; } public boolean isAdvanced() { boolean selected = cAdvanced.isSelected(); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_ADVANCED, Boolean.toString(selected)); return selected; } public int getCreaturePercentage() { int percentage = adjustingSliderPanel.getCreaturePercentage(); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_CREATURE_PERCENTAGE, Integer.toString(percentage)); return percentage; } public int getNonCreaturePercentage() { int percentage = adjustingSliderPanel.getNonCreaturePercentage(); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_NON_CREATURE_PERCENTAGE, Integer.toString(percentage)); return percentage; } public int getLandPercentage() { int percentage = adjustingSliderPanel.getLandPercentage(); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_LAND_PERCENTAGE, Integer.toString(percentage)); return percentage; } public int getDeckSize() { return Integer.parseInt(cbDeckSize.getSelectedItem().toString()); } public DeckGeneratorCMC getDeckGeneratorCMC() { DeckGeneratorCMC selectedCMC = (DeckGeneratorCMC) cbCMC.getSelectedItem(); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_ADVANCED_CMC, selectedCMC.name()); return selectedCMC; } public String getSelectedColors() { if (selectedColors != null) { PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_DECK_SIZE, cbDeckSize.getSelectedItem().toString()); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_SET, cbSets.getSelectedItem().toString()); } return selectedColors; } }