aboutsummaryrefslogtreecommitdiffstats
path: root/src/eu/equalparts/cardbase/Cardbase.java
blob: 9251d4cb1d7d42d8e2e980cb43c7412655b63da6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package eu.equalparts.cardbase;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;

import eu.equalparts.cardbase.data.Card;
import eu.equalparts.cardbase.utils.JSON;

/**
 * Provides a variety of utility methods to interact with the loaded cardbase.
 * 
 * @author Eduardo Pedroni
 */
public class Cardbase {
	
	/**
	 * The cards in the cardbase, set in key-value pairs where the key is the card hash,
	 * generated using {makeHash()}.
	 */
	private Map<String, Card> cards;
	/**
	 * Debug flag is raised when the DEBUG environment variable is set. This causes additional
	 * information to be printed to the console.
	 */
	public static final boolean DEBUG = System.getenv("CB_DEBUG") != null; 
	
	/**
	 * Creates an empty cardbase.
	 */
	public Cardbase() {
		cards = new HashMap<String, Card>();
	}
	
	/**
	 * Initialises the cardbase with the contents of a file.
	 *
	 * @param cardbaseFile the cardbase JSON to load.
	 * 
	 * @throws JsonParseException if the specified file does not contain valid JSON.
	 * @throws JsonMappingException if the specified file structure does not match that of {@code Cardbase}.
	 * @throws IOException if a low-level I/O problem (unexpected end-of-input, network error) occurs.
	 */
	public Cardbase(File cardbaseFile) throws JsonParseException, JsonMappingException, IOException {
		cards = JSON.mapper.readValue(cardbaseFile, new TypeReference<Map<String, Card>>() {});
	}

	/**
	 * Writes the provided {@code Cardbase} to the provided file in JSON format.
	 * 
	 * @param file the file to which to write the {@code Cardbase}.
	 * @param cardbase the {@code Cardbase} to write out.
	 * 
	 * @throws JsonGenerationException if the data structure given does not generate valid JSON.
	 * @throws JsonMappingException if the data structure given does not generate valid JSON as well?
	 * @throws IOException if a low-level I/O problem (unexpected end-of-input, network error) occurs.
	 */
	public void writeCardbase(File outputFile) throws JsonGenerationException, JsonMappingException, IOException {
		JSON.mapper.writeValue(outputFile, cards);
	}

	/**
	 * Adds 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.
	 * 
	 * @param cardToAdd the card to be added.
	 * @param count the amount of the card to be added.
	 */
	public void addCard(Card cardToAdd, Integer count) {
		Card card = getCard(cardToAdd.setCode, cardToAdd.number);
		if (card != null) {
			card.count += count;
		} else {
			cardToAdd.count = count;
			cards.put(makeHash(cardToAdd), cardToAdd);
		}
	}

	/**
	 * Removes a specific amount of a card from the cardbase.
	 * If the card is not present in the cardbase, nothing happens.
	 * If the card is present in the cardbase, the specified amount is removed.
	 * If that amount is equal to or exceeds the count already in the cardbase,
	 * the card entry is removed altogether.
	 * <br><br>
	 * In any case, the value returned is the actual number of cards removed.
	 * For example, if 5 Shivan Dragons are in the cardbase and the method is
	 * called to remove 10 Shivan Dragons, the {@code Card} representing the
	 * Shivan Dragon is removed from the cardbase, and the value returned is 5.
	 * 
	 * @param cardToRemove the card to be removed.
	 * @param count the amount of the card to be removed.
	 * @return the number of cards actually removed.
	 */
	public Integer removeCard(Card cardToRemove, Integer count) {
		Card card = getCard(cardToRemove.setCode, cardToRemove.number);
		Integer removed = 0;
		if (card != null) {
			if (card.count <= count) {
				cards.remove(makeHash(card));
				removed = card.count;
			} else {
				card.count -= count;
				removed = count;
			}
		}
		return removed;
	}

	/**
	 * This method is intended to allow iteration directly on the list of cards,
	 * while at the same time retaining control over the insert and remove procedures.
	 * The returned {@code List} is a read-only; trying to modify its structure will
	 * result in an {@code UnsupportedOperationException}.
	 * 
	 * @return an unmodifiable list of all the cards in the cardbase.
	 */
	public Collection<Card> getCards() {
		return Collections.unmodifiableCollection(cards.values());
	}
	
	/**
	 * Returns a card from the cardbase by set code and number.
	 * If no such card is in the cardbase, returns null.
	 * 
	 * @param setCode the set to which the requested card belongs.
	 * @param number the requested card's set number.
	 * 
	 * @return the requested {@code Card} or null if no card is found.
	 */
	public Card getCard(String setCode, String number) {
		return cards.get(makeHash(setCode, number));
	}
	
	/**
	 * Generate the hash used as a key in the storage map.
	 * 
	 * @param setCode the card's set code.
	 * @param number the card's set number.
	 * @return the generated hash.
	 */
	private String makeHash(String setCode, String number) {
		return setCode + number;
	}
	
	/**
	 * Generate the hash used as a key in the storage map.
	 * 
	 * @param the {@code Card} whose hash is desired.
	 * @return the generated hash.
	 */
	private String makeHash(Card card) {
		return card.setCode + card.number;
	}
}