/**
* 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.HashSet;
import java.util.Set;
import java.util.logging.Logger;
import net.sf.freecol.common.model.Colony.ColonyChangeEvent;
/**
* Helper container to remember a unit state prior to some change,
* and fire off any consequent property changes.
*/
public class UnitWas {
private static final Logger logger = Logger.getLogger(UnitWas.class.getName());
private Unit unit;
private UnitType type;
private Unit.Role role;
private Location loc;
private GoodsType work;
private int workAmount;
private Colony colony;
private GoodsContainer goodsContainer;
private TypeCountMap<EquipmentType> equipment;
/**
* Main constructor.
*
* @param unit The <code>Unit</code> to check changes to.
*/
public UnitWas(Unit unit) {
this.unit = unit;
this.type = unit.getType();
this.role = unit.getRole();
this.loc = unit.getLocation();
this.work = unit.getWorkType();
this.workAmount = getAmount(loc, work);
this.colony = unit.getColony();
this.equipment = new TypeCountMap<EquipmentType>();
this.equipment.add(unit.getEquipment());
if (unit.getGoodsContainer() != null) {
unit.getGoodsContainer().saveState();
}
}
/**
* Fire any property changes resulting from actions of a unit.
*/
public void fireChanges() {
UnitType newType = null;
Unit.Role newRole = null;
Location newLoc = null;
GoodsType newWork = null;
int newWorkAmount = 0;
TypeCountMap<EquipmentType> newEquipment = null;
if (!unit.isDisposed()) {
newLoc = unit.getLocation();
if (colony != null) {
newType = unit.getType();
newRole = unit.getRole();
newWork = unit.getWorkType();
newWorkAmount = (newWork == null) ? 0
: getAmount(newLoc, newWork);
newEquipment = unit.getEquipment();
}
}
if (loc != newLoc) {
FreeColGameObject oldFcgo = (FreeColGameObject) loc;
oldFcgo.firePropertyChange(change(oldFcgo), unit, null);
if (newLoc != null) {
FreeColGameObject newFcgo = (FreeColGameObject) newLoc;
newFcgo.firePropertyChange(change(newFcgo), null, unit);
}
}
if (colony != null) {
if (type != newType && newType != null) {
String pc = ColonyChangeEvent.UNIT_TYPE_CHANGE.toString();
colony.firePropertyChange(pc, type, newType);
} else if (role != newRole && newRole != null) {
String pc = Tile.UNIT_CHANGE.toString();
colony.firePropertyChange(pc, role.toString(),
newRole.toString());
}
if (work == newWork) {
if (work != null && workAmount != newWorkAmount) {
colony.firePropertyChange(work.getId(),
workAmount, newWorkAmount);
}
} else {
if (work != null) {
colony.firePropertyChange(work.getId(), workAmount, 0);
}
if (newWork != null) {
colony.firePropertyChange(newWork.getId(),
0, newWorkAmount);
}
}
}
if (newEquipment != null) {
Set<EquipmentType> keys = new HashSet<EquipmentType>();
keys.addAll(equipment.keySet());
keys.addAll(newEquipment.keySet());
for (EquipmentType e : keys) {
int cOld = equipment.getCount(e);
int cNew = newEquipment.getCount(e);
if (cOld != cNew) {
unit.firePropertyChange(Unit.EQUIPMENT_CHANGE, cOld, cNew);
}
}
}
if (unit.getGoodsContainer() != null) {
unit.getGoodsContainer().fireChanges();
}
}
// TODO: fix this non-OO nastiness
private String change(FreeColGameObject fcgo) {
return (fcgo instanceof Tile) ? Tile.UNIT_CHANGE
: (fcgo instanceof Europe) ? Europe.UNIT_CHANGE
: (fcgo instanceof ColonyTile) ? ColonyTile.UNIT_CHANGE
: (fcgo instanceof Building) ? Building.UNIT_CHANGE
: (fcgo instanceof Unit) ? Unit.CARGO_CHANGE
: null;
}
// TODO: fix this non-OO nastiness
private int getAmount(Location location, GoodsType goodsType) {
if (goodsType != null) {
if (location instanceof Building) {
Building building = (Building) location;
ProductionInfo info = building.getProductionInfo();
return (info == null || info.getProduction() == null
|| info.getProduction().size() == 0) ? 0
: info.getProduction().get(0).getAmount();
} else if (location instanceof ColonyTile) {
return ((ColonyTile)location).getProductionOf(goodsType);
}
}
return 0;
}
public Unit getUnit() {
return unit;
}
public Location getLocation() {
return loc;
}
public GoodsType getWorkType() {
return work;
}
public String toString() {
Tile tile = colony.getTile();
String eqStr = "/";
for (EquipmentType e : equipment.keySet()) {
eqStr += e.toString().substring(16, 17);
}
String locStr = (loc == null) ? ""
: (loc instanceof Building)
? ((Building)loc).getType().toString().substring(15)
: (loc instanceof ColonyTile)
? tile.getDirection(((ColonyTile)loc).getWorkTile()).toString()
: (loc instanceof Tile)
? (loc.getId() + eqStr)
: loc.getId();
Location newLoc = unit.getLocation();
String newEqStr = "/";
for (EquipmentType e : unit.getEquipment().keySet()) {
newEqStr += e.toString().substring(16, 17);
}
String newLocStr = (newLoc == null) ? ""
: (newLoc instanceof Building)
? ((Building)newLoc).getType().toString().substring(15)
: (newLoc instanceof ColonyTile)
? tile.getDirection(((ColonyTile)newLoc).getWorkTile()).toString()
: (newLoc instanceof Tile)
? (newLoc.getId() + newEqStr)
: newLoc.getId();
GoodsType newWork = unit.getWorkType();
int newWorkAmount = (newWork == null) ? 0 : getAmount(newLoc, newWork);
return String.format("%-30s %-25s -> %-25s",
unit.getId() + ":" + unit.getType().toString().substring(11),
locStr + ((work == null || workAmount <= 0) ? "" : "("
+ Integer.toString(workAmount) + " "
+ work.toString().substring(12) + ")"),
newLocStr + ((newWork == null || newWorkAmount <= 0) ? "" : "("
+ Integer.toString(newWorkAmount) + " "
+ newWork.toString().substring(12) + ")"));
}
}