1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.sf.magicproject;
20
21 import java.awt.BorderLayout;
22 import java.awt.Color;
23 import java.awt.Component;
24 import java.awt.Dimension;
25 import java.awt.Paint;
26 import java.awt.event.ActionEvent;
27 import java.awt.event.InputEvent;
28 import java.awt.event.KeyEvent;
29 import java.awt.event.MouseEvent;
30 import java.awt.event.WindowEvent;
31 import java.io.FileInputStream;
32 import java.io.IOException;
33 import java.util.ArrayList;
34 import java.util.Collection;
35 import java.util.Collections;
36 import java.util.HashMap;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.TreeMap;
40
41 import javax.swing.BoxLayout;
42 import javax.swing.JButton;
43 import javax.swing.JDialog;
44 import javax.swing.JFileChooser;
45 import javax.swing.JFrame;
46 import javax.swing.JLabel;
47 import javax.swing.JList;
48 import javax.swing.JMenu;
49 import javax.swing.JMenuBar;
50 import javax.swing.JMenuItem;
51 import javax.swing.JOptionPane;
52 import javax.swing.JPanel;
53 import javax.swing.JScrollPane;
54 import javax.swing.JSeparator;
55 import javax.swing.JTabbedPane;
56 import javax.swing.JTable;
57 import javax.swing.JTextField;
58 import javax.swing.JToggleButton;
59 import javax.swing.JToolBar;
60 import javax.swing.KeyStroke;
61 import javax.swing.ListSelectionModel;
62 import javax.swing.SwingConstants;
63 import javax.swing.border.EtchedBorder;
64 import javax.swing.event.ListSelectionEvent;
65 import javax.swing.event.ListSelectionListener;
66 import javax.swing.event.TableModelEvent;
67 import javax.swing.event.TableModelListener;
68
69 import net.sf.magicproject.chart.CardColor;
70 import net.sf.magicproject.chart.CardManaCost;
71 import net.sf.magicproject.chart.CardTypes;
72 import net.sf.magicproject.chart.ChartFilter;
73 import net.sf.magicproject.chart.ChartSets;
74 import net.sf.magicproject.chart.IChartKey;
75 import net.sf.magicproject.chart.IDataProvider;
76 import net.sf.magicproject.chart.datasets.Dataset;
77 import net.sf.magicproject.clickable.targetable.card.CardFactory;
78 import net.sf.magicproject.clickable.targetable.card.CardModel;
79 import net.sf.magicproject.clickable.targetable.card.MCard;
80 import net.sf.magicproject.deckbuilder.CardView;
81 import net.sf.magicproject.deckbuilder.ConstraintsChecker;
82 import net.sf.magicproject.deckbuilder.Deck;
83 import net.sf.magicproject.deckbuilder.DeckReader;
84 import net.sf.magicproject.deckbuilder.DeckRules;
85 import net.sf.magicproject.deckbuilder.MdbLoader;
86 import net.sf.magicproject.token.IdCardColors;
87 import net.sf.magicproject.token.IdCommonToken;
88 import net.sf.magicproject.token.IdConst;
89 import net.sf.magicproject.tools.Configuration;
90 import net.sf.magicproject.tools.Converter;
91 import net.sf.magicproject.tools.FileFilterPlus;
92 import net.sf.magicproject.tools.MCardCompare;
93 import net.sf.magicproject.tools.MSaveDeck;
94 import net.sf.magicproject.tools.MToolKit;
95 import net.sf.magicproject.tools.Picture;
96 import net.sf.magicproject.ui.HireListener;
97 import net.sf.magicproject.ui.MCardTableModel;
98 import net.sf.magicproject.ui.MListModel;
99 import net.sf.magicproject.ui.RefreshableAdd;
100 import net.sf.magicproject.ui.UIHelper;
101 import net.sf.magicproject.ui.i18n.LanguageManager;
102 import net.sf.magicproject.ui.i18n.LanguageManagerMDB;
103 import net.sf.magicproject.ui.wizard.About;
104
105 import org.jfree.chart.ChartPanel;
106 import org.jfree.chart.JFreeChart;
107
108 /***
109 * This class is a deck builder compatible with Magic-project deck format. Can
110 * also export/import other formats.
111 *
112 * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
113 * @author <a href="mailto:goldeneyemdk@users.sourceforge.net">Sebastien Genete
114 * </a>
115 * @author Jan Blaha for deck loader and statistics
116 * @since 0.2 2003/12/06, settings are loaded.
117 * @since 0.2 you can load a deck file.
118 * @since 0.2 you can load a specified mdb file (is MagicProject card list
119 * file).
120 * @since 0.3 2003/12/12, you can save a deck file.
121 * @since 0.3 new deck feature.
122 * @since 0.4 sort mdb file feature for optimized load.
123 * @since 0.4 deck are saved with alphabitacally sort.
124 * @since 0.5 statistics feature added.
125 * @since 0.81 deck converter added.
126 * @since 0.83 cleaned code, deck constraints form added.
127 * @since 0.93 pie chart added, color filtering
128 * @since 0.94 use of JTable instead of JList
129 */
130 public final class DeckBuilder extends AbstractMainForm implements
131 ListSelectionListener, RefreshableAdd, IDataProvider, TableModelListener {
132
133 /***
134 * Creates new form DeckBuilder
135 */
136 private DeckBuilder() {
137 super("DeckBuilder");
138 try {
139 setIconImage(Picture.loadImage(IdConst.IMAGES_DIR + "deckbuilder.gif"));
140 } catch (Exception e) {
141
142 }
143
144
145 loadSettings();
146
147
148 constraintsChecker = new ConstraintsChecker();
149 constraintsChecker.setBorder(new EtchedBorder());
150 final JScrollPane constraintsCheckerScroll = new JScrollPane(
151 constraintsChecker);
152 MToolKit.addOverlay(constraintsCheckerScroll);
153 constraintsCheckerScroll.setMinimumSize(new Dimension(200, 270));
154
155 final JMenuItem newItem = UIHelper.buildMenu("menu_db_new", 'n', this);
156 newItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,
157 InputEvent.CTRL_MASK));
158
159 final JMenuItem loadItem = UIHelper.buildMenu("menu_db_load", 'o', this);
160 loadItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O,
161 InputEvent.CTRL_MASK));
162
163 final JMenuItem saveAsItem = UIHelper
164 .buildMenu("menu_db_saveas", 'a', this);
165 saveAsItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F12, 0));
166
167 final JMenuItem saveItem = UIHelper.buildMenu("menu_db_save", 's', this);
168 saveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
169 InputEvent.CTRL_MASK));
170
171 final JMenuItem quitItem = UIHelper.buildMenu("menu_db_exit", this);
172 quitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4,
173 InputEvent.ALT_MASK));
174
175 final JMenuItem deckConstraintsItem = UIHelper.buildMenu(
176 "menu_db_constraints", 'c', this);
177 deckConstraintsItem.setAccelerator(KeyStroke
178 .getKeyStroke(KeyEvent.VK_F3, 0));
179
180 final JMenuItem aboutItem = UIHelper
181 .buildMenu("menu_help_about", 'a', this);
182 aboutItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1,
183 InputEvent.SHIFT_MASK));
184
185 final JMenuItem convertDCK = UIHelper
186 .buildMenu("menu_convert_DCK_MP", this);
187
188 final JMenu mainMenu = UIHelper.buildMenu("menu_file");
189 mainMenu.add(newItem);
190 mainMenu.add(loadItem);
191 mainMenu.add(saveAsItem);
192 mainMenu.add(saveItem);
193 mainMenu.add(new JSeparator());
194 mainMenu.add(quitItem);
195
196 super.optionMenu = new JMenu("Options");
197
198 final JMenu convertMenu = UIHelper.buildMenu("menu_convert");
199 convertMenu.add(convertDCK);
200
201 final JMenuItem helpItem = UIHelper.buildMenu("menu_help_help", 'h', this);
202 helpItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0));
203
204 final JMenu helpMenu = new JMenu("?");
205 helpMenu.add(helpItem);
206 helpMenu.add(deckConstraintsItem);
207 helpMenu.add(aboutItem);
208
209 final JMenuBar menuBar = new JMenuBar();
210 menuBar.add(mainMenu);
211 initAbstractMenu();
212 menuBar.add(optionMenu);
213 menuBar.add(convertMenu);
214 menuBar.add(helpMenu);
215 setJMenuBar(menuBar);
216 addWindowListener(this);
217
218
219 JLabel amountLeft = new JLabel("<html>0/?", SwingConstants.RIGHT);
220
221
222 allListModel = new MListModel<MCardCompare>(amountLeft, false);
223 leftList = new JList(allListModel);
224 leftList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
225 leftList.setLayoutOrientation(JList.VERTICAL);
226 leftList.getSelectionModel().addListSelectionListener(this);
227 leftList.addMouseListener(this);
228 leftList.setVisibleRowCount(10);
229
230
231 qtyTxt = new JTextField("1");
232 qtyTxt.setMaximumSize(new Dimension(20, 32010));
233 qtyTxt.setPreferredSize(new Dimension(20, 16));
234
235
236 addButton = new JButton(LanguageManager.getString("db_add"));
237 addButton.setMnemonic('a');
238
239
240 cardNameTxt = new JTextField();
241 new HireListener(cardNameTxt, addButton, this, leftList);
242
243
244 final JPanel addPanel = new JPanel(null);
245 addPanel.setLayout(new BoxLayout(addPanel, BoxLayout.X_AXIS));
246 addPanel.add(cardNameTxt);
247 addPanel.add(addButton);
248 addPanel.add(qtyTxt);
249 addPanel.setMaximumSize(new Dimension(32010, 26));
250
251 final JScrollPane listScrollerLeft = new JScrollPane(leftList);
252 MToolKit.addOverlay(listScrollerLeft);
253
254
255 final JPanel srcPanel = new JPanel(null);
256 srcPanel.setLayout(new BoxLayout(srcPanel, BoxLayout.Y_AXIS));
257 srcPanel.add(listScrollerLeft);
258 srcPanel.add(amountLeft);
259 srcPanel.add(addPanel);
260 srcPanel.setMinimumSize(new Dimension(200, 0));
261
262
263 DeckReader.readAvailableCards(allListModel);
264
265
266 initSets();
267 datasets = new ChartSets();
268 final int PREFERED_WIDTH = CardView.instance.getPreferredSize().width;
269 final JTabbedPane tabbedPane = new JTabbedPane();
270 tabbedPane.setPreferredSize(new Dimension(PREFERED_WIDTH, 300));
271 tabbedPane.setMinimumSize(tabbedPane.getPreferredSize());
272 tabbedPane.setMaximumSize(new Dimension(PREFERED_WIDTH, 32010));
273 for (ChartFilter filter : ChartFilter.values()) {
274 Dataset dataSet = filter.createDataSet(this);
275 final JFreeChart chart = new JFreeChart(null, null, filter.createPlot(
276 dataSet, painterMapper.get(filter)), false);
277 datasets.addDataSet(filter, dataSet);
278 ChartPanel pieChartPanel = new ChartPanel(chart, true);
279 tabbedPane.add(pieChartPanel, filter.getTitle());
280 }
281
282 cardPictureName = new JLabel("(no selected card)", SwingConstants.LEFT);
283
284
285 toolBar = new JToolBar();
286 final JButton clearButton = UIHelper.buildButton("clear");
287 clearButton.addActionListener(this);
288 toolBar.add(clearButton);
289 final JToggleButton toggleColorlessButton = new JToggleButton(UIHelper
290 .getTbsIcon("mana/colorless/small/" + MdbLoader.unknownSmlMana), true);
291 toggleColorlessButton.setActionCommand("0");
292 toggleColorlessButton.addActionListener(this);
293 toolBar.add(toggleColorlessButton);
294 for (int index = 1; index < IdCardColors.CARD_COLOR_NAMES.length; index++) {
295 final JToggleButton toggleButton = new JToggleButton(
296 UIHelper.getTbsIcon("mana/colored/small/"
297 + MdbLoader.coloredSmlManas[index]), true);
298 toggleButton.setActionCommand(String.valueOf(index));
299 toggleButton.addActionListener(this);
300 toolBar.add(toggleButton);
301 }
302 getContentPane().add(toolBar, BorderLayout.NORTH);
303
304
305 JLabel rightAmount = new JLabel("0/?", SwingConstants.RIGHT);
306
307
308 rightListModel = new MCardTableModel(new MListModel<MCardCompare>(
309 rightAmount, true));
310 rightListModel.addTableModelListener(this);
311 rightList = new JTable(rightListModel);
312 rightList.setShowGrid(false);
313 rightList.setTableHeader(null);
314 rightList.getSelectionModel().addListSelectionListener(this);
315 rightList.getColumnModel().getColumn(1).setMaxWidth(25);
316 rightList.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
317 rightList.setMinimumSize(new Dimension(200, 0));
318
319
320 final JScrollPane listScrollerRight = new JScrollPane(rightList);
321 MToolKit.addOverlay(listScrollerRight);
322 final JPanel destPanel = new JPanel();
323 destPanel.setLayout(new BoxLayout(destPanel, BoxLayout.Y_AXIS));
324 destPanel.add(listScrollerRight);
325 destPanel.add(constraintsCheckerScroll);
326 destPanel.add(rightAmount);
327
328
329 final JPanel viewCard = new JPanel(null);
330 viewCard.add(cardPictureName);
331 viewCard.add(CardView.instance);
332 viewCard.add(tabbedPane);
333 viewCard.setLayout(new BoxLayout(viewCard, BoxLayout.Y_AXIS));
334
335 final JPanel mainPanel = new JPanel(null);
336 mainPanel.add(srcPanel);
337 mainPanel.add(viewCard);
338 mainPanel.add(destPanel);
339 mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.X_AXIS));
340
341
342 getContentPane().add(mainPanel, BorderLayout.CENTER);
343
344
345 if (Configuration.getString("decks.deck(0)", "").length() > 0) {
346 loadDeck(Configuration.getString("decks.deck(0)"), rightListModel
347 .getCards());
348 } else {
349 isNew = true;
350 }
351
352
353 getRootPane().setPreferredSize(new Dimension(650, 700));
354 getRootPane().setMinimumSize(new Dimension(650, 700));
355 pack();
356 }
357
358 /***
359 * @param string
360 * @param deckListModel2
361 * @param qtyListModel2
362 * @param builder
363 */
364 private void loadDeck(String fileName, MListModel<MCardCompare> names) {
365
366 if (fileName == null || fileName.length() == 0) {
367 return;
368 }
369
370
371 setTitle("DeckBuilder".concat(" : "
372 + fileName.substring(fileName.lastIndexOf("/") + 1)));
373
374 names.clear();
375 datasets.removeAll();
376 try {
377 currentDeck = DeckReader.getDeck(this, fileName);
378 if (currentDeck == null) {
379
380 return;
381 }
382
383
384 DeckReader.validateDeck(this, currentDeck, (String) null);
385
386
387 final FileInputStream dbStream = MdbLoader.resetMdb();
388 for (MCardCompare cardCompare : currentDeck.getCards()) {
389 names.add(cardCompare);
390 dbStream.getChannel().position(cardCompare.getMdbOffset());
391 datasets.addCard(CardFactory.getCardModel(cardCompare.getName(),
392 dbStream), cardCompare.getAmount());
393 }
394 constraintsChecker.setDeck(currentDeck);
395 updateChecker();
396 } catch (IOException e) {
397 e.printStackTrace();
398 }
399 }
400
401 private void setCard(MCardCompare card) {
402 CardView.instance.setCard(card);
403 cardPictureName.setText(card.getName());
404 }
405
406 public void valueChanged(ListSelectionEvent e) {
407 if (!e.getValueIsAdjusting()) {
408 if (e.getSource() == leftList.getSelectionModel()) {
409 if (leftList.getSelectedIndex() == -1) {
410
411 addButton.setEnabled(false);
412 } else {
413
414 addButton.setEnabled(true);
415 setCard((MCardCompare) leftList.getSelectedValue());
416 cardNameTxt.setText(cardPictureName.getText());
417 }
418 } else if (e.getSource() == rightList.getSelectionModel()) {
419 setCard(((MCardTableModel) rightList.getModel()).getCards()
420 .getElementAt(rightList.getSelectedRow()));
421 }
422 }
423 }
424
425 /***
426 * Exit the Application
427 */
428 private void exitForm() {
429 if (consoleMode) {
430 System.exit(0);
431 } else {
432 setVisible(false);
433 }
434 }
435
436 /***
437 * Load the deckbuilder from the command line.
438 *
439 * @param args
440 * the command line arguments
441 */
442 public static void main(String[] args) {
443 consoleMode = true;
444 JFrame.setDefaultLookAndFeelDecorated(true);
445 JDialog.setDefaultLookAndFeelDecorated(true);
446 autoLoad();
447 }
448
449 /***
450 * Load the deckbuilder from Magic class.
451 */
452 public static void loadFromMagic() {
453 consoleMode = false;
454 autoLoad();
455 }
456
457 /***
458 * Load the deckbuilder
459 */
460 private static void autoLoad() {
461 if (deckbuilderForm != null) {
462
463 deckbuilderForm.setVisible(true);
464 return;
465 }
466 deckbuilderForm = new DeckBuilder();
467 deckbuilderForm.setLocation(
468 (deckbuilderForm.getToolkit().getScreenSize().width - 650) / 2,
469 (deckbuilderForm.getToolkit().getScreenSize().height - 700) / 2);
470
471 deckbuilderForm.setVisible(true);
472 }
473
474 public void refreshAddComponent(boolean unitary) {
475 String name = leftList.getSelectedValue().toString();
476 int qty = 1;
477 if (!unitary) {
478 try {
479 qty = Integer.parseInt(qtyTxt.getText());
480 } catch (Exception e1) {
481 JOptionPane.showMessageDialog(deckbuilderForm,
482 "Malformed integer for quantity", "Internal Error",
483 JOptionPane.ERROR_MESSAGE);
484 return;
485 }
486 }
487
488 if (name.length() == 0) {
489 cardNameTxt.requestFocusInWindow();
490 return;
491 }
492
493 int index = rightListModel.getCards().indexOf(name);
494 final MCardCompare card;
495 if (index == -1) {
496
497 int allIndex = allListModel.indexOf(name);
498 assert allIndex != -1;
499 card = allListModel.get(allIndex).clone();
500 card.add(qty);
501 currentDeck.addCard(card);
502 rightListModel.getCards().insertElementAt(card, 0);
503 rightListModel.fireTableRowsInserted(rightListModel.getCards().getSize(),
504 rightListModel.getCards().getSize());
505
506
507 cardNameTxt.requestFocusInWindow();
508 cardNameTxt.setText("");
509 } else {
510 card = rightListModel.getCards().elementAt(index);
511 card.add(qty);
512 rightListModel.fireTableCellUpdated(index, 1);
513 }
514
515
516 final FileInputStream dbStream = MdbLoader.resetMdb();
517 datasets.addCard(getCardModel(name, dbStream), qty);
518
519
520 modifiedSinceSave = true;
521 }
522
523 /***
524 * Update the checker and repaint the right list.
525 */
526 private void updateChecker() {
527 constraintsChecker.updateCheckers();
528 rightList.repaint();
529 }
530
531 /***
532 * Return the associated cardModel to the given real card name. The card is
533 * searched in the inputstream starting from a given offset.
534 *
535 * @param realCardName
536 * the card name as written in the mdb stream.
537 * @param dbFile
538 * the fileinput stream of current mdb.
539 * @return the corresponding CardModel instance, or null if the card has not
540 * been matched.
541 */
542 private CardModel getCardModel(String realCardName, FileInputStream dbFile) {
543 try {
544 int index = allListModel.indexOf(realCardName);
545 MCardCompare card = allListModel.get(index);
546 dbFile.getChannel().position(card.getMdbOffset());
547 return CardFactory.getCardModel(realCardName, dbFile);
548 } catch (IOException e) {
549 return null;
550 }
551 }
552
553 /***
554 * check if the current deck has been modified since it has been saved. If the
555 * current deck has been modified, we ask to the user if he want to save it
556 * before loading another.
557 *
558 * @return true if the user has choosen to save the deck before contuning and
559 * if the save has success. False otherwise
560 */
561 private boolean verifyModification() {
562 if (!modifiedSinceSave) {
563
564 return true;
565 }
566
567
568 Object[] options = { "Ok", "No", "Cancel" };
569 switch (JOptionPane.showOptionDialog(deckbuilderForm,
570 "Current deck has been modified, save it before loading another?",
571 "Save changes", JOptionPane.YES_NO_CANCEL_OPTION,
572 JOptionPane.WARNING_MESSAGE, null, options, null)) {
573 case 0:
574
575 return saveCurrentDeck();
576 case 1:
577
578 return true;
579 default:
580
581 return false;
582 }
583 }
584
585 /***
586 * Save the current deck. If the current deck has not been saved once, user
587 * have to specify the file's name of this new deck
588 *
589 * @return true if the current deck has been correctly saved. false otherwise.
590 */
591 private boolean saveCurrentDeck() {
592 if (isNew || Configuration.getString("decks.deck(0)", "").length() == 0) {
593 if (MToolKit.getDeckFile(this, JFileChooser.SAVE_DIALOG) == null)
594 return false;
595 }
596 return MSaveDeck.saveDeck(Configuration.getString("decks.deck(0)"),
597 rightListModel.getCards(), deckbuilderForm);
598 }
599
600 /***
601 * load the settings of jDecBuilder First byte is the Version Then :
602 *
603 * @since 0.2 the mdb file
604 * @since 0.2 the last deck file used
605 * @since 0.7 the settings are read from .properties file
606 */
607 private void loadSettings() {
608
609 if (consoleMode || MToolKit.tbsName == null) {
610
611
612
613
614 LanguageManager.initLanguageManager(Configuration.getString("language",
615 "auto"));
616 optionMenu = new JMenu(LanguageManager.getString("options"));
617 optionMenu.setMnemonic('o');
618 initAbstractMenu();
619 final String tbsName = Configuration.getString("lastTBS");
620 if (tbsName != null && tbsName.length() != 0) {
621 setMdb(tbsName);
622 }
623 }
624
625 }
626
627 /***
628 * Invoked when an action occurs.
629 *
630 * @param e
631 * attached event
632 */
633 public void actionPerformed(ActionEvent e) {
634 String command = e.getActionCommand();
635 if ("menu_help_about".equals(command)) {
636 new About(deckbuilderForm).setVisible(true);
637 } else if ("menu_db_exit".equals(command)) {
638 exitForm();
639 } else if ("menu_db_new".equals(command)) {
640 if (!verifyModification()) {
641 return;
642 }
643 setTitle("DeckBuilder");
644 rightListModel.getCards().clear();
645 datasets.removeAll();
646 modifiedSinceSave = false;
647 currentDeck.getCards().clear();
648 updateChecker();
649 isNew = true;
650 } else if ("menu_convert_DCK_MP".equals(command)) {
651
652
653
654 try {
655 Converter.convertDCK(MToolKit.showDialogFile(
656 "Choose a directory of DCK to convert", null, null, 'o', null,
657 FILTER_DECK, this, JFileChooser.OPEN_DIALOG,
658 JFileChooser.DIRECTORIES_ONLY).getCanonicalPath());
659 } catch (IOException e1) {
660 JOptionPane.showMessageDialog(this,
661 "Error occured reading the specified directory", "File problem",
662 JOptionPane.ERROR_MESSAGE);
663 } catch (Exception e1) {
664
665 }
666 } else if ("menu_db_constraints".equals(command)) {
667
668 new DeckRules(this).setVisible(true);
669 } else if ("menu_help_help".equals(command)) {
670
671
672
673
674 JOptionPane.showMessageDialog(deckbuilderForm,
675 "Sorry, no documentation available for deck builder",
676 "Negative yet implemented", JOptionPane.INFORMATION_MESSAGE);
677 } else if ("menu_db_load".equals(command)) {
678 if (verifyModification()) {
679 String deckFile = MToolKit.getDeckFile(this, JFileChooser.OPEN_DIALOG);
680 if (deckFile != null) {
681 loadDeck(deckFile, rightListModel.getCards());
682 modifiedSinceSave = false;
683 isNew = false;
684 }
685 }
686 } else if ("menu_db_saveas".equals(command)) {
687 String deckFile = MToolKit.getDeckFile(this, JFileChooser.SAVE_DIALOG);
688 if (deckFile != null) {
689 MSaveDeck
690 .saveDeck(deckFile, rightListModel.getCards(), deckbuilderForm);
691 isNew = false;
692 modifiedSinceSave = false;
693 }
694 } else if ("menu_db_save".equals(command)) {
695 saveCurrentDeck();
696 isNew = false;
697 modifiedSinceSave = false;
698 } else {
699 final MListModel<MCardCompare> model = ((MListModel<MCardCompare>) leftList
700 .getModel());
701 if ("clear".equals(command)) {
702
703 for (Component component : toolBar.getComponents()) {
704 if (component instanceof JToggleButton) {
705 ((JToggleButton) component).setSelected(true);
706 }
707 }
708 model.addAll(model.removedDelegate);
709 } else {
710
711 final int colorIndex = Integer.valueOf(command);
712 if (colorIndex >= 0) {
713
714 final FileInputStream dbStream = MdbLoader.resetMdb();
715 final JToggleButton colorButton = (JToggleButton) toolBar
716 .getComponent(colorIndex + 1);
717 if (colorButton.isSelected()) {
718
719 final List<MCardCompare> toAdd = new ArrayList<MCardCompare>();
720 for (MCardCompare cardCompare : model.removedDelegate) {
721 try {
722 dbStream.getChannel().position(cardCompare.getMdbOffset());
723 final CardModel cardModel = CardFactory.getCardModel(
724 cardCompare.getName(), dbStream);
725 if (colorIndex == 0) {
726 if (cardModel.getIdColor() == 0) {
727 toAdd.add(cardCompare);
728 }
729 } else if ((cardModel.getIdColor() & IdCardColors.CARD_COLOR_VALUES[colorIndex]) == IdCardColors.CARD_COLOR_VALUES[colorIndex]) {
730 toAdd.add(cardCompare);
731 }
732 } catch (IOException e1) {
733 e1.printStackTrace();
734 }
735 }
736 model.addAll(toAdd);
737 } else {
738
739 final List<MCardCompare> toRemove = new ArrayList<MCardCompare>();
740 for (MCardCompare cardCompare : model.delegate) {
741 try {
742 dbStream.getChannel().position(cardCompare.getMdbOffset());
743 final CardModel cardModel = CardFactory.getCardModel(
744 cardCompare.getName(), dbStream);
745 if (colorIndex == 0) {
746 if (cardModel.getIdColor() == 0) {
747 toRemove.add(cardCompare);
748 }
749 } else if ((cardModel.getIdColor() & IdCardColors.CARD_COLOR_VALUES[colorIndex]) == IdCardColors.CARD_COLOR_VALUES[colorIndex]) {
750 toRemove.add(cardCompare);
751 }
752 } catch (IOException e1) {
753 e1.printStackTrace();
754 }
755 }
756 model.removeAll(toRemove);
757 }
758 }
759 leftList.repaint();
760 }
761 }
762 }
763
764 @Override
765 protected void setToolKitMdb(String tbsName) {
766 super.setToolKitMdb(tbsName);
767 DeckReader.readAvailableCards(allListModel);
768 }
769
770 public void mouseClicked(MouseEvent e) {
771 if (e.getSource() == leftList && e.getClickCount() == 2) {
772 refreshAddComponent(true);
773 } else if (e.getSource() == cardNameTxt) {
774 cardNameTxt.selectAll();
775 }
776 }
777
778 private static final FileFilterPlus FILTER_DECK = new FileFilterPlus("dck",
779 "DCK : Shandalar deck file");
780
781 private final MListModel<MCardCompare> allListModel;
782
783 private final MCardTableModel rightListModel;
784
785 private static boolean modifiedSinceSave = false;
786
787 private static DeckBuilder deckbuilderForm = null;
788
789 private final JButton addButton;
790
791 /***
792 * The right list : cards in the deck.
793 */
794 private final JTable rightList;
795
796 /***
797 * The left list : available cards.
798 */
799 private final JList leftList;
800
801 private final JTextField qtyTxt;
802
803 private final JTextField cardNameTxt;
804
805 /***
806 * The label displayed above the card picture
807 */
808 private final JLabel cardPictureName;
809
810 /***
811 * indicates if jdeckbuilder was launched from console
812 */
813 public static boolean consoleMode = false;
814
815 @Override
816 public void windowClosing(WindowEvent e) {
817 exitForm();
818 }
819
820 /***
821 * Are we working with a new deck?
822 */
823 private boolean isNew = false;
824
825 private final ChartSets datasets;
826
827 private Map<ChartFilter, Map<Integer, IChartKey>> keyMapper;
828
829 private Map<ChartFilter, Map<Integer, Paint>> painterMapper;
830
831 private void initSets() {
832 final Map<Integer, Paint> painterColorMapper = new TreeMap<Integer, Paint>();
833 for (int index = IdCardColors.CARD_COLOR_VALUES.length; index-- > 0;) {
834 painterColorMapper.put(IdCardColors.CARD_COLOR_VALUES[index],
835 IdCardColors.CARD_COLOR[index]);
836 }
837 painterColorMapper.put(ChartFilter.DEFAULT_KEY, Color.YELLOW.darker()
838 .darker());
839 painterMapper = new HashMap<ChartFilter, Map<Integer, Paint>>();
840 painterMapper.put(ChartFilter.color, painterColorMapper);
841
842 final Map<Integer, IChartKey> keyColorMapper = new TreeMap<Integer, IChartKey>();
843 for (int index = 0; index < IdCardColors.CARD_COLOR_VALUES.length; index++) {
844 keyColorMapper.put(IdCardColors.CARD_COLOR_VALUES[index], new CardColor(
845 LanguageManager.getString(IdCardColors.CARD_COLOR_NAMES[index]),
846 IdCardColors.CARD_COLOR_VALUES[index]));
847 }
848 keyColorMapper.put(ChartFilter.DEFAULT_KEY, CardColor.UNKNOW_COLOR);
849
850 final Map<Integer, IChartKey> keyTypeMapper = new TreeMap<Integer, IChartKey>();
851 for (int index = 0; index < CardFactory.exportedTypeNames.length; index++) {
852 keyTypeMapper.put(CardFactory.exportedTypeValues[index], new CardTypes(
853 LanguageManagerMDB.getString(CardFactory.exportedTypeNames[index]),
854 CardFactory.exportedTypeValues[index]));
855 }
856 keyTypeMapper.put(ChartFilter.DEFAULT_KEY, CardTypes.UNKNOW_TYPE);
857
858 keyMapper = new HashMap<ChartFilter, Map<Integer, IChartKey>>();
859 keyMapper.put(ChartFilter.color, keyColorMapper);
860 keyMapper.put(ChartFilter.type, keyTypeMapper);
861 keyMapper.put(ChartFilter.property, new TreeMap<Integer, IChartKey>());
862 keyMapper.put(ChartFilter.manacost, new TreeMap<Integer, IChartKey>());
863 }
864
865 private Map<Integer, IChartKey> getMapper(ChartFilter filter) {
866 return keyMapper.get(filter);
867 }
868
869 public List<IChartKey> getKeys(ChartFilter filter) {
870 List<IChartKey> list = new ArrayList<IChartKey>(getMapper(filter).values());
871 Collections.sort(list);
872 return list;
873 }
874
875 public Collection<IChartKey> getKeys(CardModel cardModel, ChartFilter filter) {
876 Collection<IChartKey> result = new ArrayList<IChartKey>();
877 switch (filter) {
878 case color:
879 int idColor = cardModel.getIdColor();
880 if (idColor == 0)
881 result.add(getMapper(filter).get(IdCardColors.CARD_COLOR_VALUES[0]));
882 else {
883 for (IChartKey value : getMapper(filter).values()) {
884 if (value.getIntegerKey() != 0
885 && MCard.hasIdColor(idColor, value.getIntegerKey())) {
886 result.add(value);
887 }
888 }
889 }
890 break;
891 case type:
892 int idCard = cardModel.getIdCard();
893 for (IChartKey value : getMapper(filter).values()) {
894 if (MCard.hasIdCard(idCard, value.getIntegerKey()))
895 result.add(value);
896 }
897 break;
898 case manacost:
899 int total = 0;
900 for (int index = IdCommonToken.WHITE_MANA + 1; index-- > 0;) {
901 total += cardModel.getStaticRegisters()[index];
902 }
903 result.add(new CardManaCost(total));
904 break;
905 default:
906
907 }
908 if (result.isEmpty()) {
909 IChartKey defaultKey = getMapper(filter).get(ChartFilter.DEFAULT_KEY);
910 if (defaultKey != null)
911 result.add(getMapper(filter).get(ChartFilter.DEFAULT_KEY));
912 }
913 return result;
914 }
915
916 public void tableChanged(TableModelEvent e) {
917 try {
918 MCardCompare card = rightListModel.getCards().get(e.getFirstRow());
919 if (card.getAmount() == 0) {
920 currentDeck.removeCard(card);
921 }
922 } catch (Throwable t) {
923
924 }
925 updateChecker();
926 }
927
928 /***
929 * The toolbar containg some filters.
930 */
931 private final JToolBar toolBar;
932
933 private Deck currentDeck;
934
935 private final ConstraintsChecker constraintsChecker;
936
937 }