aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/eu/equalparts/cardbase/data/CardSet.java27
-rw-r--r--src/eu/equalparts/cardbase/data/CardbaseManager.java68
-rw-r--r--src/eu/equalparts/cardbase/data/Deck.java3
-rw-r--r--src/eu/equalparts/cardbase/data/FullCardSet.java46
-rw-r--r--src/eu/equalparts/cardbase/io/IO.java (renamed from src/eu/equalparts/cardbase/query/IO.java)12
-rw-r--r--src/eu/equalparts/cardbase/standalone/CardbaseCLI.java540
6 files changed, 423 insertions, 273 deletions
diff --git a/src/eu/equalparts/cardbase/data/CardSet.java b/src/eu/equalparts/cardbase/data/CardSet.java
index 959e0a3..b9720bf 100644
--- a/src/eu/equalparts/cardbase/data/CardSet.java
+++ b/src/eu/equalparts/cardbase/data/CardSet.java
@@ -2,10 +2,31 @@ package eu.equalparts.cardbase.data;
public class CardSet {
- public String name = "";
- public String code = "";
- public String releaseDate = "";
+ private String name = "";
+ private String code = "";
+ private String releaseDate = "";
+ /**
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @return the code
+ */
+ public String getCode() {
+ return code;
+ }
+
+ /**
+ * @return the releaseDate
+ */
+ public String getReleaseDate() {
+ return releaseDate;
+ }
+
@Override
public String toString() {
return String.format("%1$-12s : %2$s", code, name, releaseDate);
diff --git a/src/eu/equalparts/cardbase/data/CardbaseManager.java b/src/eu/equalparts/cardbase/data/CardbaseManager.java
index e6a4f97..dfef3c8 100644
--- a/src/eu/equalparts/cardbase/data/CardbaseManager.java
+++ b/src/eu/equalparts/cardbase/data/CardbaseManager.java
@@ -2,19 +2,30 @@ package eu.equalparts.cardbase.data;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.Iterator;
+import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
-import eu.equalparts.cardbase.query.IO;
+import eu.equalparts.cardbase.io.IO;
public class CardbaseManager {
-
+
private ArrayList<CardSet> cardSets;
- public Cardbase cardbase;
/**
+ * A cache of CardSets to avoid querying the server many times for the same information.
+ */
+ private HashMap<String, FullCardSet> cardSetCache = new HashMap<String, FullCardSet>();
+ /**
+ *
+ */
+ private Cardbase cardbase;
+
+
+ /**
* Parse a cardbase file and create an associated Cardbase object.
*
* @param cardbaseFile
@@ -39,12 +50,46 @@ public class CardbaseManager {
cardSets = IO.getCardSetList();
cardbase = new Cardbase();
}
-
+
public ArrayList<CardSet> getCardSetList() {
return cardSets;
}
+
+ public void writeCardbase(File outputFile) throws JsonGenerationException, JsonMappingException, IOException {
+ IO.writeCardbase(outputFile, cardbase);
+ }
/**
+ * Returns the specified set in the form of a {@code FullCardSet} object.
+ *
+ * @param code the code of the set to be returned.
+ * @return the requested {@code FullCardSet} or null if no set matches the given code.
+ *
+ * @throws JsonParseException if the upstream JSON is not formatted correctly.
+ * @throws JsonMappingException if the upstream JSON does not map to {@code FullCardSet}.
+ * @throws IOException if a low-level I/O problem (unexpected end-of-input, network error) occurs.
+ */
+ public FullCardSet getFullCardSet(String code) throws JsonParseException, JsonMappingException, IOException {
+ FullCardSet requestedSet = null;
+ for (CardSet cardSet : cardSets) {
+ if (cardSet.getCode().equalsIgnoreCase(code)) {
+ // if the set is cached, no need to fetch
+ if (cardSetCache.containsKey(cardSet.getCode())) {
+ requestedSet = cardSetCache.get(cardSet.getCode());
+ }
+ // not cached; fetch, cache and return it
+ else {
+ requestedSet = IO.getFullCardSet(cardSet.getCode());
+ cardSetCache.put(cardSet.getCode(), requestedSet);
+ }
+ return requestedSet;
+ }
+ }
+ // not found
+ return null;
+ }
+
+ /**
* Add a specific amount of a card to the cardbase.
* If the card is not already in the cardbase, it is added.
* If it is already present, the count is simply updated.
@@ -70,20 +115,25 @@ public class CardbaseManager {
* If that amount is equal to or exceeds the count already in the cardbase,
* the card entry is removed altogether.
*
- * @param remove
+ * @param cardToRemove
* @param count
+ * @return the number of cards actually removed.
*/
- public void removeCard(Card remove, Integer count) {
- Card card = cardbase.getCardByNumber(remove.setCode, remove.number);
+ public Integer removeCard(Card cardToRemove, Integer count) {
+ Card card = cardbase.getCardByNumber(cardToRemove.setCode, cardToRemove.number);
+ Integer removed = 0;
if (card != null) {
if (card.count <= count) {
cardbase.cards.remove(card);
+ removed = card.count;
} else {
card.count -= count;
+ removed = count;
}
- }
+ }
+ return removed;
}
-
+
/**
* @return an iterator to the cards in the cardbase.
*/
diff --git a/src/eu/equalparts/cardbase/data/Deck.java b/src/eu/equalparts/cardbase/data/Deck.java
index b5fe402..8a9ed12 100644
--- a/src/eu/equalparts/cardbase/data/Deck.java
+++ b/src/eu/equalparts/cardbase/data/Deck.java
@@ -9,7 +9,4 @@ public class Deck {
*/
public HashMap<Integer, Integer> cards;
- public Deck() {
-
- }
}
diff --git a/src/eu/equalparts/cardbase/data/FullCardSet.java b/src/eu/equalparts/cardbase/data/FullCardSet.java
index 0b5c099..48488b5 100644
--- a/src/eu/equalparts/cardbase/data/FullCardSet.java
+++ b/src/eu/equalparts/cardbase/data/FullCardSet.java
@@ -3,11 +3,47 @@ package eu.equalparts.cardbase.data;
import java.util.ArrayList;
public class FullCardSet extends CardSet {
- public String border;
- public String type;
- public String block;
- public String gathererCode;
- public ArrayList<Card> cards;
+
+ private String border;
+ private String type;
+ private String block;
+ private String gathererCode;
+ private ArrayList<Card> cards;
+
+ /**
+ * @return the border
+ */
+ public String getBorder() {
+ return border;
+ }
+
+ /**
+ * @return the type
+ */
+ public String getType() {
+ return type;
+ }
+
+ /**
+ * @return the block
+ */
+ public String getBlock() {
+ return block;
+ }
+
+ /**
+ * @return the gathererCode
+ */
+ public String getGathererCode() {
+ return gathererCode;
+ }
+
+ /**
+ * @return the cards
+ */
+ public ArrayList<Card> getCards() {
+ return cards;
+ }
/**
* Searches for a card by number (the one shown on the card itself).
diff --git a/src/eu/equalparts/cardbase/query/IO.java b/src/eu/equalparts/cardbase/io/IO.java
index 6fe9390..2275913 100644
--- a/src/eu/equalparts/cardbase/query/IO.java
+++ b/src/eu/equalparts/cardbase/io/IO.java
@@ -1,4 +1,4 @@
-package eu.equalparts.cardbase.query;
+package eu.equalparts.cardbase.io;
import java.io.File;
import java.io.IOException;
@@ -12,6 +12,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
+import eu.equalparts.cardbase.data.Card;
import eu.equalparts.cardbase.data.FullCardSet;
import eu.equalparts.cardbase.data.Cardbase;
import eu.equalparts.cardbase.data.CardSet;
@@ -67,8 +68,13 @@ public class IO {
* @throws JsonMappingException if the input JSON structure does not match structure expected for result type (or has other mismatch issues).
* @throws IOException if a low-level I/O problem (unexpected end-of-input, network error) occurs.
*/
- public static FullCardSet getCardSet(String setCode) throws JsonParseException, JsonMappingException, IOException {
- return mapper.readValue(new URL(BASE_URL + setCode + ".json"), FullCardSet.class);
+ public static FullCardSet getFullCardSet(String setCode) throws JsonParseException, JsonMappingException, IOException {
+ FullCardSet fullCardSet = mapper.readValue(new URL(BASE_URL + setCode + ".json"), FullCardSet.class);
+ // MTG JSON does not include set code in the card information, but it is useful for sorting
+ for (Card card : fullCardSet.getCards()) {
+ card.setCode = setCode;
+ }
+ return fullCardSet;
}
/**
diff --git a/src/eu/equalparts/cardbase/standalone/CardbaseCLI.java b/src/eu/equalparts/cardbase/standalone/CardbaseCLI.java
index 4071fad..e0f5433 100644
--- a/src/eu/equalparts/cardbase/standalone/CardbaseCLI.java
+++ b/src/eu/equalparts/cardbase/standalone/CardbaseCLI.java
@@ -5,7 +5,7 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.util.HashMap;
+import java.util.Arrays;
import java.util.Iterator;
import java.util.Scanner;
@@ -17,7 +17,6 @@ import eu.equalparts.cardbase.data.Card;
import eu.equalparts.cardbase.data.CardbaseManager;
import eu.equalparts.cardbase.data.FullCardSet;
import eu.equalparts.cardbase.data.CardSet;
-import eu.equalparts.cardbase.query.IO;
/**
* This provides a lightweight CLI for interacting with cardbase files.
@@ -32,11 +31,11 @@ public class CardbaseCLI {
* @author Eduardo Pedroni
*/
private enum Action {
-
+
ADD, REMOVE;
public Card card;
public Integer count;
-
+
/**
* Sets both fields at once.
*
@@ -48,7 +47,7 @@ public class CardbaseCLI {
this.count = count;
}
}
-
+
/**
* The last action performed by the user.
*/
@@ -58,21 +57,13 @@ public class CardbaseCLI {
*/
private FullCardSet selectedSet = null;
/**
- * A cache of CardSets to avoid querying the server many times for the same information.
- */
- private HashMap<String, FullCardSet> setCache = new HashMap<String, FullCardSet>();
- /**
- * The manager object which provides a façade to the cardbase data structure.
- */
- private CardbaseManager cbm;
- /**
- * Exit flag, program breaks out of the main loop when true.
+ * The manager object which allows interaction with cardbase data structure.
*/
- private boolean exit = false;
+ private CardbaseManager cardbaseManager;
/**
* Printed to the console when the user enter the help command.
*/
- private String help = "Not available, check project page.";
+ private String help = "Not available, check project page on GitHub.";
/**
* The cardbase file off which we are currently working, if any.
*/
@@ -82,6 +73,10 @@ public class CardbaseCLI {
* if the user tries to exit with unsaved changed.
*/
private boolean savePrompt = false;
+ /**
+ * Exit flag, program breaks out of the main loop when true.
+ */
+ private boolean exit = false;
/**
* Execute the interface.
@@ -90,7 +85,7 @@ public class CardbaseCLI {
*/
public static void main(String... args) {
try {
- new CardbaseCLI(args).run();
+ new CardbaseCLI(args).startInterface();
} catch (JsonParseException e) {
System.out.println("Error: poorly formatted cardbase, check the syntax and try again.");
// although the problem could also be with the upstream CardSetList json.
@@ -103,23 +98,33 @@ public class CardbaseCLI {
e.printStackTrace();
}
}
-
+
+ /**
+ * Reads in an optional cardbase JSON and initialises other necessary components.
+ * This does not actually produce the CLI, for that use {@code startInterface()}
+ * on the constructed object.
+ *
+ * @param args a list of arguments. Only the first argument is used, as a cardbase JSON.
+ * @throws JsonParseException the file specified does not comply to JSON standards.
+ * @throws JsonMappingException the file specified cannot be mapped to a {@code Cardbase} object.
+ * @throws IOException something went wrong with the low-level I/O.
+ */
private CardbaseCLI(String... args) throws JsonParseException, JsonMappingException, IOException {
System.out.println("Welcome to Cardbase CLI!");
// make the CardbaseManager
if (args.length > 0) {
- cardbaseFile = new File(args[0]);
+ File cardbaseFile = new File(args[0]);
if (cardbaseFile.exists() && cardbaseFile.isFile() && cardbaseFile.canRead()) {
System.out.println("Loading cardbase from \"" + args[0] + "\".");
- cbm = new CardbaseManager(cardbaseFile);
+ cardbaseManager = new CardbaseManager(cardbaseFile);
} else {
System.out.println(args[0] + " appears to be invalid.");
System.exit(0);
}
} else {
System.out.println("No cardbase file was provided, creating a clean cardbase.");
- cbm = new CardbaseManager();
+ cardbaseManager = new CardbaseManager();
}
// load help information
@@ -127,18 +132,49 @@ public class CardbaseCLI {
if (is != null) {
help = new Scanner(is).useDelimiter("\\Z").next();
} else {
- System.out.println("Help file was not found, check the project page for help instead.");
+ System.out.println("Help file was not found, check the project page on GitHub for help instead.");
}
}
- private void run() {
+ /**
+ * Read stdin for user input, sanitise and interpret any commands entered.
+ */
+ private void startInterface() {
BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));
- // the main loop
try {
+ // the main loop
while (!exit) {
- System.out.print(selectedSet == null ? "> " : selectedSet.code + " > ");
- interpret(consoleReader.readLine().trim().toLowerCase().split("[ \t]+"));
+ // print prompt
+ System.out.print(selectedSet == null ? "> " : selectedSet.getCode() + " > ");
+ // condition input and interpret
+ String[] raw = consoleReader.readLine().trim().toLowerCase().split("[ \t]+");
+ String command = raw[0];
+ String[] args = Arrays.copyOfRange(raw, 1, raw.length);
+
+ if (command.equalsIgnoreCase("help")) {
+ help();
+ } else if (command.equalsIgnoreCase("write")
+ || command.equalsIgnoreCase("save")) {
+ write(args);
+ } else if (command.equalsIgnoreCase("exit")) {
+ exit();
+ } else if (command.equalsIgnoreCase("sets")) {
+ sets();
+ } else if (command.equalsIgnoreCase("set")) {
+ set(args);
+ } else if (command.equalsIgnoreCase("glance")) {
+ glance();
+ } else if (command.equalsIgnoreCase("peruse")) {
+ peruse(args);
+ } else if (command.equalsIgnoreCase("undo")) {
+ undo();
+ } else if (command.equalsIgnoreCase("remove")
+ || command.equalsIgnoreCase("rm")) {
+ remove(args);
+ } else {
+ add(command, args);
+ }
}
} catch (IOException e) {
System.out.println("Error: something went wrong with stdin, exiting...");
@@ -147,232 +183,233 @@ public class CardbaseCLI {
}
/**
- * Handle console commands appropriately.
- *
- * @param commands an array of {@code String} containing the arguments in order.
+ * Print help to console.
*/
- private void interpret(String[] commands) {
- if (commands.length > 0) {
- switch (commands[0]) {
- /*
- * Show help.
- */
- case "help":
- System.out.println(help);
- break;
-
- /*
- * Write current cardbase to file.
- */
- case "write":
- File outputFile;
- if (commands.length > 1) {
- outputFile = new File(sanitiseFileName(commands[1]));
- } else {
- outputFile = cardbaseFile;
- }
-
- if (outputFile != null) {
- if (outputFile.exists() && (!outputFile.isFile() || !outputFile.canWrite())) {
- System.out.println("Could not write to \"" + outputFile.getAbsolutePath() + "\".");
- return;
- }
- // handle these exceptions locally - they don't necessarily mean the program should halt.
- try {
- IO.writeCardbase(outputFile, cbm.cardbase);
- // we are now working off outputFile, which may or may not be the same as cardbaseFile at this point
- cardbaseFile = outputFile;
- System.out.println("Cardbase was saved to \"" + outputFile.getAbsolutePath() + "\". "
- + "Subsequent writes will be done to this same file unless otherwise requested.");
- savePrompt = false;
- } catch (JsonGenerationException | JsonMappingException e) {
- System.out.println("Error: something terrible happened to the internal cardbase data structure. Oops.");
- e.printStackTrace();
- } catch (IOException e) {
- System.out.println("Error: lost contact with the output file, try again?");
- e.printStackTrace();
- }
- } else {
- System.out.println("Please provide a file name.");
- }
- break;
-
- /*
- * Exit procedure.
- */
- case "exit":
- if (savePrompt) {
- System.out.println("Don't forget to save. If you really wish to quit without saving, type \"exit\" again.");
+ public void help() {
+ System.out.println(help);
+ }
+
+ /**
+ * Write current cardbase to file.
+ *
+ * @param args optionally the file to which to write.
+ */
+ public void write(String[] args) {
+ File outputFile;
+ // user-provided file overrides everything else
+ if (args.length > 0) {
+ outputFile = new File(sanitiseFileName(args[0]));
+ } else {
+ outputFile = cardbaseFile;
+ }
+
+ if (outputFile != null) {
+ if (outputFile.exists() && (!outputFile.isFile() || !outputFile.canWrite())) {
+ System.out.println("Could not write to \"" + outputFile.getAbsolutePath() + "\".");
+ } else {
+ // handle these exceptions locally - they don't necessarily mean the program should exit
+ try {
+ cardbaseManager.writeCardbase(outputFile);
+ // we are now working off outputFile, which may or may not be the same as cardbaseFile at this point
+ cardbaseFile = outputFile;
+ System.out.println("Cardbase was saved to \"" + outputFile.getAbsolutePath() + "\". "
+ + "Subsequent writes will be done to this same file unless otherwise requested.");
savePrompt = false;
- } else {
- exit = true;
- }
- break;
-
- /*
- * Print a list of valid set codes.
- */
- case "sets":
- for (CardSet set : cbm.getCardSetList()) {
- // MetaCardSet has an overridden toString().
- System.out.println(set);
- }
- break;
-
- /*
- * Select a set.
- */
- case "set":
- // first check if the set code is valid
- for (CardSet set : cbm.getCardSetList()) {
- if (set.code.equalsIgnoreCase(commands[1])) {
- // if the set is already cached, use that
- if (setCache.containsKey(set.code)) {
- selectedSet = setCache.get(set.code);
- } else {
- // if not, download it and cache it
- try {
- selectedSet = IO.getCardSet(set.code);
- setCache.put(set.code, selectedSet);
- } catch (JsonParseException e) {
- System.out.println("Error: JSON fetched from upstream was not formatted properly.");
- e.printStackTrace();
- return;
- } catch (JsonMappingException e) {
- System.out.println("Error: JSON fetched from upstream does not match the data structure used internally.");
- e.printStackTrace();
- return;
- } catch (IOException e) {
- System.out.println("Error: JSON could not be fetched from upstream.");
- e.printStackTrace();
- return;
- }
- }
- System.out.println("Selected set: " + set.name + ".");
- // undoing is not allowed if the set is changed - it would get tricky
- lastAction = null;
- return;
- }
- }
- System.out.println("\"" + commands[1] + "\" does not correspond to any set (use \"sets\" to see all valid set codes).");
- break;
-
- /*
- * Print a brief list of the whole cardbase.
- */
- case "glance":
- Card current;
- int total = 0;
- for (Iterator<Card> i = cbm.cardIterator(); i.hasNext();) {
- current = i.next();
- printGlance(current);
- total += current.count;
+ } catch (JsonGenerationException | JsonMappingException e) {
+ System.out.println("Error: something terrible happened to the internal cardbase data structure. Oops.");
+ e.printStackTrace();
+ } catch (IOException e) {
+ System.out.println("Error: lost contact with the output file, try again?");
+ e.printStackTrace();
}
- System.out.println("Total: " + total);
- break;
-
- /*
- * Print detailed information of a single card or the whole cardbase.
- */
- case "peruse":
- // if a card is specified, peruse only that
- if (commands.length > 1) {
- if (selectedSet != null) {
- Card card = cbm.getCard(selectedSet.code, commands[1]);
- if (card != null) {
- printPerusal(card);
- } else {
- System.out.println("Card not in cardbase.");
- }
- } else {
- System.out.println("Please select a set before perusing a specific card.");
- }
+ }
+ } else {
+ System.out.println("Please provide a file name.");
+ }
+ }
+
+ /**
+ * Exit procedure.
+ */
+ public void exit() {
+ if (savePrompt) {
+ System.out.println("Don't forget to save. If you really wish to quit without saving, type \"exit\" again.");
+ savePrompt = false;
+ } else {
+ exit = true;
+ }
+ }
+
+ /**
+ * Print a list of valid set codes.
+ */
+ public void sets() {
+ for (CardSet set : cardbaseManager.getCardSetList()) {
+ // CardSet has an overridden toString().
+ System.out.println(set);
+ }
+ }
+
+ /**
+ * Select a set.
+ *
+ * @param args the code of the chosen set.
+ */
+ public void set(String[] args) {
+ if (args.length > 0) {
+ try {
+ selectedSet = cardbaseManager.getFullCardSet(args[0]);
+ // if the set code is invalid, null is returned
+ if (selectedSet != null) {
+ System.out.println("Selected set: " + selectedSet.getName() + ".");
+ // undoing is not allowed if the set is changed - it would get tricky
+ lastAction = null;
} else {
- // peruse all cards in cardbase
- for (Iterator<Card> i = cbm.cardIterator(); i.hasNext();) {
- printPerusal(i.next());
- }
+ System.out.println("\"" + args[0] + "\" does not correspond to any set (use \"sets\" to see all valid set codes).");
}
- break;
-
- /*
- * Undo previous action.
- */
- case "undo":
- if (lastAction != null) {
- if (lastAction == Action.ADD) {
- remove(lastAction.card, lastAction.count);
- } else if (lastAction == Action.REMOVE) {
- add(lastAction.card, lastAction.count);
- }
- // can only undo once
- lastAction = null;
+ } catch (JsonParseException e) {
+ System.out.println("Error: JSON fetched from upstream was not formatted properly.");
+ e.printStackTrace();
+ return;
+ } catch (JsonMappingException e) {
+ System.out.println("Error: JSON fetched from upstream does not match the data structure used internally.");
+ e.printStackTrace();
+ return;
+ } catch (IOException e) {
+ System.out.println("Error: JSON could not be fetched from upstream.");
+ e.printStackTrace();
+ return;
+ }
+ } else {
+ System.out.println("Please enter a set code (use \"sets\" to see all valid set codes).");
+ }
+ }
+
+ /**
+ * Print a brief list of the whole cardbase.
+ */
+ public void glance() {
+ Card current;
+ int total = 0;
+ for (Iterator<Card> i = cardbaseManager.cardIterator(); i.hasNext();) {
+ current = i.next();
+ printGlance(current);
+ total += current.count;
+ }
+ System.out.println("Total: " + total);
+ }
+
+ /**
+ * Print detailed information of a single card or the whole cardbase.
+ *
+ * @param args optionally a card within the set (by number) to peruse.
+ */
+ public void peruse(String[] args) {
+ // if a card is specified, peruse only that
+ if (args.length > 0) {
+ if (selectedSet != null) {
+ Card card = cardbaseManager.getCard(selectedSet.getCode(), args[0]);
+ if (card != null) {
+ printPerusal(card);
} else {
- System.out.println("Nothing to undo.");
+ System.out.println("Card not in cardbase.");
}
- break;
-
- /*
- * Remove one or more of a card.
- */
- case "remove":
- if (selectedSet != null) {
- if (commands.length > 1) {
- Card cardToRemove = selectedSet.getCardByNumber(commands[1]);
- if (cardToRemove != null) {
- Integer count = 1;
- if (commands.length > 2 && commands[2].matches("[0-9]+")) {
- count = Integer.valueOf(commands[2]);
- if (count <= 0) {
- System.out.println("Can't remove " + count + " cards.");
- return;
- }
- }
- remove(cardToRemove, count);
- } else {
- System.out.println(commands[1] + " does not correspond to a card in " + selectedSet.name + ".");
+ } else {
+ System.out.println("Please select a set before perusing a specific card.");
+ }
+ } else {
+ // peruse all cards in cardbase
+ Card current;
+ int total = 0;
+ for (Iterator<Card> i = cardbaseManager.cardIterator(); i.hasNext();) {
+ current = i.next();
+ printPerusal(current);
+ total += current.count;
+ }
+ System.out.println("Total: " + total);
+ }
+ }
+
+ /**
+ * Undo previous action.
+ */
+ public void undo() {
+ if (lastAction != null) {
+ if (lastAction == Action.ADD) {
+ removeCard(lastAction.card, lastAction.count);
+ } else if (lastAction == Action.REMOVE) {
+ addCard(lastAction.card, lastAction.count);
+ }
+ // can only undo once
+ lastAction = null;
+ } else {
+ System.out.println("Nothing to undo.");
+ }
+ }
+
+ /**
+ * Remove one or more of a card.
+ *
+ * @param args the set number of the card to remove and optionally the count to be removed.
+ */
+ public void remove(String[] args) {
+ if (selectedSet != null) {
+ if (args.length > 0) {
+ Card cardToRemove = selectedSet.getCardByNumber(args[0]);
+ if (cardToRemove != null) {
+ Integer count = 1;
+ if (args.length > 1 && args[1].matches("[0-9]+")) {
+ count = Integer.valueOf(args[1]);
+ if (count <= 0) {
+ System.out.println("Can't remove " + count + " cards.");
+ return;
}
- } else {
- System.out.println("Please specify a card number to remove.");
}
+ removeCard(cardToRemove, count);
} else {
- System.out.println("Select a set before removing cards.");
+ System.out.println(args[0] + " does not correspond to a card in " + selectedSet.getName() + ".");
}
- break;
-
- /*
- * Add one or more of a card.
- */
- default:
- if (selectedSet != null) {
- // a blank line after adding a card repeats the addition unlimitedly
- if (commands.length == 1 && commands[0].isEmpty()) {
- if (lastAction == Action.ADD)
- add(lastAction.card, lastAction.count);
- } else {
- Card cardToAdd = selectedSet.getCardByNumber(commands[0]);
- if (cardToAdd != null) {
- Integer count = 1;
- if (commands.length > 1 && commands[1].matches("[0-9]+")) {
- count = Integer.valueOf(commands[1]);
- if (count <= 0) {
- System.out.println("Can't add " + count + " cards.");
- return;
- }
- }
- add(cardToAdd, count);
- } else {
- System.out.println(commands[0] + " does not correspond to a card in " + selectedSet.name + ".");
+ } else {
+ System.out.println("Please specify a card number to remove.");
+ }
+ } else {
+ System.out.println("Select a set before removing cards.");
+ }
+ }
+
+ /**
+ * Add one or more of a card.
+ *
+ * @param number the number of the card to add.
+ * @param args optionally the count to add.
+ */
+ public void add(String number, String[] args) {
+ if (selectedSet != null) {
+ // a blank line after adding a card repeats the addition unlimitedly
+ if (number.isEmpty()) {
+ if (lastAction == Action.ADD)
+ addCard(lastAction.card, lastAction.count);
+ } else {
+ Card cardToAdd = selectedSet.getCardByNumber(number);
+ if (cardToAdd != null) {
+ Integer count = 1;
+ if (args.length > 0 && args[0].matches("[0-9]+")) {
+ count = Integer.valueOf(args[0]);
+ if (count <= 0) {
+ System.out.println("Can't add " + count + " cards.");
+ return;
}
}
+ addCard(cardToAdd, count);
} else {
- System.out.println("Select a set before adding cards.");
+ System.out.println(number + " does not correspond to a card in " + selectedSet.getName() + ".");
}
- break;
}
+ } else {
+ System.out.println("Select a set before adding cards.");
}
}
-
+
/**
* Add the specified count of the specified card
* to the cardbase.
@@ -380,16 +417,14 @@ public class CardbaseCLI {
* @param card the card to add.
* @param count the number of times to add it.
*/
- private void add(Card card, Integer count) {
- // MTG JSON does not contain this information, but it is useful for sorting
- card.setCode = selectedSet.code;
- cbm.addCard(card, count);
+ private void addCard(Card card, Integer count) {
+ cardbaseManager.addCard(card, count);
System.out.println("Added " + count + "x " + card.name + ".");
savePrompt = true;
lastAction = Action.ADD;
lastAction.set(card, count);
}
-
+
/**
* Remove the specified count of the specified card
* from the cardbase.
@@ -397,14 +432,19 @@ public class CardbaseCLI {
* @param card the card to remove.
* @param count the number of times to remove it.
*/
- private void remove(Card card, Integer count) {
- cbm.removeCard(card, count);
- System.out.println("Removed " + count + "x " + card.name + ".");
- savePrompt = true;
- lastAction = Action.REMOVE;
- lastAction.set(card, count);
+ private void removeCard(Card card, Integer count) {
+ Integer removed = cardbaseManager.removeCard(card, count);
+ if (removed > 0) {
+ System.out.println("Removed " + removed + "x " + card.name + ".");
+ savePrompt = true;
+ lastAction = Action.REMOVE;
+ lastAction.set(card, removed);
+ } else {
+ System.out.println(card.name + " is not in the cardbase.");
+ }
+
}
-
+
/**
* Return a {@code String} that is guaranteed to be a legal file name.
*
@@ -420,7 +460,7 @@ public class CardbaseCLI {
}
return name;
}
-
+
/**
* Prints a glance of the specified card. A glance contains simply
* the card count, name, set code and set number.
@@ -430,7 +470,7 @@ public class CardbaseCLI {
private void printGlance(Card card) {
System.out.println(String.format("%1$-4d %2$s (%3$s, %4$s)", card.count, card.name, card.setCode, card.number));
}
-
+
/**
* Prints a perusal of the specified card. A perusal contains more
* information than a glance, but not every single field the card has
@@ -444,10 +484,10 @@ public class CardbaseCLI {
if (card.manaCost != null) System.out.println("\tCost: " + card.manaCost);
if (card.power != null && card.toughness != null) System.out.println("\t" + card.power + "/" + card.toughness);
if (card.loyalty != null) System.out.println("\tLoyalty: " + card.loyalty);
-
+
if (card.text != null) System.out.println("\t" + card.text.replaceAll("\n", "\n\t"));
if (card.flavor != null) System.out.println("\t" + card.flavor.replaceAll("\n", "\n\t"));
-
+
if (card.rarity != null) System.out.println("\t" + card.rarity);
if (card.multiverseid != null) System.out.println("\tMID: " + card.multiverseid);
if (card.artist != null) System.out.println("\tIllus. " + card.artist);