Made sorting on CN more reliable with zero-padded strings

This commit is contained in:
leriomaggio
2021-05-24 10:14:22 +01:00
parent 189b0ea122
commit 2a304bd413

View File

@@ -50,7 +50,9 @@ import forge.util.CardTranslation;
import forge.util.Localizer; import forge.util.Localizer;
public enum ColumnDef { public enum ColumnDef {
/**The column containing the inventory item name.*/ /**
* The column containing the inventory item name.
*/
STRING("", "", 0, false, SortState.ASC, STRING("", "", 0, false, SortState.ASC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -64,7 +66,9 @@ public enum ColumnDef {
return from.getKey().toString(); return from.getKey().toString();
} }
}), }),
/**The name column.*/ /**
* The name column.
*/
NAME("lblName", "lblName", 180, false, SortState.ASC, NAME("lblName", "lblName", 180, false, SortState.ASC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -83,7 +87,9 @@ public enum ColumnDef {
} }
}), }),
/**The column for sorting cards in collector order.*/ /**
* The column for sorting cards in collector order.
*/
COLLECTOR_ORDER("lblCN", "ttCN", 20, false, SortState.ASC, COLLECTOR_ORDER("lblCN", "ttCN", 20, false, SortState.ASC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -99,7 +105,9 @@ public enum ColumnDef {
((PaperCard) item).getCollectorNumber() : IPaperCard.NO_COLLECTOR_NUMBER; ((PaperCard) item).getCollectorNumber() : IPaperCard.NO_COLLECTOR_NUMBER;
} }
}), }),
/**The type column.*/ /**
* The type column.
*/
TYPE("lblType", "ttType", 100, false, SortState.ASC, TYPE("lblType", "ttType", 100, false, SortState.ASC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -113,7 +121,9 @@ public enum ColumnDef {
return CardTranslation.getTranslatedType(from.getKey().getName(), toType(from.getKey())); return CardTranslation.getTranslatedType(from.getKey().getName(), toType(from.getKey()));
} }
}), }),
/**The mana cost column.*/ /**
* The mana cost column.
*/
COST("lblCost", "ttCost", 70, true, SortState.ASC, COST("lblCost", "ttCost", 70, true, SortState.ASC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -127,7 +137,9 @@ public enum ColumnDef {
return toCardRules(from.getKey()); return toCardRules(from.getKey());
} }
}), }),
/**The color column.*/ /**
* The color column.
*/
COLOR("lblColor", "ttColor", 46, true, SortState.ASC, COLOR("lblColor", "ttColor", 46, true, SortState.ASC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -141,7 +153,9 @@ public enum ColumnDef {
return toColor(from.getKey()); return toColor(from.getKey());
} }
}), }),
/**The power column.*/ /**
* The power column.
*/
POWER("lblPower", "ttPower", 20, true, SortState.DESC, POWER("lblPower", "ttPower", 20, true, SortState.DESC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -155,7 +169,9 @@ public enum ColumnDef {
return toPower(from.getKey()); return toPower(from.getKey());
} }
}), }),
/**The toughness column.*/ /**
* The toughness column.
*/
TOUGHNESS("lblToughness", "ttToughness", 20, true, SortState.DESC, TOUGHNESS("lblToughness", "ttToughness", 20, true, SortState.DESC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -169,7 +185,9 @@ public enum ColumnDef {
return toToughness(from.getKey()); return toToughness(from.getKey());
} }
}), }),
/**The converted mana cost column.*/ /**
* The converted mana cost column.
*/
CMC("lblCMC", "ttCMC", 20, true, SortState.ASC, CMC("lblCMC", "ttCMC", 20, true, SortState.ASC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -183,7 +201,9 @@ public enum ColumnDef {
return toCMC(from.getKey()); return toCMC(from.getKey());
} }
}), }),
/**The rarity column.*/ /**
* The rarity column.
*/
RARITY("lblRarity", "lblRarity", 20, true, SortState.DESC, RARITY("lblRarity", "lblRarity", 20, true, SortState.DESC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -197,7 +217,9 @@ public enum ColumnDef {
return toRarity(from.getKey()); return toRarity(from.getKey());
} }
}), }),
/**The set code column.*/ /**
* The set code column.
*/
SET("lblSet", "lblSet", 38, true, SortState.DESC, SET("lblSet", "lblSet", 38, true, SortState.DESC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -214,7 +236,9 @@ public enum ColumnDef {
return i instanceof InventoryItemFromSet ? ((InventoryItemFromSet) i).getEdition() : "n/a"; return i instanceof InventoryItemFromSet ? ((InventoryItemFromSet) i).getEdition() : "n/a";
} }
}), }),
/**The AI compatibility flag column*/ /**
* The AI compatibility flag column
*/
AI("lblAI", "lblAIStatus", 30, true, SortState.ASC, AI("lblAI", "lblAIStatus", 30, true, SortState.ASC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -237,7 +261,9 @@ public enum ColumnDef {
: (ai.getRemRandomDecks() ? "?" : ""); : (ai.getRemRandomDecks() ? "?" : "");
} }
}), }),
/**The Draft ranking column.*/ /**
* The Draft ranking column.
*/
RANKING("lblRanking", "lblDraftRanking", 50, true, SortState.ASC, RANKING("lblRanking", "lblDraftRanking", 50, true, SortState.ASC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -251,7 +277,9 @@ public enum ColumnDef {
return toRanking(from.getKey(), true); return toRanking(from.getKey(), true);
} }
}), }),
/**The quantity column.*/ /**
* The quantity column.
*/
QUANTITY("lblQty", "lblQuantity", 25, true, SortState.ASC, QUANTITY("lblQty", "lblQuantity", 25, true, SortState.ASC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -265,7 +293,9 @@ public enum ColumnDef {
return from.getValue(); return from.getValue();
} }
}), }),
/**The quantity in deck column.*/ /**
* The quantity in deck column.
*/
DECK_QUANTITY("lblQuantity", "lblQuantity", 50, true, SortState.ASC, DECK_QUANTITY("lblQuantity", "lblQuantity", 50, true, SortState.ASC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -279,19 +309,29 @@ public enum ColumnDef {
return from.getValue(); return from.getValue();
} }
}), }),
/**The new inventory flag column.*/ /**
* The new inventory flag column.
*/
NEW("lblNew", "lblNew", 30, true, SortState.DESC, NEW("lblNew", "lblNew", 30, true, SortState.DESC,
null, null), //functions will be set later null, null), //functions will be set later
/**The price column.*/ /**
* The price column.
*/
PRICE("lblPrice", "ttPrice", 35, true, SortState.DESC, PRICE("lblPrice", "ttPrice", 35, true, SortState.DESC,
null, null), null, null),
/**The quantity owned column.*/ /**
* The quantity owned column.
*/
OWNED("lblOwned", "lblOwned", 20, true, SortState.ASC, OWNED("lblOwned", "lblOwned", 20, true, SortState.ASC,
null, null), null, null),
/**The deck name column.*/ /**
* The deck name column.
*/
DECKS("lblDecks", "lblDecks", 20, true, SortState.ASC, DECKS("lblDecks", "lblDecks", 20, true, SortState.ASC,
null, null), null, null),
/**The favorite flag column.*/ /**
* The favorite flag column.
*/
FAVORITE("", "ttFavorite", 18, true, SortState.DESC, FAVORITE("", "ttFavorite", 18, true, SortState.DESC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -309,7 +349,9 @@ public enum ColumnDef {
return toCard(from.getKey()); return toCard(from.getKey());
} }
}), }),
/**The favorite deck flag column.*/ /**
* The favorite deck flag column.
*/
DECK_FAVORITE("", "ttFavorite", 18, true, SortState.DESC, DECK_FAVORITE("", "ttFavorite", 18, true, SortState.DESC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -327,7 +369,9 @@ public enum ColumnDef {
return toDeck(from.getKey()); return toDeck(from.getKey());
} }
}), }),
/**The edit/delete deck column.*/ /**
* The edit/delete deck column.
*/
DECK_ACTIONS("", "lblDeleteEdit", 40, true, SortState.DESC, DECK_ACTIONS("", "lblDeleteEdit", 40, true, SortState.DESC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -341,7 +385,9 @@ public enum ColumnDef {
return toDeck(from.getKey()); return toDeck(from.getKey());
} }
}), }),
/**The deck folder column.*/ /**
* The deck folder column.
*/
DECK_FOLDER("lblFolder", "lblFolder", 80, false, SortState.ASC, DECK_FOLDER("lblFolder", "lblFolder", 80, false, SortState.ASC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -355,7 +401,9 @@ public enum ColumnDef {
return toDeckFolder(from.getKey()); return toDeckFolder(from.getKey());
} }
}), }),
/**The deck color column.*/ /**
* The deck color column.
*/
DECK_COLOR("lblColor", "ttColor", 70, true, SortState.ASC, DECK_COLOR("lblColor", "ttColor", 70, true, SortState.ASC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -369,7 +417,9 @@ public enum ColumnDef {
return toDeckColor(from.getKey()); return toDeckColor(from.getKey());
} }
}), }),
/**The deck format column.*/ /**
* The deck format column.
*/
DECK_FORMAT("lblFormat", "ttFormats", 60, false, SortState.DESC, DECK_FORMAT("lblFormat", "ttFormats", 60, false, SortState.DESC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -398,7 +448,9 @@ public enum ColumnDef {
return deck.getFormatsString(); return deck.getFormatsString();
} }
}), }),
/**The deck edition column, a mystery to us all.*/ /**
* The deck edition column, a mystery to us all.
*/
DECK_EDITION("lblSet", "lblSetEdition", 38, true, SortState.DESC, DECK_EDITION("lblSet", "lblSetEdition", 38, true, SortState.DESC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -412,7 +464,9 @@ public enum ColumnDef {
return toDeck(from.getKey()).getEdition().getCode(); return toDeck(from.getKey()).getEdition().getCode();
} }
}), }),
/**The main library size column.*/ /**
* The main library size column.
*/
DECK_MAIN("lblMain", "ttMain", 30, true, SortState.ASC, DECK_MAIN("lblMain", "ttMain", 30, true, SortState.ASC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -426,7 +480,9 @@ public enum ColumnDef {
return toDeck(from.getKey()).getMainSize(); return toDeck(from.getKey()).getMainSize();
} }
}), }),
/**The sideboard size column.*/ /**
* The sideboard size column.
*/
DECK_SIDE("lblSide", "lblSideboard", 30, true, SortState.ASC, DECK_SIDE("lblSide", "lblSideboard", 30, true, SortState.ASC,
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() { new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override @Override
@@ -446,8 +502,16 @@ public enum ColumnDef {
Function<Entry<? extends InventoryItem, Integer>, Object> fnDisplay0) { Function<Entry<? extends InventoryItem, Integer>, Object> fnDisplay0) {
final Localizer localizer = Localizer.getInstance(); final Localizer localizer = Localizer.getInstance();
if (shortName0 != null && !shortName0.isEmpty()) { this.shortName = localizer.getMessage(shortName0);} else {this.shortName = shortName0;} if (shortName0 != null && !shortName0.isEmpty()) {
if (longName0 != null && !longName0.isEmpty()) { this.longName = localizer.getMessage(longName0);} else {this.longName = longName0;} this.shortName = localizer.getMessage(shortName0);
} else {
this.shortName = shortName0;
}
if (longName0 != null && !longName0.isEmpty()) {
this.longName = localizer.getMessage(longName0);
} else {
this.longName = longName0;
}
this.preferredWidth = preferredWidth0; this.preferredWidth = preferredWidth0;
this.isWidthFixed = isWidthFixed0; this.isWidthFixed = isWidthFixed0;
@@ -467,6 +531,7 @@ public enum ColumnDef {
public String toString() { public String toString() {
return this.longName; return this.longName;
} }
/** /**
* Converts a card name to a sortable name. * Converts a card name to a sortable name.
* Trim leading quotes, then move article last, then replace characters. * Trim leading quotes, then move article last, then replace characters.
@@ -474,6 +539,7 @@ public enum ColumnDef {
* Capitals and lowercase sorted as one: "my deck" before "Myr Retribution" * Capitals and lowercase sorted as one: "my deck" before "Myr Retribution"
* Apostrophes matter, though: "D'Avenant" before "Danitha" * Apostrophes matter, though: "D'Avenant" before "Danitha"
* TO DO: Commas before apostrophes: "Rakdos, Lord of Riots" before "Rakdos's Return" * TO DO: Commas before apostrophes: "Rakdos, Lord of Riots" before "Rakdos's Return"
*
* @param printedName The name of the card. * @param printedName The name of the card.
* @return A sortable name. * @return A sortable name.
*/ */
@@ -483,19 +549,24 @@ public enum ColumnDef {
} }
/**Article words. These words get kicked to the end of a sortable name. /**
For localization, simply overwrite this array with appropriate words. * Article words. These words get kicked to the end of a sortable name.
Words in this list are used by the method String moveArticleToEnd(String), useful * For localization, simply overwrite this array with appropriate words.
for alphabetizing phrases, in particular card or other inventory object names.*/ * Words in this list are used by the method String moveArticleToEnd(String), useful
* for alphabetizing phrases, in particular card or other inventory object names.
*/
private static final String[] ARTICLE_WORDS = { private static final String[] ARTICLE_WORDS = {
"A", "A",
"An", "An",
"The" "The"
}; };
/**Detects whether a string begins with an article word /**
@param str The name of the card. * Detects whether a string begins with an article word
@return The sort-friendly name of the card. Example: "The Hive" becomes "Hive The".*/ *
* @param str The name of the card.
* @return The sort-friendly name of the card. Example: "The Hive" becomes "Hive The".
*/
private static String moveArticleToEnd(String str) { private static String moveArticleToEnd(String str) {
String articleWord; String articleWord;
for (int i = 0; i < ARTICLE_WORDS.length; i++) { for (int i = 0; i < ARTICLE_WORDS.length; i++) {
@@ -515,9 +586,11 @@ public enum ColumnDef {
private static IPaperCard toCard(final InventoryItem i) { private static IPaperCard toCard(final InventoryItem i) {
return i instanceof IPaperCard ? ((IPaperCard) i) : null; return i instanceof IPaperCard ? ((IPaperCard) i) : null;
} }
private static ManaCost toManaCost(final InventoryItem i) { private static ManaCost toManaCost(final InventoryItem i) {
return i instanceof IPaperCard ? ((IPaperCard) i).getRules().getManaCost() : ManaCost.NO_COST; return i instanceof IPaperCard ? ((IPaperCard) i).getRules().getManaCost() : ManaCost.NO_COST;
} }
private static CardRules toCardRules(final InventoryItem i) { private static CardRules toCardRules(final InventoryItem i) {
return i instanceof IPaperCard ? ((IPaperCard) i).getRules() : null; return i instanceof IPaperCard ? ((IPaperCard) i).getRules() : null;
} }
@@ -567,26 +640,46 @@ public enum ColumnDef {
private static DeckProxy toDeck(final InventoryItem i) { private static DeckProxy toDeck(final InventoryItem i) {
return i instanceof DeckProxy ? ((DeckProxy) i) : null; return i instanceof DeckProxy ? ((DeckProxy) i) : null;
} }
private static ColorSet toDeckColor(final InventoryItem i) { private static ColorSet toDeckColor(final InventoryItem i) {
return i instanceof DeckProxy ? ((DeckProxy) i).getColor() : null; return i instanceof DeckProxy ? ((DeckProxy) i).getColor() : null;
} }
private static String toDeckFolder(final InventoryItem i) { private static String toDeckFolder(final InventoryItem i) {
return i instanceof DeckProxy ? ((DeckProxy) i).getPath() + "/" : null; return i instanceof DeckProxy ? ((DeckProxy) i).getPath() + "/" : null;
} }
/**Generates a sortable numeric string based on a card's attributes. /**
This is a multi-layer sort. It is coded in layers to make it easier to manipulate. * Generates a sortable numeric string based on a card's attributes.
This method can be fed any inventory item, but is only useful for paper cards. * This is a multi-layer sort. It is coded in layers to make it easier to manipulate.
@param i An inventory item. * This method can be fed any inventory item, but is only useful for paper cards.
@return A sortable numeric string based on the item's attributes.*/ *
* @param i An inventory item.
* @return A sortable numeric string based on the item's attributes.
*/
private static String toCollectorPrefix(final InventoryItem i) { private static String toCollectorPrefix(final InventoryItem i) {
//make sure it's a card. if not, pointless to proceed. //make sure it's a card. if not, pointless to proceed.
return (i instanceof PaperCard ? ((PaperCard) i).getCollectorNumber() : IPaperCard.NO_COLLECTOR_NUMBER) + toSortableName(i.getName()); String collectorNumber;
if (i instanceof PaperCard) {
collectorNumber = ((PaperCard) i).getCollectorNumber();
// Now, for proper sorting, let's zero-pad the collector number (if integer)
try {
int collNr = Integer.parseInt(collectorNumber);
collectorNumber = String.format("%05d", collNr);
} catch (NumberFormatException ex) {
} // NOOP, leave it as it is - NaN (may contains letters)
} else {
collectorNumber = IPaperCard.NO_COLLECTOR_NUMBER;
}
return collectorNumber + toSortableName(i.getName());
} }
/**Returns 1 for land, otherwise 0 and continues sorting. /**
@param i A paper card. * Returns 1 for land, otherwise 0 and continues sorting.
@return Part of a sortable numeric string.*/ *
* @param i A paper card.
* @return Part of a sortable numeric string.
*/
private static String toLandsLast(final InventoryItem i) { private static String toLandsLast(final InventoryItem i) {
//nonland? //nonland?
return !(((IPaperCard) i).getRules().getType().isLand()) ? return !(((IPaperCard) i).getRules().getType().isLand()) ?
@@ -595,10 +688,13 @@ public enum ColumnDef {
: "1"; : "1";
} }
/**Returns 1 for artifacts without color shards in their mana cost, otherwise 0 and continues sorting. /**
As of 2019, colored artifacts appear here if there are no colored shards in their casting cost. * Returns 1 for artifacts without color shards in their mana cost, otherwise 0 and continues sorting.
@param i A paper card. * As of 2019, colored artifacts appear here if there are no colored shards in their casting cost.
@return Part of a sortable numeric string.*/ *
* @param i A paper card.
* @return Part of a sortable numeric string.
*/
private static String toArtifactsWithColorlessCostsLast(final InventoryItem i) { private static String toArtifactsWithColorlessCostsLast(final InventoryItem i) {
forge.card.mana.ManaCost manaCost = ((IPaperCard) i).getRules().getManaCost(); forge.card.mana.ManaCost manaCost = ((IPaperCard) i).getRules().getManaCost();
@@ -611,42 +707,57 @@ public enum ColumnDef {
? "0" + toSplitLast(i) : "1"; ? "0" + toSplitLast(i) : "1";
} }
/**Returns 1 for split cards or 0 for other cards; continues sorting. /**
@param i A paper card. * Returns 1 for split cards or 0 for other cards; continues sorting.
@return Part of a sortable numeric string.*/ *
* @param i A paper card.
* @return Part of a sortable numeric string.
*/
private static String toSplitLast(final InventoryItem i) { private static String toSplitLast(final InventoryItem i) {
return ((IPaperCard) i).getRules().getSplitType() != CardSplitType.Split ? return ((IPaperCard) i).getRules().getSplitType() != CardSplitType.Split ?
"0" + toConspiracyFirst(i) : "1" + toSplitCardSort(i); "0" + toConspiracyFirst(i) : "1" + toSplitCardSort(i);
} }
/**Returns 0 for Conspiracy cards, otherwise 1 and continues sorting. /**
@param i A paper card. * Returns 0 for Conspiracy cards, otherwise 1 and continues sorting.
@return Part of a sortable numeric string.*/ *
* @param i A paper card.
* @return Part of a sortable numeric string.
*/
private static String toConspiracyFirst(final InventoryItem i) { private static String toConspiracyFirst(final InventoryItem i) {
return ((IPaperCard) i).getRules().getType().isConspiracy() return ((IPaperCard) i).getRules().getType().isConspiracy()
? "0" //is a Conspiracy ? "0" //is a Conspiracy
: "1" + toColorlessFirst(i); //isn't a Conspiracy : "1" + toColorlessFirst(i); //isn't a Conspiracy
} }
/**Returns 0 for colorless cards, otherwise 1 and continues sorting. /**
@param i A paper card. * Returns 0 for colorless cards, otherwise 1 and continues sorting.
@return Part of a sortable numeric string.*/ *
* @param i A paper card.
* @return Part of a sortable numeric string.
*/
private static String toColorlessFirst(final InventoryItem i) { private static String toColorlessFirst(final InventoryItem i) {
return toColor(i).isColorless() ? return toColor(i).isColorless() ?
"0" : "1" + toMonocolorFirst(i); "0" : "1" + toMonocolorFirst(i);
} }
/**Returns 0 for monocolor cards, 1 for multicolor cards; continues sorting. /**
@param i A paper card. * Returns 0 for monocolor cards, 1 for multicolor cards; continues sorting.
@return Part of a sortable numeric string.*/ *
* @param i A paper card.
* @return Part of a sortable numeric string.
*/
private static String toMonocolorFirst(final InventoryItem i) { private static String toMonocolorFirst(final InventoryItem i) {
return toColor(i).isMonoColor() ? return toColor(i).isMonoColor() ?
"0" + toWubrgOrder(i) : "1" + toGoldFirst(i); "0" + toWubrgOrder(i) : "1" + toGoldFirst(i);
} }
/**Returns 0 for gold cards and continues sorting, 1 otherwise. /**
@param i A paper card. * Returns 0 for gold cards and continues sorting, 1 otherwise.
@return Part of a sortable numeric string.*/ *
* @param i A paper card.
* @return Part of a sortable numeric string.
*/
private static String toGoldFirst(final InventoryItem i) { private static String toGoldFirst(final InventoryItem i) {
forge.card.mana.ManaCost manaCost = ((IPaperCard) i).getRules().getManaCost(); forge.card.mana.ManaCost manaCost = ((IPaperCard) i).getRules().getManaCost();
@@ -655,11 +766,14 @@ public enum ColumnDef {
manaCost.canBePaidWithAvaliable(MagicColor.GREEN)) ? "0" : "1"; manaCost.canBePaidWithAvaliable(MagicColor.GREEN)) ? "0" : "1";
} }
/**Entry point for generating split card sortable strings. /**
Splits the card into two card faces, then sends it to the next * Entry point for generating split card sortable strings.
sorting method. * Splits the card into two card faces, then sends it to the next
@param i A paper card. * sorting method.
@return Part of a sortable numeric string.*/ *
* @param i A paper card.
* @return Part of a sortable numeric string.
*/
//Split card sorting is probably as complex as sorting gets. //Split card sorting is probably as complex as sorting gets.
//This method serves as an entry point only, separating the two card parts for convenience. //This method serves as an entry point only, separating the two card parts for convenience.
private static String toSplitCardSort(final InventoryItem i) { private static String toSplitCardSort(final InventoryItem i) {
@@ -669,18 +783,21 @@ public enum ColumnDef {
return toSplitSort(mainPart, otherPart); return toSplitSort(mainPart, otherPart);
} }
/**Generates a sortable numeric string for split cards. /**
Split cards are sorted by color on both halves. * Generates a sortable numeric string for split cards.
Sort order is C//C, W//W, U//U, B//B, R//R, G//G, * Split cards are sorted by color on both halves.
Gold/Gold, * Sort order is C//C, W//W, U//U, B//B, R//R, G//G,
W//U, U//B, B//R, R//G, G//W, * Gold/Gold,
W//B, U//R, B//G, R//W, G//U, * W//U, U//B, B//R, R//G, G//W,
W//R, U//G, B//W, R//U, G//B, * W//B, U//R, B//G, R//W, G//U,
W//G, U//W, B//U, R//B, G//R. * W//R, U//G, B//W, R//U, G//B,
Any that do not conform will sort at the end. * W//G, U//W, B//U, R//B, G//R.
@param mainPart The first half of the card. * Any that do not conform will sort at the end.
@param otherPart The other half of the card. *
@return Part of a sortable numeric string.*/ * @param mainPart The first half of the card.
* @param otherPart The other half of the card.
* @return Part of a sortable numeric string.
*/
private static String toSplitSort(final ICardFace mainPart, final ICardFace otherPart) { private static String toSplitSort(final ICardFace mainPart, final ICardFace otherPart) {
ColorSet mainPartColor = mainPart.getColor(); ColorSet mainPartColor = mainPart.getColor();
ColorSet otherPartColor = otherPart.getColor(); ColorSet otherPartColor = otherPart.getColor();
@@ -733,46 +850,61 @@ public enum ColumnDef {
"99"; "99";
} }
/**Returns 0 for white, 1 for blue, 2 for black, 3 for red, or 4 for green. /**
@param i A paper card. * Returns 0 for white, 1 for blue, 2 for black, 3 for red, or 4 for green.
@return Part of a sortable numeric string.*/ *
* @param i A paper card.
* @return Part of a sortable numeric string.
*/
private static String toWubrgOrder(final InventoryItem i) { private static String toWubrgOrder(final InventoryItem i) {
ColorSet color = toColor(i); ColorSet color = toColor(i);
return color.hasWhite() ? "0" : color.hasBlue() ? "1" : color.hasBlack() ? "2" : return color.hasWhite() ? "0" : color.hasBlue() ? "1" : color.hasBlack() ? "2" :
color.hasRed() ? "3" : "4"; color.hasRed() ? "3" : "4";
} }
/**Returns 1 for Contraptions, otherwise 0 and continues sorting. /**
@param i A paper card. * Returns 1 for Contraptions, otherwise 0 and continues sorting.
@return Part of a sortable numeric string.*/ *
* @param i A paper card.
* @return Part of a sortable numeric string.
*/
private static String toContraptionsLast(final InventoryItem i) { private static String toContraptionsLast(final InventoryItem i) {
return !(((IPaperCard) i).getRules().getType().hasSubtype("Contraption")) ? return !(((IPaperCard) i).getRules().getType().hasSubtype("Contraption")) ?
"0" + toLandsLast(i) : "1"; "0" + toLandsLast(i) : "1";
} }
/**Returns 1 for basic lands, 0 otherwise, and continues sorting. /**
@param i A paper card. * Returns 1 for basic lands, 0 otherwise, and continues sorting.
@return Part of a sortable numeric string.*/ *
* @param i A paper card.
* @return Part of a sortable numeric string.
*/
private static String toBasicLandsLast(final InventoryItem i) { private static String toBasicLandsLast(final InventoryItem i) {
return !(((IPaperCard) i).getRules().getType().isBasicLand()) return !(((IPaperCard) i).getRules().getType().isBasicLand())
? "0" + toContraptionsLast(i) ? "0" + toContraptionsLast(i)
: "1" + toFullArtFirst(i); : "1" + toFullArtFirst(i);
} }
/**Currently only continues sorting. If Forge is updated to /**
use a flag for full-art lands, this method should be updated * Currently only continues sorting. If Forge is updated to
to assign those 0 and regular lands 1, then continue sorting. * use a flag for full-art lands, this method should be updated
@param i A paper card. * to assign those 0 and regular lands 1, then continue sorting.
@return Part of a sortable numeric string.*/ *
* @param i A paper card.
* @return Part of a sortable numeric string.
*/
private static String toFullArtFirst(final InventoryItem i) { private static String toFullArtFirst(final InventoryItem i) {
return toBasicLandSort(i); return toBasicLandSort(i);
} }
/**Returns 0 for wastes, 1 for plains, 2 for island, /**
3 for swamp, 4 for mountain, 5 for forest. Snow * Returns 0 for wastes, 1 for plains, 2 for island,
lands are treated like nonsnow. * 3 for swamp, 4 for mountain, 5 for forest. Snow
@param i A paper card. * lands are treated like nonsnow.
@return Part of a sortable numeric string.*/ *
* @param i A paper card.
* @return Part of a sortable numeric string.
*/
private static String toBasicLandSort(final InventoryItem i) { private static String toBasicLandSort(final InventoryItem i) {
CardType basicLandType = ((IPaperCard) i).getRules().getType(); CardType basicLandType = ((IPaperCard) i).getRules().getType();
return basicLandType.hasStringType("Plains") ? "1" : ( return basicLandType.hasStringType("Plains") ? "1" : (