/** * Copyright (C) 2002-2012 The FreeCol Team * * This file is part of FreeCol. * * FreeCol is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * FreeCol is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with FreeCol. If not, see <http://www.gnu.org/licenses/>. */ package net.sf.freecol.common.model; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import net.sf.freecol.common.model.Unit.Role; import net.sf.freecol.common.option.BooleanOption; import net.sf.freecol.common.option.OptionGroup; import org.freecolandroid.xml.stream.XMLStreamException; import org.freecolandroid.xml.stream.XMLStreamReader; import org.freecolandroid.xml.stream.XMLStreamWriter; /** * Represents one of the European nations present in the game, * i.e. both REFs and possible human players. */ public class EuropeanNationType extends NationType { /** * Whether this is an REF Nation. */ private boolean ref = false; /** * Stores the starting units of this Nation. */ private List<AbstractUnit> startingUnits; /** * Stores the starting units of this Nation at various * difficulties. */ private Map<String, Map<String, AbstractUnit>> startingUnitMap = new HashMap<String, Map<String, AbstractUnit>>(); public EuropeanNationType(String id, Specification specification) { super(id, specification); } /** * Get the <code>REF</code> value. * * @return a <code>boolean</code> value */ public final boolean isREF() { return ref; } /** * Set the <code>REF</code> value. * * @param newREF The new REF value. */ public final void setREF(final boolean newREF) { this.ref = newREF; } /** * Returns true. * * @return a <code>boolean</code> value */ public boolean isEuropean() { return true; } /** * Returns false. * * @return a <code>boolean</code> value */ public boolean isIndian() { return false; } /** * Returns a list of this Nation's starting units. * * @return a list of this Nation's starting units. */ public List<AbstractUnit> getStartingUnits() { return startingUnits; } /** * Returns a list of this Nation's starting units at the given * difficulty. * * @param key the value of the expert-starting-units field * @return a list of this Nation's starting units. */ public List<AbstractUnit> getStartingUnits(String key) { Map<String, AbstractUnit> result = new HashMap<String, AbstractUnit>(); Map<String, AbstractUnit> defaultMap = startingUnitMap.get(null); Map<String, AbstractUnit> difficultyMap = startingUnitMap.get(key); if (defaultMap != null) { result.putAll(defaultMap); } if (difficultyMap != null) { result.putAll(difficultyMap); } return new ArrayList<AbstractUnit>(result.values()); } /** * Applies the difficulty level to this nation type. * * @param difficulty difficulty level to apply */ @Override public void applyDifficultyLevel(OptionGroup difficulty) { String experts = Boolean.toString(((BooleanOption) difficulty.getOption("model.option.expertStartingUnits")) .getValue()); startingUnits = getStartingUnits(experts); } /** * Makes an XML-representation of this object. * * @param out The output stream. * @throws XMLStreamException if there are any problems writing to the * stream. */ public void toXMLImpl(XMLStreamWriter out) throws XMLStreamException { super.toXML(out, getXMLElementTagName()); } /** * Write the attributes of this object to a stream. * * @param out The target stream. * @throws XMLStreamException if there are any problems writing to * the stream. */ @Override public void writeAttributes(XMLStreamWriter out) throws XMLStreamException { super.writeAttributes(out); out.writeAttribute("ref", Boolean.toString(ref)); } /** * Write the children of this object to a stream. * * @param out The target stream. * @throws XMLStreamException if there are any problems writing to * the stream. */ @Override protected void writeChildren(XMLStreamWriter out) throws XMLStreamException { super.writeChildren(out); if (startingUnitMap != null && !startingUnitMap.isEmpty()) { // default map for (Map.Entry<String, AbstractUnit> entry : startingUnitMap.get(null).entrySet()) { writeUnit(out, entry.getKey(), entry.getValue(), false); } // expert map for (Map.Entry<String, AbstractUnit> entry : startingUnitMap.get("true").entrySet()) { writeUnit(out, entry.getKey(), entry.getValue(), true); } } } private void writeUnit(XMLStreamWriter out, String id, AbstractUnit unit, boolean expert) throws XMLStreamException { out.writeStartElement("unit"); out.writeAttribute(ID_ATTRIBUTE_TAG, id); out.writeAttribute("type", unit.getId()); out.writeAttribute("role", unit.getRole().toString().toLowerCase(Locale.US)); //out.writeAttribute("number", String.valueOf(unit.getNumber())); if (expert) { out.writeAttribute("expert-starting-units", "true"); } out.writeEndElement(); } /** * Reads the attributes of this object from an XML stream. * * @param in The XML input stream. * @throws XMLStreamException if a problem was encountered * during parsing. */ @Override protected void readAttributes(XMLStreamReader in) throws XMLStreamException { super.readAttributes(in); String extendString = in.getAttributeValue(null, "extends"); EuropeanNationType parent = (extendString == null) ? this : (EuropeanNationType) getSpecification().getNationType(extendString); ref = getAttribute(in, "ref", parent.ref); if (parent != this) { for (Map.Entry<String,Map<String, AbstractUnit>> entry : parent.startingUnitMap.entrySet()) { startingUnitMap.put(entry.getKey(), new HashMap<String, AbstractUnit>(entry.getValue())); } } } /** * Reads a child object. * * @param in The XML stream to read. * @exception XMLStreamException if an error occurs */ @Override protected void readChild(XMLStreamReader in) throws XMLStreamException { String childName = in.getLocalName(); if ("unit".equals(childName)) { String id = in.getAttributeValue(null, ID_ATTRIBUTE_TAG); String type = in.getAttributeValue(null, "type"); Role role = Enum.valueOf(Role.class, getAttribute(in, "role", "default").toUpperCase(Locale.US)); String useExperts = in.getAttributeValue(null, "expert-starting-units"); AbstractUnit unit = new AbstractUnit(type, role, 1); Map<String, AbstractUnit> units = startingUnitMap.get(useExperts); if (units == null) { units = new HashMap<String, AbstractUnit>(); startingUnitMap.put(useExperts, units); } units.put(id, unit); in.nextTag(); } else { super.readChild(in); } } /** * Returns the tag name of the root element representing this object. * * @return "european-nation-type". */ public static String getXMLElementTagName() { return "european-nation-type"; } }