From cd6a5c077874ac6baacc8b073195aaea81a1e247 Mon Sep 17 00:00:00 2001
From: Eduardo Pedroni <e.pedroni91@gmail.com>
Date: Sun, 28 Jun 2015 12:51:11 +0200
Subject: Made good progress with introspective sort, fixed ant build issue,
 ant builds are now done on a different bin directory

---
 src/eu/equalparts/cardbase/cli/CardbaseCLI.java    | 13 ++++
 .../cardbase/comparator/CardComparator.java        | 37 ++++++++---
 .../cardbase/comparator/ComparatorDelegates.java   | 76 ++++++++++++++--------
 .../cardbase/comparator/SpecialFields.java         | 11 +++-
 src/eu/equalparts/cardbase/data/Card.java          |  8 ++-
 5 files changed, 104 insertions(+), 41 deletions(-)

(limited to 'src/eu/equalparts')

diff --git a/src/eu/equalparts/cardbase/cli/CardbaseCLI.java b/src/eu/equalparts/cardbase/cli/CardbaseCLI.java
index 6a7f013..866314a 100644
--- a/src/eu/equalparts/cardbase/cli/CardbaseCLI.java
+++ b/src/eu/equalparts/cardbase/cli/CardbaseCLI.java
@@ -50,6 +50,10 @@ public class CardbaseCLI {
 	 * Location of the help file.
 	 */
 	private static final String HELP_FILE_PATH = "/help";
+	/**
+	 * Program version.
+	 */
+	private static final String VERSION = "1.0";
 	/**
 	 * The last action performed by the user.
 	 */
@@ -162,6 +166,8 @@ public class CardbaseCLI {
 				} else if (command.equalsIgnoreCase("write")
 						|| command.equalsIgnoreCase("save")) {
 					write(args);
+				} else if (command.equalsIgnoreCase("version")) {
+					version();
 				} else if (command.equalsIgnoreCase("exit")) {
 					exit();
 				} else if (command.equalsIgnoreCase("sets")) {
@@ -233,6 +239,13 @@ public class CardbaseCLI {
 		}
 	}
 
+	/**
+	 * Print program version.
+	 */
+	public void version() {
+		System.out.println("Cardbase v" + VERSION);
+	}
+	
 	/**
 	 * Exit procedure.
 	 */
diff --git a/src/eu/equalparts/cardbase/comparator/CardComparator.java b/src/eu/equalparts/cardbase/comparator/CardComparator.java
index 78200b8..fe440f3 100644
--- a/src/eu/equalparts/cardbase/comparator/CardComparator.java
+++ b/src/eu/equalparts/cardbase/comparator/CardComparator.java
@@ -1,5 +1,6 @@
 package eu.equalparts.cardbase.comparator;
 
+import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
@@ -7,6 +8,8 @@ import java.util.Comparator;
 import java.util.function.BiFunction;
 
 import eu.equalparts.cardbase.Cardbase;
+import eu.equalparts.cardbase.comparator.SpecialFields.DirtyNumber;
+import eu.equalparts.cardbase.comparator.SpecialFields.Rarity;
 import eu.equalparts.cardbase.data.Card;
 
 /**
@@ -35,9 +38,11 @@ public class CardComparator implements Comparator<Card> {
 	 * The field being compared.
 	 */
 	private Field fieldToCompare;
+	/**
+	 * The comparison delegate to use for the specified field.
+	 */
+	private BiFunction<Comparable, Comparable, Integer> selectedComparisonDelegate = this::defaultComparison;
 	
-	private BiFunction<Comparable, Comparable, Integer> comparisonDelegate = this::defaultComparison;
-
 	/**
 	 * Creates a new comparator for the specified field only. This class
 	 * will only be constructed successfully if the field comes from
@@ -55,12 +60,14 @@ public class CardComparator implements Comparator<Card> {
 			this.fieldToCompare = fieldToCompare;
 			
 			// if annotated with a special comparator, set the comparison delegate here
-			this.comparisonDelegate = ComparatorDelegates::compareManaCost;
-			
+			for (Annotation annotation : fieldToCompare.getAnnotations()) {
+				if (annotation.annotationType() == DirtyNumber.class) {
+					this.selectedComparisonDelegate = ComparatorDelegates::compareDirtyNumber;
+				} else if (annotation.annotationType() == Rarity.class) {
+					this.selectedComparisonDelegate = ComparatorDelegates::compareRarity;
+				}
+			}
 		} else {
-			System.out.println(fieldToCompare.isAccessible());
-			System.out.println(fieldToCompare.getDeclaringClass().equals(Card.class));
-			System.out.println(isSelfComparable(fieldToCompare.getType()));
 			throw new IllegalArgumentException("The field provided is not valid.");
 		}
 	}
@@ -75,9 +82,21 @@ public class CardComparator implements Comparator<Card> {
 			Comparable field1 = (Comparable) fieldToCompare.get(o1);
 			Comparable field2 = (Comparable) fieldToCompare.get(o2);
 			
-			return comparisonDelegate.apply(field1, field2);
+			// if either or both fields' values are null, skip delegation altogether since delegates are not required to deal with null values
+			if (field1 == null) {
+				if (field2 == null) {
+					return 0;
+				} else {
+					return -1;
+				}
+			} else if (field2 == null) {
+				return 1;
+			} else {
+				return selectedComparisonDelegate.apply(field1, field2);
+			}
+			
 		} catch (IllegalArgumentException e) {
-			System.out.println("Error: class Card does not define field" + fieldToCompare.getName() + ".");
+			System.out.println("Error: class Card does not define field \"" + fieldToCompare.getName() + "\".");
 			if (Cardbase.DEBUG) e.printStackTrace();
 		} catch (IllegalAccessException e) {
 			System.out.println("Error: field " + fieldToCompare.getName() + " in Card is not visible.");
diff --git a/src/eu/equalparts/cardbase/comparator/ComparatorDelegates.java b/src/eu/equalparts/cardbase/comparator/ComparatorDelegates.java
index 5736381..7bf09ac 100644
--- a/src/eu/equalparts/cardbase/comparator/ComparatorDelegates.java
+++ b/src/eu/equalparts/cardbase/comparator/ComparatorDelegates.java
@@ -1,39 +1,59 @@
 package eu.equalparts.cardbase.comparator;
 
 
-abstract class ComparatorDelegates {
+final class ComparatorDelegates {
 
 	private ComparatorDelegates() {}
-	
-	public static Integer compareManaCost(Comparable<String> field1, Comparable<String> field2) {
-		// avoid casting syntax nightmare
-		String mc1 = (String) field1, mc2 = (String) field2;
-		
-		// first by number of colours
-		int mc1count = 0, mc2count = 0;
-		if (mc1.contains("W")) mc1count++;
-		if (mc1.contains("U")) mc1count++;
-		if (mc1.contains("B")) mc1count++;
-		if (mc1.contains("R")) mc1count++;
-		if (mc1.contains("G")) mc1count++;
-		
-		if (mc2.contains("W")) mc2count++;
-		if (mc2.contains("U")) mc2count++;
-		if (mc2.contains("B")) mc2count++;
-		if (mc2.contains("R")) mc2count++;
-		if (mc2.contains("G")) mc2count++;
+
+	/*
+	 * Delegates
+	 */
+	public static Integer compareDirtyNumber(Comparable<String> field1, Comparable<String> field2) {
+		// this assumes that the format is uninterrupted numbers and letters
+		String number1 = ((String) field1).replaceAll("[^0-9]+", "");
+		String number2 = ((String) field2).replaceAll("[^0-9]+", "");
 		
-		if (mc1count != mc2count)
-			return (mc1count < mc2count) ? -1 : ((mc1count == mc2count) ? 0 : 1);
+		Integer int1 = number1.matches("[0-9]+") ? Integer.parseInt(number1) : null;
+		Integer int2 = number2.matches("[0-9]+") ? Integer.parseInt(number2) : null;
 		
-		// next by colour wheel
+		if (int1 == null) {
+			if (int2 != null) {
+				// field1 has no numbers but field2 does, field1 is less by default
+				// if neither have numbers, letters will be looked at below
+				return -1;
+			}
+		} else if (int2 == null) {
+			// field2 has no numbers but field1 does, field1 is more by default
+			return 1;
+		} else {
+			// both have numbers, perform comparison if not identical
+			// if identical, look at letters below
+			if (int1 != int2)
+				return int1.compareTo(int2);
+		}
+		// compare by letters
+		String letter1 = number1.replaceAll("[0-9]+", "");
+		String letter2 = number2.replaceAll("[0-9]+", "");
+		return letter1.compareTo(letter2);
+	}
+
+	public static Integer compareRarity(Comparable<String> field1, Comparable<String> field2) {
+		// assign numerical values based on the different possibilities and compare those instead
+		Integer value1 = getRarityValue((String) field1);
+		Integer value2 = getRarityValue((String) field2);
 		
-		return 0;
+		return value1.compareTo(value2);
 	}
 	
+	/*
+	 * Internally used utility functions
+	 */
+	private static int getRarityValue(String rarityString) {
+		return rarityString.equalsIgnoreCase("Common") ? 0 :
+			   rarityString.equalsIgnoreCase("Uncommon") ? 1 :
+			   rarityString.equalsIgnoreCase("Rare") ? 2 :
+			   rarityString.equalsIgnoreCase("Mythic Rare") ? 3 : 
+			   rarityString.equalsIgnoreCase("Basic Land") ? 4 : 
+			   rarityString.equalsIgnoreCase("Special") ? 5 : 6;
+	}
 }
