/**
* 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.Iterator;
import java.util.List;
import java.util.logging.Logger;
import org.freecolandroid.xml.stream.XMLStreamException;
import org.freecolandroid.xml.stream.XMLStreamReader;
import org.freecolandroid.xml.stream.XMLStreamWriter;
/**
* The <code>GoodsLocation</code> is a place where {@link Unit}s and
* {@link Goods} can be put. The GoodsLocation can not store any other
* Locatables, such as {@link TileItem}s.
*
* @see Locatable
*/
public abstract class GoodsLocation extends UnitLocation {
private static final Logger logger = Logger.getLogger(GoodsLocation.class.getName());
/**
* Describe goodsContainer here.
*/
private GoodsContainer goodsContainer;
protected GoodsLocation() {
// empty constructor
}
/**
* Creates a new <code>GoodsLocation</code> instance.
*
* @param game a <code>Game</code> value
*/
public GoodsLocation(Game game) {
super(game);
}
/**
* Creates a new <code>GoodsLocation</code> instance.
*
* @param game a <code>Game</code> value
* @param in a <code>XMLStreamReader</code> value
* @exception XMLStreamException if an error occurs
*/
public GoodsLocation(Game game, XMLStreamReader in) throws XMLStreamException {
super(game, in);
}
/**
* Creates a new <code>GoodsLocation</code> instance.
*
* @param game a <code>Game</code> value
* @param id a <code>String</code> value
*/
public GoodsLocation(Game game, String id) {
super(game, id);
}
/**
* Gets the maximum number of <code>Goods</code> this Location
* can hold.
*
* @return the capacity for goods
*/
public abstract int getGoodsCapacity();
/**
* Gets an <code>Iterator</code> of every <code>Goods</code> in this
* <code>GoodsContainer</code>. Each <code>Goods</code> have a maximum
* amount of GoodsContainer.CARGO_SIZE.
*
* @return The <code>Iterator</code>.
*/
public Iterator<Goods> getGoodsIterator() {
return goodsContainer.getGoodsIterator();
}
/**
* Gets an <code>List</code> with every <code>Goods</code> in this
* <code>Colony</code>. There is only one <code>Goods</code> for each
* type of goods.
*
* @return The <code>Iterator</code>.
*/
public List<Goods> getCompactGoods() {
return goodsContainer.getCompactGoods();
}
/**
* Gets the reason why a given <code>Locatable</code> can not be
* added to this Location.
*
* @param locatable The <code>Locatable</code> to test.
* @return The reason why adding would fail.
*/
public NoAddReason getNoAddReason(Locatable locatable) {
if (locatable instanceof Goods) {
// WARNING: Goods can always be added to settlements. Any
// excess Goods will be removed during end-of-turn
// processing. If Units should inherit from GoodsLocation,
// this needs to be changed.
return NoAddReason.NONE;
} else {
return super.getNoAddReason(locatable);
}
}
/**
* Adds a <code>Locatable</code> to this Location.
*
* @param locatable
* The <code>Locatable</code> to add to this Location.
*/
@Override
public boolean add(Locatable locatable) {
if (locatable instanceof Goods) {
return addGoods((Goods) locatable);
} else {
return super.add(locatable);
}
}
/**
* Removes a <code>Locatable</code> from this Location.
*
* @param locatable
* The <code>Locatable</code> to remove from this Location.
*/
public boolean remove(Locatable locatable) {
if (locatable instanceof Goods) {
return removeGoods((Goods) locatable) != null;
} else {
return super.remove(locatable);
}
}
/**
* Checks if this <code>Location</code> contains the specified
* <code>Locatable</code>.
*
* @param locatable
* The <code>Locatable</code> to test the presence of.
* @return
* <ul>
* <li><i>true</i> if the specified <code>Locatable</code> is
* on this <code>Location</code> and
* <li><i>false</i> otherwise.
* </ul>
*/
public boolean contains(Locatable locatable) {
if (locatable instanceof Goods) {
return goodsContainer.contains((Goods) locatable);
} else {
return super.contains(locatable);
}
}
/**
* Gets the <code>GoodsContainer</code> this <code>Location</code>
* use for storing it's goods, or <code>null</code> if the
* <code>Location</code> cannot store any goods.
*
* @return A <code>GoodsContainer</code> value
*/
public final GoodsContainer getGoodsContainer() {
return goodsContainer;
}
/**
* Set the <code>GoodsContainer</code> value.
*
* @param newGoodsContainer The new GoodsContainer value.
*/
public final void setGoodsContainer(final GoodsContainer newGoodsContainer) {
this.goodsContainer = newGoodsContainer;
}
/**
* Gets the storage capacity of this settlement.
*
* @return The storage capacity of this settlement.
* @see #getGoodsCapacity
*/
public int getWarehouseCapacity() {
return getGoodsCapacity();
}
/**
* Removes a specified amount of a type of Goods from this Settlement.
*
* @param type The type of Goods to remove from this settlement.
* @param amount The amount of Goods to remove from this settlement.
*/
public Goods removeGoods(GoodsType type, int amount) {
return goodsContainer.removeGoods(type, amount);
}
/**
* Removes the given Goods from the Settlement.
*
* @param goods a <code>Goods</code> value
*/
public Goods removeGoods(AbstractGoods goods) {
return goodsContainer.removeGoods(goods);
}
/**
* Removes all Goods of the given type from the Settlement.
*
* @param type a <code>GoodsType</code> value
*/
public Goods removeGoods(GoodsType type) {
return goodsContainer.removeGoods(type);
}
/**
* Describe <code>addGoods</code> method here.
*
* @param type a <code>GoodsType</code> value
* @param amount an <code>int</code> value
*/
public boolean addGoods(GoodsType type, int amount) {
return goodsContainer.addGoods(type, amount);
}
/**
* Describe <code>addGoods</code> method here.
*
* @param goods an <code>AbstractGoods</code> value
*/
public boolean addGoods(AbstractGoods goods) {
return addGoods(goods.getType(), goods.getAmount());
}
/**
* Gets the amount of one type of Goods at this Settlement.
*
* @param type The type of goods to look for.
* @return The amount of this type of Goods at this Location.
*/
public int getGoodsCount(GoodsType type) {
return goodsContainer.getGoodsCount(type);
}
/**
* Removes all references to this object.
*
* @return A list of disposed objects.
*/
public List<FreeColGameObject> disposeList() {
List<FreeColGameObject> objects = new ArrayList<FreeColGameObject>();
if (goodsContainer != null) {
objects.addAll(goodsContainer.disposeList());
goodsContainer = null;
}
objects.addAll(super.disposeList());
return objects;
}
/**
* Dispose of this GoodsLocation.
*/
public void dispose() {
disposeList();
}
/**
* {@inheritDoc}
*/
protected void writeChildren(XMLStreamWriter out, Player player,
boolean showAll, boolean toSavedGame)
throws XMLStreamException {
super.writeChildren(out, player, showAll, toSavedGame);
if (goodsContainer != null) {
goodsContainer.toXML(out, player, showAll, toSavedGame);
}
}
/**
* {@inheritDoc}
*/
protected void readChild(XMLStreamReader in) throws XMLStreamException {
if (GoodsContainer.getXMLElementTagName().equals(in.getLocalName())) {
goodsContainer = (GoodsContainer) getGame().getFreeColGameObject(in.getAttributeValue(null, ID_ATTRIBUTE));
if (goodsContainer == null) {
goodsContainer = new GoodsContainer(getGame(), this, in);
} else {
goodsContainer.readFromXML(in);
}
} else {
super.readChild(in);
}
}
}