/*
* SpecialAbility.java
*
* Copyright (c) 2009 Jay Lawson <jaylawson39 at yahoo.com>. All rights reserved.
*
* This file is part of MekHQ.
*
* MekHQ 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 3 of the License, or
* (at your option) any later version.
*
* MekHQ 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 MekHQ. If not, see <http://www.gnu.org/licenses/>.
*/
package mekhq.campaign.personnel;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Hashtable;
import mekhq.MekHQ;
import mekhq.MekHqXmlSerializable;
import mekhq.MekHqXmlUtil;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* This object tracks a specific skill prerequisite for a special ability. This object can list more
* than one skill and we will track these skills in a hashmap where the value gives the minimum skill
* level. The collection of skills is treated as an OR statement such that a person possessing any of the
* skills at the appropriate level will evaluate as eligible. To create AND conditions, use multiple skill
* prereqs in the SpecialAbility object.
*
* We are going to limit the skill levels by the Green, Regular, Veteran, Elite notation such
* that:
* 0 - Any
* 1 - Green
* 2 - Regular
* 3 - Veteran
* 4 - Elite
* This way, if the user changes the meaning of various skill levels, they won't have to redo all of
* their prereqs - we could consider expanding this to allow users to specify a more specific numeric
* skill level (to allow for better consistency with AToW) for example
*
* @author Jay Lawson
*
*/
public class SkillPrereq implements MekHqXmlSerializable {
private Hashtable<String, Integer> skillset;
public SkillPrereq() {
skillset = new Hashtable<String, Integer>();
}
@SuppressWarnings("unchecked") // FIXME: Broken Java with it's Object clones
public SkillPrereq clone() {
SkillPrereq clone = new SkillPrereq();
clone.skillset = (Hashtable<String, Integer>)this.skillset.clone();
return clone;
}
public boolean isEmpty() {
return skillset.isEmpty();
}
public boolean qualifies(Person p) {
for(String skillName : skillset.keySet()) {
if(p.hasSkill(skillName)) {
if(p.getSkill(skillName).getExperienceLevel() >= skillset.get(skillName)) {
return true;
}
}
}
return false;
}
public int getSkillLevel(String skillName) {
if(null != skillset.get(skillName)) {
return skillset.get(skillName);
}
return -1;
}
public void addPrereq(String type, int lvl) {
skillset.put(type, lvl);
}
@Override
public String toString() {
String toReturn = "";
Enumeration<String> enumKeys = skillset.keys();
while(enumKeys.hasMoreElements()) {
String key = enumKeys.nextElement();
SkillType.getType(key).getName();
int lvl = skillset.get(key);
String skillLvl = "";
if(lvl >= SkillType.EXP_GREEN) {
skillLvl = SkillType.getExperienceLevelName(lvl) + " ";
}
toReturn += skillLvl + SkillType.getType(key).getName();
if(enumKeys.hasMoreElements()) {
toReturn += "<br>OR ";
}
}
return "{" + toReturn + "}";
}
@Override
public void writeToXml(PrintWriter pw1, int indent) {
pw1.println(MekHqXmlUtil.indentStr(indent) + "<skillPrereq>");
for(String key : skillset.keySet()) {
int lvl = skillset.get(key);
if(lvl <= 0) {
pw1.println(MekHqXmlUtil.indentStr(indent+1)
+"<skill>"
+key
+"</skill>");
} else {
pw1.println(MekHqXmlUtil.indentStr(indent+1)
+"<skill>"
+key + "::" + SkillType.getExperienceLevelName(lvl)
+"</skill>");
}
}
pw1.println(MekHqXmlUtil.indentStr(indent) + "</skillPrereq>");
}
public static SkillPrereq generateInstanceFromXML(Node wn) {
SkillPrereq retVal = null;
try {
retVal = new SkillPrereq();
NodeList nl = wn.getChildNodes();
for (int x=0; x<nl.getLength(); x++) {
Node wn2 = nl.item(x);
if (wn2.getNodeName().equalsIgnoreCase("skill")) {
String skillName = wn2.getTextContent();
int level = 0;
if (skillName.contains("::")) {
level = parseStringForLevel(skillName);
skillName = parseStringForName(skillName);
}
//if the skill name does not match existing skills, then ignore
if(null != SkillType.getType(skillName)) {
retVal.addPrereq(skillName, level);
}
}
}
} catch (Exception ex) {
// Errrr, apparently either the class name was invalid...
// Or the listed name doesn't exist.
// Doh!
MekHQ.logError(ex);
}
return retVal;
}
private static String parseStringForName(String s) {
return s.split("::")[0];
}
private static int parseStringForLevel(String s) {
String[] temp = s.split("::");
if(temp.length < 2) {
return 0;
} else {
switch(temp[1].substring(0, 1)) {
case "G":
return 1;
case "R":
return 2;
case "V":
return 3;
case "E":
return 4;
default:
return 0;
}
}
}
}