/**
* 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.client.gui.panel;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JSeparator;
import net.miginfocom.swing.MigLayout;
import net.sf.freecol.client.FreeColClient;
import net.sf.freecol.client.gui.GUI;
import net.sf.freecol.client.gui.i18n.Messages;
import net.sf.freecol.common.model.Colony;
import net.sf.freecol.common.model.Europe;
import net.sf.freecol.common.model.Goods;
import net.sf.freecol.common.model.Location;
import net.sf.freecol.common.model.Player;
import net.sf.freecol.common.model.StringTemplate;
import net.sf.freecol.common.model.TypeCountMap;
import net.sf.freecol.common.model.Unit;
import net.sf.freecol.common.model.UnitType;
/**
* This panel displays a unit Report.
*/
public abstract class ReportUnitPanel extends ReportPanel {
/**
* Units in Europe.
*/
private List<Unit> inEurope = new ArrayList<Unit>();
/**
* Units in colonies.
*/
private Map<Colony, List<Unit>> inColonies
= new HashMap<Colony, List<Unit>>();
/**
* Units in other locations.
*/
private Map<String, List<Unit>> inLocations
= new HashMap<String, List<Unit>>();
/**
* Records the number of units of each type.
*/
private Map<String, TypeCountMap<UnitType>> units
= new HashMap<String, TypeCountMap<UnitType>>();
/**
* Whether to show colonies even if no selected units are present.
*/
private boolean showColonies = false;
protected Player player = getMyPlayer();
/**
* The constructor that will add the items to this panel.
* @param freeColClient the FreeColClient
* @param gui the GUI
* @param key the report name key
* @param showColonies whether to show colonies with no selected units
*/
public ReportUnitPanel(FreeColClient freeColClient, GUI gui, String key, boolean showColonies) {
super(freeColClient, gui, Messages.message(key));
this.showColonies = showColonies;
reportPanel.setLayout(new MigLayout("fillx, wrap 12", "", ""));
gatherData();
addREFUnits();
addOwnUnits();
reportPanel.add(new JSeparator(JSeparator.HORIZONTAL), "newline, span, growx, wrap 40");
// colonies first, sorted according to user preferences
for (Colony colony : getSortedColonies()) {
handleLocation(colony, colony.getName(), inColonies.get(colony));
}
// Europe next
Europe europe = player.getEurope();
if (europe != null) {
handleLocation(europe, Messages.message(europe.getNameKey()), inEurope);
}
// finally all other locations, sorted alphabetically
List<String> otherNames = new ArrayList<String>(inLocations.keySet());
Collections.sort(otherNames);
for (String locationName : otherNames) {
handleLocation(null, locationName, inLocations.get(locationName));
}
revalidate();
repaint();
}
protected int getCount(String key, UnitType type) {
TypeCountMap<UnitType> map = units.get(key);
if (map == null) {
return 0;
} else {
return map.getCount(type);
}
}
protected void incrementCount(String key, UnitType type, int number) {
TypeCountMap<UnitType> map = units.get(key);
if (map == null) {
map = new TypeCountMap<UnitType>();
units.put(key, map);
}
map.incrementCount(type, number);
}
protected void addUnit(Unit unit, String key) {
if (unit.getLocation() == null) {
// this should never happen
return;
} else if (unit.isInEurope()) {
inEurope.add(unit);
} else {
Colony colony = unit.getLocation().getColony();
if (colony == null) {
String locationName = getLocationNameFor(unit);
List<Unit> unitList = inLocations.get(locationName);
if (unitList == null) {
unitList = new ArrayList<Unit>();
inLocations.put(locationName, unitList);
}
unitList.add(unit);
} else {
List<Unit> unitList = inColonies.get(colony);
if (unitList == null) {
unitList = new ArrayList<Unit>();
inColonies.put(colony, unitList);
}
unitList.add(unit);
}
}
incrementCount(key, unit.getType(), 1);
}
protected abstract void gatherData();
protected abstract void addREFUnits();
protected abstract void addOwnUnits();
protected void handleLocation(Location location, String locationName, List<Unit> unitList) {
if ((unitList == null || unitList.isEmpty()) && !showColonies) {
return;
}
JComponent component;
if (location == null) {
component = new JLabel(locationName);
} else {
JButton button = getLinkButton(locationName, null, location.getId());
button.addActionListener(this);
component = button;
}
reportPanel.add(component, "newline, span, split 2");
reportPanel.add(new JSeparator(JSeparator.HORIZONTAL), "growx");
if (unitList == null || unitList.isEmpty()) {
reportPanel.add(new JLabel(Messages.message("none")), "sg");
} else {
Collections.sort(unitList, ReportPanel.getUnitTypeComparator());
for (Unit unit : unitList) {
JButton unitButton = getUnitButton(unit);
if (unit.isCarrier()) {
reportPanel.add(unitButton, "newline, sg");
for (Goods goods : unit.getGoodsList()) {
GoodsLabel goodsLabel = new GoodsLabel(goods, getGUI());
reportPanel.add(goodsLabel);
}
for (Unit unitLoaded : unit.getUnitList()) {
UnitLabel unitLoadedLabel = new UnitLabel(getFreeColClient(), unitLoaded, getGUI(), true);
reportPanel.add(unitLoadedLabel);
}
} else {
reportPanel.add(unitButton, "sg");
}
}
}
}
protected JButton getUnitButton(Unit unit) {
ImageIcon icon = getLibrary().getUnitImageIcon(unit.getType(), unit.getRole());
JButton button = getLinkButton("", icon, unit.getLocation().getId());
button.addActionListener(this);
String toolTip = Messages.message(Messages.getLabel(unit));
if (unit.getDestination() != null) {
String type = unit.isPerson()
? "person"
: unit.isNaval()
? "ship"
: "other";
toolTip += "\n"
+ Messages.message(StringTemplate.template("goingTo")
.addName("%type%", type)
.addStringTemplate("%location%", unit.getDestination()
.getLocationNameFor(getMyPlayer())));
}
button.setToolTipText(toolTip);
return button;
}
@Override
public Dimension getMinimumSize() {
return new Dimension(750, 600);
}
@Override
public Dimension getPreferredSize() {
return getMinimumSize();
}
}