-/*
- * first by number of colours
- * next by colour wheel: white > blue > black > red > green
- * next by cmc
- */
\ No newline at end of file
diff --git a/src/eu/equalparts/cardbase/comparator/SpecialFields.java b/src/eu/equalparts/cardbase/comparator/SpecialFields.java
index 8ecc82c..f17ccc6 100644
--- a/src/eu/equalparts/cardbase/comparator/SpecialFields.java
+++ b/src/eu/equalparts/cardbase/comparator/SpecialFields.java
@@ -1,8 +1,15 @@
 package eu.equalparts.cardbase.comparator;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
-public class SpecialFields {
 
-	public @interface ManaCost {}
+public class SpecialFields {
+	
+	@Retention(RetentionPolicy.RUNTIME)
+	public @interface DirtyNumber {}
+	
+	@Retention(RetentionPolicy.RUNTIME)
+	public @interface Rarity {}
 	
 }
diff --git a/src/eu/equalparts/cardbase/data/Card.java b/src/eu/equalparts/cardbase/data/Card.java
index 7202660..e2ad3f0 100644
--- a/src/eu/equalparts/cardbase/data/Card.java
+++ b/src/eu/equalparts/cardbase/data/Card.java
@@ -1,21 +1,25 @@
 package eu.equalparts.cardbase.data;
 
-import eu.equalparts.cardbase.comparator.SpecialFields.ManaCost;
+import eu.equalparts.cardbase.comparator.SpecialFields.DirtyNumber;
+import eu.equalparts.cardbase.comparator.SpecialFields.Rarity;
 
 public class Card {
 	
 	public String name;
 	public String layout;
-	@ManaCost
 	public String manaCost;
 	public Integer cmc;
 	public String type;
+	@Rarity
 	public String rarity;
 	public String text;
 	public String flavor;
 	public String artist;
+	@DirtyNumber
 	public String number;
+	@DirtyNumber
 	public String power;
+	@DirtyNumber
 	public String toughness;
 	public Integer loyalty;
 	public Integer multiverseid;
-- 
cgit v1.2.3