package pdp.scrabble.game.impl;
import java.util.List;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import org.jdom.Element;
import pdp.scrabble.utility.Display;
import pdp.scrabble.utility.Tool;
import pdp.scrabble.game.Bag;
import pdp.scrabble.game.GameEnvironment;
import pdp.scrabble.game.Letter;
import pdp.scrabble.game.BagConfiguration;
import static pdp.scrabble.Factory.FACTORY;
import static pdp.scrabble.game.BagConfiguration.CONFIGURATION_PATH;
public class BagImpl implements Bag {
/** Configuration, containing letters data (occurences, values). */
private List<BagConfiguration> configuration = null;
/** Letters in the bag (bag map). */
private List<Letter> letters = null;
public BagImpl() {
this.letters = new ArrayList<Letter>(MAXIMUM_LETTERS);
// this.available = new boolean[MAXIMUM_LETTERS];
this.configuration = new ArrayList<BagConfiguration>(16);
// this.remaining = 0;
}
public void initWithLanguage(String language) {
this.configuration.clear();
this.loadConfiguration(language);
}
private void loadConfiguration(String filename) {
String filepath = new StringBuilder(
CONFIGURATION_PATH).append(filename).append(".txt").toString();
try {
BufferedReader file = new BufferedReader(new FileReader(filepath));
String line = null;
line = file.readLine();
while (line != null) {
this.configuration.add(BagConfiguration.decode(line));
line = file.readLine();
}
file.close();
}
catch (FileNotFoundException e) {
Display.error("Load letters", "File not found:", " " + filepath);
}
catch (IOException e) {
Display.error("Load letters", "Can't read datas:", " " + filepath);
}
}
public void fill() {
Iterator<BagConfiguration> itr = this.configuration.iterator();
int id = 0;
while (itr.hasNext()) {
BagConfiguration current = itr.next();
String name = current.getName();
int value = current.getValue();
int number = current.getNumber();
for (int i = 0; i < number; i++) {
this.addLetter(FACTORY.createLetter(name.charAt(0), value, id));
id++;
}
}
}
public int getWordValue(String word) {
int value = 0;
int len = word.length();
for (int i = 0; i < len; i++) {
value += this.getLetterValue(String.valueOf(word.charAt(i)));
}
return value;
}
public int getLetterValue(String letter) {
Iterator<BagConfiguration> itr = this.configuration.iterator();
while (itr.hasNext()) {
BagConfiguration current = itr.next();
String name = current.getName();
int value = current.getValue();
if (letter.equals(name)) {
return value;
}
}
return 0;
}
public void clear() {
this.letters.clear();
}
public boolean isEmpty() {
return this.letters.isEmpty();
}
public void addLetter(Letter letter) {
this.letters.add(letter);
}
public Letter getRandomLetter() {
if(this.isEmpty()){
// No letters available, bag is empty
return null;
}
// Random index in ArrayList
int index = Tool.random(0, this.letters.size()-1);
// Get a letter
Letter letter = this.letters.get(index);
// Remove letter from bag
this.letters.remove(index);
// Return letter
return letter;
}
public int getOriginalNumberOf(Character lName) {
return this.configuration.get(Tool.getNumericValue(lName)).getNumber();
}
public void save(Element root) {
Element element = new Element("Bag");
root.addContent(element);
if (!this.isEmpty()) {
for (int i = 0; i < this.letters.size(); i++) {
this.letters.get(i).save(element);
}
}
}
public void load(Element root) {
this.clear();
Element element = root.getChild("Bag");
@SuppressWarnings("unchecked")
Iterator<Element> Eletters = (element.getChildren()).iterator();
while (Eletters.hasNext()) {
Element Eletter = Eletters.next();
Letter letter = FACTORY.createLetter(' ', 0, 0);
letter.load(Eletter);
this.letters.add(letter);
}
}
public int getRemainingLettersNumber() {
return this.letters.size();
}
public BagImpl clone() {
BagImpl clone = null;
try {
clone = (BagImpl) super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
clone.letters = new ArrayList<Letter>(MAXIMUM_LETTERS);
for (Letter l : this.letters)
clone.letters.add(l.clone());
return clone;
}
}