/*
* MegaMekLab - Copyright (C) 2010
*
* Original author - jtighe (torren@users.sourceforge.net)
*
* This program 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.
*
* This program 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.
*/
package megameklab.com.util;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Vector;
import megamek.common.Aero;
import megamek.common.AmmoType;
import megamek.common.Bay;
import megamek.common.Entity;
import megamek.common.EntityMovementMode;
import megamek.common.FixedWingSupport;
import megamek.common.MiscType;
import megamek.common.Mounted;
import megamek.common.SmallCraft;
import megamek.common.TechConstants;
public class ImageHelperAero {
private static final String[] LOCATION_ABBRS =
{ "N", "LW", "RW", "A", "WG", "BD" };
private static String[] LOCATION_ABBRS_SMALLCRAFT =
{ "N", "LS", "RS", "A" };
public static String getLocationAbbrs(int pos) {
return LOCATION_ABBRS[pos];
}
public static String getLocationAbbrsSmallCraft(int pos) {
return LOCATION_ABBRS_SMALLCRAFT[pos];
}
public static void drawAeroArmorPip(Graphics2D g2d, float width, float height) {
ImageHelperAero.drawAeroArmorPip(g2d, width, height, 9.0f);
}
public static void drawAeroArmorPip(Graphics2D g2d, float width, float height, float fontsize) {
Font font = new Font("Arial", Font.PLAIN, 9);
font = font.deriveFont(fontsize);
g2d.setFont(font);
g2d.setColor(Color.BLACK);
g2d.setBackground(Color.WHITE);
g2d.drawString("O", width, height);
}
public static void drawAeroISPip(Graphics2D g2d, int width, int height) {
Dimension circle = new Dimension(6, 6);
Dimension fillCircle = new Dimension(4, 4);
g2d.setColor(Color.black);
g2d.fillOval(width, height, circle.width, circle.height);
g2d.setColor(Color.white);
g2d.fillOval(width + 1, height + 1, fillCircle.width, fillCircle.height);
}
public static void printAeroFuel(Aero aero, Graphics2D g2d) {
printAeroFuel(aero, g2d, 0);
}
public static void printAeroFuel(Aero aero, Graphics2D g2d, int xoffset) {
int pointY = 330;
int pointX = 22 + xoffset;
String fuel = "Fuel: ";
g2d.setFont(UnitUtil.getNewFont(g2d, fuel, false, 200, 7.0f));
g2d.drawString(fuel, pointX, pointY);
pointX += ImageHelper.getStringWidth(g2d, fuel, g2d.getFont());
String fuelAmount = String.format("%1$s Points", aero.getFuel());
g2d.setFont(UnitUtil.getNewFont(g2d, fuelAmount, false, 200, 7.0f));
g2d.drawString(fuelAmount, pointX, pointY);
}
public static void printAeroWeaponsNEquipment(Aero aero, Graphics2D g2d) {
int pointShift = 0;
if ((aero instanceof SmallCraft) && aero.isSpheroid()) {
pointShift = 11;
}
int qtyPoint = 30;
int typePoint = 42;
int locPoint = 112 + pointShift;
int heatPoint = 130 + pointShift;
int shtPoint = 147 + pointShift;
int medPoint = 170 + pointShift;
int longPoint = 190 + pointShift;
int erPoint = 210 + pointShift;
float linePoint = 204f;
float maxHeight = 97.0f;
float lineFeed = 6.7f;
boolean newLineNeeded = false;
ArrayList<Hashtable<String, EquipmentInfo>> equipmentLocations = new ArrayList<Hashtable<String, EquipmentInfo>>(aero.locations());
for (int pos = 0; pos <= aero.locations(); pos++) {
equipmentLocations.add(pos, new Hashtable<String, EquipmentInfo>());
}
for (Mounted eq : aero.getEquipment()) {
if ((eq.isWeaponGroup() || (eq.getType() instanceof AmmoType)) || (eq.getLocation() == Entity.LOC_NONE) || !UnitUtil.isPrintableEquipment(eq.getType())) {
continue;
}
Hashtable<String, EquipmentInfo> eqHash = equipmentLocations.get(eq.getLocation());
String equipmentName = eq.getName();
if (eq.isRearMounted()) {
equipmentName += "(R)";
}
if (eqHash.containsKey(equipmentName)) {
EquipmentInfo eqi = eqHash.get(equipmentName);
if (eq.getType().getTechLevel(aero.getTechLevelYear()) != eqi.techLevel) {
eqi = new EquipmentInfo(aero, eq);
} else {
eqi.count++;
}
eqHash.put(equipmentName, eqi);
} else {
EquipmentInfo eqi = new EquipmentInfo(aero, eq);
eqHash.put(equipmentName, eqi);
}
}
if (aero.getTroopCarryingSpace() > 0) {
maxHeight -= lineFeed;
}
if (aero.hasWorkingMisc(MiscType.F_CHASSIS_MODIFICATION)) {
maxHeight -= lineFeed;
}
if (aero.getCockpitType() != Aero.COCKPIT_STANDARD) {
maxHeight -= lineFeed;
}
for (@SuppressWarnings("unused")
Bay bay : aero.getTransportBays()) {
maxHeight -= lineFeed;
}
if (aero.getAmmo().size() > 0) {
maxHeight -= lineFeed;
}
g2d.setFont(UnitUtil.deriveFont(false, 7.0f));
Font font = ImageHelperAero.getAeroWeaponsNEquipmentFont(g2d, false, maxHeight, equipmentLocations, 7.0f);
g2d.setFont(font);
float stringHeight = ImageHelper.getStringHeight(g2d, "H", font);
lineFeed = stringHeight;
for (int pos = Aero.LOC_NOSE; pos <= aero.locations(); pos++) {
Hashtable<String, EquipmentInfo> eqHash = equipmentLocations.get(pos);
if (eqHash.size() < 1) {
continue;
}
ArrayList<EquipmentInfo> equipmentList = new ArrayList<EquipmentInfo>();
for (EquipmentInfo eqi : eqHash.values()) {
equipmentList.add(eqi);
}
Collections.sort(equipmentList, StringUtils.equipmentInfoComparator());
for (EquipmentInfo eqi : equipmentList) {
newLineNeeded = false;
g2d.setFont(font);
g2d.drawString(Integer.toString(eqi.count), qtyPoint, linePoint);
String name = eqi.name.trim() + " " + eqi.damage.trim();
/*if (ImageHelper.getStringWidth(g2d, name, font) > 65) {
g2d.setFont(UnitUtil.getNewFont(g2d, name, false, 65, font.getSize2D()));
}*/
if (eqi.c3Level == EquipmentInfo.C3I) {
ImageHelper.printC3iName(g2d, typePoint, linePoint, font, false, aero.isMixedTech() && TechConstants.isClan(aero.getTechLevel()));
} else if (eqi.c3Level == EquipmentInfo.C3EM) {
ImageHelper.printC3EmName(g2d, typePoint, linePoint, font, false, aero.isMixedTech() && TechConstants.isClan(aero.getTechLevel()));
} else if (eqi.c3Level == EquipmentInfo.C3S) {
ImageHelper.printC3sName(g2d, typePoint, linePoint, font, false, aero.isMixedTech() && TechConstants.isClan(aero.getTechLevel()));
} else if (eqi.c3Level == EquipmentInfo.C3M) {
ImageHelper.printC3mName(g2d, typePoint, linePoint, font, false, aero.isMixedTech() && TechConstants.isClan(aero.getTechLevel()));
} else if (eqi.c3Level == EquipmentInfo.C3SB) {
ImageHelper.printC3sbName(g2d, typePoint, linePoint, font, false, aero.isMixedTech() && TechConstants.isClan(aero.getTechLevel()));
} else if (eqi.c3Level == EquipmentInfo.C3MB) {
ImageHelper.printC3mbName(g2d, typePoint, linePoint, font, false, aero.isMixedTech() && TechConstants.isClan(aero.getTechLevel()));
} else if (eqi.c3Level == EquipmentInfo.C3REMOTESENSOR) {
ImageHelper.printC3RemoteSensorName(g2d, typePoint, linePoint, font, false, aero.isMixedTech() && TechConstants.isClan(aero.getTechLevel()));
} else if (eqi.isMashCore) {
ImageHelper.printMashCore(g2d, typePoint, linePoint, font, false, aero);
} else if (eqi.isDroneControl) {
ImageHelper.printDroneControl(g2d, typePoint, linePoint, font, false, aero);
} else {
if (ImageHelper.getStringWidth(g2d, name, font) > 65) {
// g2d.setFont(UnitUtil.getNewFont(g2d, eqi.name.trim(),
// false, 65, font.getSize2D()));
g2d.drawString(eqi.name.trim(), typePoint, linePoint);
linePoint += lineFeed;
g2d.drawString(eqi.damage.trim(), typePoint, linePoint);
} else {
g2d.drawString(name, typePoint, linePoint);
}
}
g2d.setFont(font);
String location = ImageHelperAero.getLocationAbbrs(pos);
if ((aero instanceof SmallCraft) && (aero.getMovementMode() == EntityMovementMode.SPHEROID)) {
location = ImageHelperAero.getLocationAbbrsSmallCraft(pos);
}
g2d.drawString(location, locPoint, linePoint);
ImageHelper.printCenterString(g2d, Integer.toString(eqi.heat), font, heatPoint, linePoint);
if (eqi.isMML) {
linePoint += lineFeed;
g2d.drawString("SRM Ammo", typePoint, linePoint);
g2d.drawString(Integer.toString(eqi.shtRange * 2 ), shtPoint, (int) linePoint);
g2d.drawString("\u2014", medPoint, linePoint);
g2d.drawString("\u2014", longPoint, linePoint);
g2d.drawString("\u2014", erPoint, linePoint);
//g2d.drawLine(medPoint, (int) linePoint - 2, medPoint + 6, (int) linePoint - 2);
//g2d.drawLine(longPoint, (int) linePoint - 2, longPoint + 6, (int) linePoint - 2);
//g2d.drawLine(erPoint, (int) linePoint - 2, erPoint + 6, (int) linePoint - 2);
linePoint += lineFeed;
g2d.drawString("LRM Ammo", typePoint, linePoint);
g2d.drawString(Integer.toString(eqi.shtRange), shtPoint, (int) linePoint);
g2d.drawString(Integer.toString(eqi.medRange), medPoint, (int) linePoint);
g2d.drawString(Integer.toString(eqi.longRange), longPoint, (int) linePoint);
g2d.drawString("\u2014", erPoint, linePoint);
//g2d.drawLine(erPoint, (int) linePoint - 2, erPoint + 6, (int) linePoint - 2);
} else if (eqi.shtRange > 0) {
g2d.drawString(Integer.toString(eqi.shtRange), shtPoint, (int) linePoint);
} else {
g2d.drawString("\u2014", shtPoint, linePoint);
//g2d.drawLine(shtPoint, (int) linePoint - 2, shtPoint + 6, (int) linePoint - 2);
}
if ((eqi.medRange > 0) && !eqi.isMML) {
g2d.drawString(Integer.toString(eqi.medRange), medPoint, (int) linePoint);
} else if (!eqi.isMML){
g2d.drawString("\u2014", medPoint, linePoint);
//g2d.drawLine(medPoint, (int) linePoint - 2, medPoint + 6, (int) linePoint - 2);
}
if ((eqi.longRange > 0) && !eqi.isMML) {
g2d.drawString(Integer.toString(eqi.longRange), longPoint, (int) linePoint);
} else if (!eqi.isMML) {
g2d.drawString("\u2014", longPoint, linePoint);
//g2d.drawLine(longPoint, (int) linePoint - 2, longPoint + 6, (int) linePoint - 2);
}
if ((eqi.erRange > 0) && !eqi.isMML) {
g2d.drawString(Integer.toString(eqi.erRange), erPoint, (int) linePoint);
} else if (!eqi.isMML) {
g2d.drawString("\u2014", erPoint, linePoint);
//g2d.drawLine(erPoint, (int) linePoint - 2, erPoint + 6, (int) linePoint - 2);
}
if (eqi.hasArtemis) {
g2d.drawString("w/Artemis IV FCS", typePoint, linePoint + lineFeed);
newLineNeeded = true;
} else if (eqi.hasArtemisV) {
g2d.drawString("w/Artemis V FCS", typePoint, linePoint + lineFeed);
newLineNeeded = true;
} else if (eqi.hasApollo) {
g2d.drawString("w/Apollo FCS", typePoint, linePoint + lineFeed);
newLineNeeded = true;
}
linePoint += lineFeed;
if (newLineNeeded) {
linePoint += lineFeed;
}
}
}
if (aero.getCockpitType() != Aero.COCKPIT_STANDARD) {
g2d.drawString(aero.getCockpitTypeString(), 22, linePoint);
linePoint += lineFeed;
}
if (aero instanceof FixedWingSupport) {
ImageHelperAero.printFixedWingSupportCargoChassisMod((FixedWingSupport) aero, g2d, (int) linePoint);
} else {
ImageHelperAero.printCargo(aero, g2d, (int)linePoint);
}
ImageHelper.printVehicleAmmo(aero, g2d, -20, 8);
ImageHelperAero.printAeroFuel(aero, g2d, 8);
}
static public void printArmorPoints(Graphics2D g2d, Vector<float[]> pipPlotter, float totalArmor, float maxArmor) {
pipPlotter.trimToSize();
float pipSpace = maxArmor / totalArmor;
for (float pos = 0; pos < pipPlotter.size(); pos += pipSpace) {
int currentPip = (int) pos;
ImageHelperAero.drawAeroArmorPip(g2d, pipPlotter.get(currentPip)[0], pipPlotter.get(currentPip)[1]);
if (--totalArmor <= 0) {
return;
}
}
}
public static void printFixedWingSupportCargoChassisMod(FixedWingSupport aero, Graphics2D g2d, int pointY) {
int pointX = 22;
double lineFeed = ImageHelper.getStringHeight(g2d, "H", g2d.getFont());
Font font = g2d.getFont();
if (aero.hasWorkingMisc(MiscType.F_CHASSIS_MODIFICATION)) {
pointY += lineFeed;
String chassisMods = "Chassis Modifications: ";
for (Mounted misc : aero.getMisc()) {
if (misc.getType().hasFlag(MiscType.F_CHASSIS_MODIFICATION)) {
chassisMods += misc.getName() + ", ";
}
}
chassisMods = chassisMods.substring(0, chassisMods.length() - 2);
g2d.setFont(UnitUtil.getNewFont(g2d, chassisMods, false, 205, font.getSize2D()));
g2d.drawString(chassisMods, pointX, pointY);
}
g2d.setFont(font);
ImageHelperAero.printCargo(aero, g2d, pointY);
}
public static void printCargo(Aero aero, Graphics2D g2d, int pointY) {
if ((aero.getTransportBays().size() < 1) && (aero.getTroopCarryingSpace() == 0)) {
return;
}
int pointX = 30;
double lineFeed = ImageHelper.getStringHeight(g2d, "H", g2d.getFont());
Font font = UnitUtil.deriveFont(true, g2d.getFont().getSize2D());
g2d.setFont(font);
pointY += lineFeed;
g2d.drawString("Cargo: ", pointX, pointY);
font = UnitUtil.deriveFont(g2d.getFont().getSize2D());
g2d.setFont(font);
double troopspace = aero.getTroopCarryingSpace();
if (troopspace > 0) {
pointY += lineFeed;
String troopString = "Infantry Compartment (";
if ((troopspace - Math.floor(troopspace)) > 0) {
troopString += String.valueOf(troopspace);
} else {
troopString += String.valueOf((int) troopspace);
}
if (troopspace == 1) {
troopString += " ton)";
} else {
troopString += " tons)";
}
g2d.drawString(troopString, pointX, pointY);
}
pointY += lineFeed;
for (Bay bay : aero.getTransportBays()) {
g2d.drawString(ImageHelperDropShip.getBayString(bay), pointX, pointY);
pointY += lineFeed;
}
}
public static Font getAeroWeaponsNEquipmentFont(Graphics2D g2d, boolean bold, float stringHeight, ArrayList<Hashtable<String, EquipmentInfo>> equipmentLocations, float pointSize) {
Font font = g2d.getFont();
int weaponCount = 1;
for (int pos = 0; pos < equipmentLocations.size(); pos++) {
Hashtable<String, EquipmentInfo> eqHash = equipmentLocations.get(pos);
if (eqHash.size() < 1) {
continue;
}
for (EquipmentInfo eqi : eqHash.values()) {
String name = String.format("%1$s %2$s", eqi.name.trim(), eqi.damage.trim());
weaponCount++;
if (eqi.isWeapon) {
/* if (eqi.isMML) {
weaponCount += 2;
} else if (eqi.isATM) {
weaponCount += 3;
}*/
if (eqi.hasArtemis || eqi.hasArtemisV || eqi.hasApollo) {
weaponCount++;
}
if (ImageHelper.getStringWidth(g2d, name, font) > 65) {
weaponCount++;
}
}
}
}
while (((ImageHelper.getStringHeight(g2d, "H", font) * weaponCount) > stringHeight) && (pointSize > 0)) {
pointSize -= .1;
font = UnitUtil.deriveFont(bold, pointSize);
}
return font;
}
}