package com.hero;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;

import javax.swing.JOptionPane;

import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

import com.hero.objects.GenericObject;
import com.hero.objects.characteristics.Characteristic;
import com.hero.util.XMLUtility;

/**
 * Copyright (c) 2000 - 2005, CompNet Design, Inc. All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, is prohibited unless the following conditions are met: 1.
 * Express written consent of CompNet Design, Inc. is obtained by the developer.
 * 2. Redistributions must retain this copyright notice. THIS SOFTWARE IS
 * PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * @author CompNet Design, Inc.
 * @version $Revision$
 */

public class Rules {
	public static final int DONOTALLOW = 2;

	public static final int IGNORE = 0;

	public static final int WARN = 1;

	private int attackAPMaxResponse;

	private int basePoints;

	private int disadPoints;

	private int APPerEND;

	private int STRAPPerEND;

	private boolean equipmentAllowed;

	private boolean ncmSelected;

	private boolean ncmUserChangeable;

	private int attackAPMaxValue;

	private int availDisadPointsResponse;

	private int availTotalPointsResponse;

	private int characteristicMaxResponse;

	private int characteristicMaxValue;

	private String currentSet;

	private int defenseAPMaxResponse;

	private int defenseAPMaxValue;

	private boolean dirty;

	private int disadCategoryMaxResponse;

	private int disadCategoryMaxValue;

	private double equipmentCostConversion;

	private int equipmentCostDecimalPlaces;

	private int equipmentCostResponse;

	private String equipmentCostUnits;

	private int equipmentCostValue;

	private boolean equipmentUnitsPrefix;

	private boolean languageSimilaritiesUsed;

	private int maneuverMaxResponse;

	private int maneuverMaxValue;

	private int perkMaxResponse;

	private int perkMaxValue;

	private int powerMaxResponse;

	private int powerMaxValue;

	private int skillMaxResponse;

	private int skillMaxValue;

	private boolean penalizeNoLevel1;

	private int talentMaxResponse;

	private int talentMaxValue;

	private int linkAcrossFramework;

	private int specialTypeInFramework;

	private int nonENDUsingAbilityInEC;

	private boolean automaticallyApplyNoFigured;

	private boolean onlySellOneFigured;

	private boolean useIncreasedDamageDifferentiation;

	private boolean standardEffectAllowed;

	private boolean defaultStandardEffect;

	private boolean multiplierAllowed;

	private boolean useExpandedGrowthChart;

	private boolean literacyFree;

	private boolean nativeLiteracyFree;

	private String campaignSet;

	private boolean useNotes1;

	private String notes1Label;

	private boolean useNotes2;

	private String notes2Label;

	private boolean useNotes3;

	private String notes3Label;

	private boolean useNotes4;

	private String notes4Label;

	private boolean useNotes5;

	private String notes5Label;

	private String name;

	private boolean useSkillMaxima = false;

	private int skillMaximaLimit = 13;

	private boolean useSkillMultipliers = false;

	private Hashtable<String, Integer> characteristicMaxima = new Hashtable<String, Integer>();
	
	private int skillRollBase = 9;
	private double skillRollDenominator = 5;
	
	private int charRollBase = 9;
	private double charRollDenominator = 5;
	
	private boolean languagesAsINTSkill = false;
	

	public int getSkillRollBase() {
		return skillRollBase;
	}

	public void setSkillRollBase(int skillRollBase) {
		this.skillRollBase = skillRollBase;
	}

	public double getSkillRollDenominator() {
		if (skillRollDenominator == 0) {
			skillRollDenominator = 5;
		}
		return skillRollDenominator;
	}

	public void setSkillRollDenominator(double skillRollDenominator) {
		this.skillRollDenominator = skillRollDenominator;
	}
	
	public int getCharRollBase() {
		return charRollBase;
	}

	public void setCharRollBase(int val) {
		this.charRollBase = val;
	}

	public double getCharRollDenominator() {
		if (charRollDenominator == 0) {
			charRollDenominator = 5;
		}
		return charRollDenominator;
	}

	public void setCharRollDenominator(double val) {
		this.charRollDenominator = val;
	}

	public Rules() {
	}

	public int getCharacteristicMaxima(String xmlid) {
		if (characteristicMaxima.get(xmlid) != null) {
			return characteristicMaxima.get(xmlid);
		} else {
			return 999;
		}
	}
	
	public void setCharacteristicMaxima(Characteristic c, int v) {
		characteristicMaxima.remove(c.getXMLID());
		characteristicMaxima.put(c.getXMLID(),v);
	}

	public boolean automaticallyApplyNoFigured() {
		return automaticallyApplyNoFigured;
	}

	public boolean defaultStandardEffect() {
		return defaultStandardEffect;
	}

	public int getAPPerEND() {
		return APPerEND;
	}

	/**
	 * @return
	 */
	public int getAttackAPMaxResponse() {
		return attackAPMaxResponse;
	}

	/**
	 * @return
	 */
	public int getAttackAPMaxValue() {
		return attackAPMaxValue;
	}

	/**
	 * @return
	 */
	public int getAvailDisadPointsResponse() {
		return availDisadPointsResponse;
	}

	/**
	 * @return
	 */
	public int getAvailTotalPointsResponse() {
		return availTotalPointsResponse;
	}

	public int getBasePoints() {
		return basePoints;
	}

	public String getCampaignSet() {
		if ((campaignSet == null) || !isDefault()) {
			campaignSet = "";
		}
		return campaignSet;
	}

	/**
	 * @return
	 */
	public int getCharacteristicMaxResponse() {
		return characteristicMaxResponse;
	}

	/**
	 * @return
	 */
	public int getCharacteristicMaxValue() {
		return characteristicMaxValue;
	}

	public String getCurrentSet() {
		String ret = currentSet;
		if ((currentSet == null) || (currentSet.trim().length() == 0)) {
			if ((campaignSet != null) && (campaignSet.trim().length() > 0)) {
				ret = campaignSet;
			} else {
				ret = "Default";
			}
		}
		return ret;
	}

	/**
	 * @return
	 */
	public int getDefenseAPMaxResponse() {
		return defenseAPMaxResponse;
	}

	/**
	 * @return
	 */
	public int getDefenseAPMaxValue() {
		return defenseAPMaxValue;
	}

	/**
	 * @return
	 */
	public int getDisadCategoryMaxResponse() {
		return disadCategoryMaxResponse;
	}

	/**
	 * @return
	 */
	public int getDisadCategoryMaxValue() {
		return disadCategoryMaxValue;
	}

	public int getDisadPoints() {
		return disadPoints;
	}

	/**
	 * @return
	 */
	public double getEquipmentCostConversion() {
		if (equipmentCostConversion == 0) {
			return 1;
		}
		return equipmentCostConversion;
	}

	/**
	 * @return
	 */
	public int getEquipmentCostDecimalPlaces() {
		return equipmentCostDecimalPlaces;
	}

	/**
	 * @return
	 */
	public int getEquipmentCostResponse() {
		return equipmentCostResponse;
	}

	/**
	 * @return
	 */
	public String getEquipmentCostUnits() {
		return equipmentCostUnits;
	}

	/**
	 * @return
	 */
	public int getEquipmentCostValue() {
		return equipmentCostValue;
	}

	public int getLinkAcrossFramework() {
		return linkAcrossFramework;
	}

	/**
	 * @return
	 */
	public int getManeuverMaxResponse() {
		return maneuverMaxResponse;
	}

	/**
	 * @return
	 */
	public int getManeuverMaxValue() {
		return maneuverMaxValue;
	}

	public String getName() {
		return name;
	}

	public int getNonENDUsingAbilityInEC() {
		return nonENDUsingAbilityInEC;
	}

	public String getNotes1Label() {
		if ((notes1Label == null) || (notes1Label.trim().length() == 0)) {
			notes1Label = "Notes 1";
		}
		return notes1Label;
	}

	public String getNotes2Label() {
		if ((notes2Label == null) || (notes2Label.trim().length() == 0)) {
			notes2Label = "Notes 2";
		}
		return notes2Label;
	}

	public String getNotes3Label() {
		if ((notes3Label == null) || (notes3Label.trim().length() == 0)) {
			notes3Label = "Notes 3";
		}
		return notes3Label;
	}

	public String getNotes4Label() {
		if ((notes4Label == null) || (notes4Label.trim().length() == 0)) {
			notes4Label = "Notes 4";
		}
		return notes4Label;
	}

	public String getNotes5Label() {
		if ((notes5Label == null) || (notes5Label.trim().length() == 0)) {
			notes5Label = "Notes 5";
		}
		return notes5Label;
	}

	/**
	 * @return
	 */
	public int getPerkMaxResponse() {
		return perkMaxResponse;
	}

	/**
	 * @return
	 */
	public int getPerkMaxValue() {
		return perkMaxValue;
	}

	/**
	 * @return
	 */
	public int getPowerMaxResponse() {
		return powerMaxResponse;
	}

	/**
	 * @return
	 */
	public int getPowerMaxValue() {
		return powerMaxValue;
	}

	public Element getRulesXML() {
		Element root = new Element("RULES");
		if (currentSet == null) {
			currentSet = "";
		}
		if ((name == null) || (name.trim().length() == 0)) {
			name = currentSet;
			File f = new File(currentSet);
			if (f.exists()) {
				name = f.getName();
			}
		}
		root.setAttribute("name", name);
		root.setAttribute("path", currentSet);
		root.setAttribute("BASEPOINTS", "" + basePoints);
		root.setAttribute("DISADPOINTS", "" + disadPoints);
		root.setAttribute("APPEREND", "" + APPerEND);
		root.setAttribute("STRAPPEREND", "" + STRAPPerEND);
		root.setAttribute("NCMSELECTED", ncmSelected ? "Yes" : "No");
		root
				.setAttribute("NCMUSERCHANGEABLE", ncmUserChangeable ? "Yes"
						: "No");
		root.setAttribute("ATTACKAPMAXVALUE", "" + attackAPMaxValue);
		root.setAttribute("ATTACKAPMAXRESPONSE", "" + attackAPMaxResponse);
		root.setAttribute("DEFENSEAPMAXVALUE", "" + defenseAPMaxValue);
		root.setAttribute("DEFENSEAPMAXRESPONSE", "" + defenseAPMaxResponse);
		root.setAttribute("DISADCATEGORYMAXVALUE", "" + disadCategoryMaxValue);
		root.setAttribute("DISADCATEGORYMAXRESPONSE", ""
				+ disadCategoryMaxResponse);
		root.setAttribute("AVAILDISADPOINTSRESPONSE", ""
				+ availDisadPointsResponse);
		root.setAttribute("AVAILTOTALPOINTSRESPONSE", ""
				+ availTotalPointsResponse);
		root
				.setAttribute("CHARACTERISTICMAXVALUE", ""
						+ characteristicMaxValue);
		root.setAttribute("CHARACTERISTICMAXRESPONSE", ""
				+ characteristicMaxResponse);
		root.setAttribute("MANEUVERMAXVALUE", "" + maneuverMaxValue);
		root.setAttribute("MANEUVERMAXRESPONSE", "" + maneuverMaxResponse);
		root.setAttribute("SKILLMAXVALUE", "" + skillMaxValue);
		root.setAttribute("SKILLMAXRESPONSE", "" + skillMaxResponse);
		root.setAttribute("PERKMAXVALUE", "" + perkMaxValue);
		root.setAttribute("PERKMAXRESPONSE", "" + perkMaxResponse);
		root.setAttribute("TALENTMAXVALUE", "" + talentMaxValue);
		root.setAttribute("TALENTMAXRESPONSE", "" + talentMaxResponse);
		root.setAttribute("POWERMAXVALUE", "" + powerMaxValue);
		root.setAttribute("POWERMAXRESPONSE", "" + powerMaxResponse);
		root.setAttribute("EQUIPMENTCOSTVALUE", "" + equipmentCostValue);
		root.setAttribute("EQUIPMENTCOSTRESPONSE", "" + equipmentCostResponse);
		root.setAttribute("EQUIPMENTCOSTUNITS", "" + equipmentCostUnits);
		root.setAttribute("EQUIPMENTCOSTCONVERSION", ""
				+ equipmentCostConversion);
		root.setAttribute("EQUIPMENTCOSTDECIMALPLACES", ""
				+ equipmentCostDecimalPlaces);
		root.setAttribute("EQUIPMENTUNITSPREFIX", equipmentUnitsPrefix ? "Yes"
				: "No");
		root.setAttribute("STANDARDEFFECTALLOWED",
				standardEffectAllowed ? "Yes" : "No");
		root.setAttribute("USEEXPANDEDGROWTHCHART",
				useExpandedGrowthChart ? "Yes" : "No");
		root.setAttribute("DEFAULTSTANDARDEFFECT",
				defaultStandardEffect ? "Yes" : "No");
		root
				.setAttribute("MULTIPLIERALLOWED", multiplierAllowed ? "Yes"
						: "No");
		root.setAttribute("LANGUAGESIMILARITIESUSED",
				languageSimilaritiesUsed ? "Yes" : "No");
		root.setAttribute("LITERACYFREE", literacyFree ? "Yes" : "No");
		root.setAttribute("NATIVELITERACYFREE", nativeLiteracyFree ? "Yes"
				: "No");
		root.setAttribute("EQUIPMENTALLOWED", equipmentAllowed ? "Yes" : "No");
		root.setAttribute("PENALIZENOLEVEL1", penalizeNoLevel1 ? "Yes" : "No");
		root.setAttribute("ONLYSELLONEFIGURED", onlySellOneFigured ? "Yes"
				: "No");
		root.setAttribute("USEINCREASEDDAMAGEDIFFERENTIATION",
				useIncreasedDamageDifferentiation ? "Yes" : "No");
		root.setAttribute("AUTOMATICALLYAPPLYNOFIGURED",
				automaticallyApplyNoFigured ? "Yes" : "No");
		root.setAttribute("LINKACROSSFRAMEWORK", "" + linkAcrossFramework);
		root
				.setAttribute("SPECIALTYPEINFRAMEWORK", ""
						+ specialTypeInFramework);
		root
				.setAttribute("NONENDUSINGABILITYINEC", ""
						+ nonENDUsingAbilityInEC);
		root.setAttribute("USESKILLMAXIMA", getUseSkillMaxima() ? "Yes" : "No");
		root.setAttribute("USESKILLMULTIPLIERS", useSkillMultipliers() ? "Yes"
				: "No");
		root.setAttribute("LANGUAGESASINTSKILL", useLanguagesAsINTSkill() ? "Yes"
				: "No");
		root.setAttribute("SKILLMAXIMALIMIT", "" + getSkillMaximaLimit());
		root.setAttribute("SKILLROLLBASE", "" + getSkillRollBase());
		root.setAttribute("SKILLROLLDENOMINATOR", "" + getSkillRollDenominator());
		root.setAttribute("CHARROLLBASE", "" + getCharRollBase());
		root.setAttribute("CHARROLLDENOMINATOR", "" + getCharRollDenominator());
		root.setAttribute("USENOTES1", useNotes1() ? "Yes" : "No");
		root.setAttribute("USENOTES2", useNotes2() ? "Yes" : "No");
		root.setAttribute("USENOTES3", useNotes3() ? "Yes" : "No");
		root.setAttribute("USENOTES4", useNotes4() ? "Yes" : "No");
		root.setAttribute("USENOTES5", useNotes5() ? "Yes" : "No");
		root.setAttribute("NOTES1LABEL", getNotes1Label());
		root.setAttribute("NOTES2LABEL", getNotes2Label());
		root.setAttribute("NOTES3LABEL", getNotes3Label());
		root.setAttribute("NOTES4LABEL", getNotes4Label());
		root.setAttribute("NOTES5LABEL", getNotes5Label());
		Iterator<String> keys = characteristicMaxima.keySet().iterator();
		while (keys.hasNext()) {
			String c = keys.next();
			int v = characteristicMaxima.get(c);
			root.setAttribute(c+"_MAX", ""+v);
		}
		return root;
	}

	public int getSkillMaximaLimit() {
		return skillMaximaLimit;
	}

	/**
	 * @return
	 */
	public int getSkillMaxResponse() {
		return skillMaxResponse;
	}

	/**
	 * @return
	 */
	public int getSkillMaxValue() {
		return skillMaxValue;
	}

	public int getSpecialTypeInFramework() {
		return specialTypeInFramework;
	}

	public int getSTRAPPerEND() {
		if (isDefault()) {
			if (HeroDesigner.getActiveTemplate() != null) {
				Template t = HeroDesigner.getActiveTemplate();
				if ((t.getId().indexOf("Heroic") >= 0)
						|| (t.getId().indexOf("Normal") >= 0)) {
					return 5;
				}
				for (Template temp : t.getParentTemplates()) {
					if ((temp.getId().indexOf("Heroic") >= 0)
							|| (temp.getId().indexOf("Normal") >= 0)) {
						return 5;
					}
				}
			}
		}
		return STRAPPerEND;
	}

	/**
	 * @return
	 */
	public int getTalentMaxResponse() {
		return talentMaxResponse;
	}

	/**
	 * @return
	 */
	public int getTalentMaxValue() {
		return talentMaxValue;
	}

	public boolean getUseSkillMaxima() {
		return useSkillMaxima;
	}

	public boolean isDefault() {
		if (getCurrentSet().equals("Default") && !dirty) {
			return true;
		} else {
			return false;
		}
	}

	public boolean isDirty() {
		return dirty;
	}

	public boolean isEquipmentAllowed() {
		if (isDefault()) {
			if (HeroDesigner.getActiveTemplate() != null) {
				Template t = HeroDesigner.getActiveTemplate();
				if ((t.getId().indexOf("Heroic") >= 0)
						|| (t.getId().indexOf("Normal") >= 0)) {
					return true;
				}
				for (Template temp : t.getParentTemplates()) {
					if ((temp.getId().indexOf("Heroic") >= 0)
							|| (temp.getId().indexOf("Normal") >= 0)) {
						return true;
					}
				}

			}
			return false;
		}
		return equipmentAllowed;
	}

	public boolean isEquipmentUnitsPrefix() {
		return equipmentUnitsPrefix;
	}

	/**
	 * @return
	 */
	public boolean isLanguageSimilaritiesUsed() {
		return languageSimilaritiesUsed;
	}

	public boolean isLiteracyFree() {
		return literacyFree;
	}

	public boolean isNativeLiteracyFree() {
		return nativeLiteracyFree;
	}

	public boolean isNCMSelected() {
		return ncmSelected;
	}

	public boolean isNCMUserChangeable() {
		return ncmUserChangeable;
	}

	/**
	 * @return
	 */
	public boolean isStandardEffectAllowed() {
		return standardEffectAllowed;
	}

	public void loadRulesDefinition(String filePath) {
		try {
			File prefs = new File(filePath);
			if (!prefs.exists()
					&& (HeroDesigner.getInstance().getPrefs().getRulesDir() != null)) {
				prefs = new File(HeroDesigner.getInstance().getPrefs()
						.getRulesDir()
						+ File.separator + prefs.getName());
				filePath = prefs.getAbsolutePath();
			}
			if (!prefs.exists()) {
				useDefault();
				return;
			}
			SAXBuilder builder = new SAXBuilder(false);
			Document doc = builder.build(prefs);
			builder = null;
			Element root = doc.getRootElement();
			restoreRules(root);
			currentSet = filePath;
		} catch (Exception exp) {
			exp.printStackTrace();
			JOptionPane.showMessageDialog(HeroDesigner.getAppFrame(),
					"An error occurred reading the rules file\n     \""
							+ filePath + "\"\n\nError Message: "
							+ exp.getMessage(), "Error loading rules",
					JOptionPane.ERROR_MESSAGE);
			useDefault();
		}
		campaignSet = "";
	}

	public boolean multiplierAllowed() {
		return multiplierAllowed;
	}

	public boolean onlySellOneFigured() {
		return onlySellOneFigured;
	}

	public boolean penalizeNoLevel1() {
		return penalizeNoLevel1;
	}

	public void restoreRules(Element root) {
		String n = root.getAttributeValue("name");
		if (n != null) {
			name = n;
		}
		if ((name == null) || (name.trim().length() == 0)) {
			name = currentSet;
		}
		if ((name == null) || (name.trim().length() == 0)) {
			name = "Custom";
		}
		String check = XMLUtility.getValue(root, "BASEPOINTS");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				basePoints = Integer.parseInt(check);
			} catch (NumberFormatException e) {
				basePoints = 200;
			}
		} else {
			basePoints = 200;
		}

		check = XMLUtility.getValue(root, "DISADPOINTS");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				disadPoints = Integer.parseInt(check);
			} catch (NumberFormatException e) {
				disadPoints = 150;
			}
		} else {
			disadPoints = 150;
		}
		
		check = XMLUtility.getValue(root, "SKILLROLLBASE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				skillRollBase = Integer.parseInt(check);
			} catch (NumberFormatException e) {
				skillRollBase = 9;
			}
		} else {
			skillRollBase = 9;
		}
		
		check = XMLUtility.getValue(root, "SKILLROLLDENOMINATOR");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				skillRollDenominator = Double.parseDouble(check);
			} catch (NumberFormatException e) {
				skillRollDenominator = 5;
			}
		} else {
			skillRollDenominator = 5;
		}
		
		check = XMLUtility.getValue(root, "CHARROLLBASE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				charRollBase = Integer.parseInt(check);
			} catch (NumberFormatException e) {
				charRollBase = 9;
			}
		} else {
			charRollBase = 9;
		}
		
		check = XMLUtility.getValue(root, "CHARROLLDENOMINATOR");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				charRollDenominator = Double.parseDouble(check);
			} catch (NumberFormatException e) {
				charRollDenominator = 5;
			}
		} else {
			charRollDenominator = 5;
		}

		check = XMLUtility.getValue(root, "APPEREND");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				APPerEND = Integer.parseInt(check);
			} catch (NumberFormatException e) {
				APPerEND = 10;
			}
		} else {
			APPerEND = 10;
		}

		check = XMLUtility.getValue(root, "STRAPPEREND");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				STRAPPerEND = Integer.parseInt(check);
			} catch (NumberFormatException e) {
				STRAPPerEND = 10;
			}
		} else {
			STRAPPerEND = 10;
		}

		check = XMLUtility.getValue(root, "ATTACKAPMAXVALUE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				attackAPMaxValue = Integer.parseInt(check);
			} catch (NumberFormatException e) {
				attackAPMaxValue = 90;
			}
		} else {
			attackAPMaxValue = 90;
		}

		check = XMLUtility.getValue(root, "ATTACKAPMAXRESPONSE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				int test = Integer.parseInt(check);
				if ((test >= Rules.IGNORE) && (test <= Rules.DONOTALLOW)) {
					attackAPMaxResponse = test;
				} else {
					attackAPMaxResponse = Rules.IGNORE;
				}
			} catch (NumberFormatException e) {
				attackAPMaxResponse = Rules.IGNORE;
			}
		} else {
			attackAPMaxResponse = Rules.IGNORE;
		}

		check = XMLUtility.getValue(root, "DEFENSEAPMAXVALUE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				defenseAPMaxValue = Integer.parseInt(check);
			} catch (NumberFormatException e) {
				defenseAPMaxValue = 90;
			}
		} else {
			defenseAPMaxValue = 90;
		}

		check = XMLUtility.getValue(root, "DEFENSEAPMAXRESPONSE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				int test = Integer.parseInt(check);
				if ((test >= Rules.IGNORE) && (test <= Rules.DONOTALLOW)) {
					defenseAPMaxResponse = test;
				} else {
					defenseAPMaxResponse = Rules.IGNORE;
				}
			} catch (NumberFormatException e) {
				defenseAPMaxResponse = Rules.IGNORE;
			}
		} else {
			defenseAPMaxResponse = Rules.IGNORE;
		}

		check = XMLUtility.getValue(root, "MANEUVERMAXVALUE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				maneuverMaxValue = Integer.parseInt(check);
			} catch (NumberFormatException e) {
				maneuverMaxValue = 1000;
			}
		} else {
			maneuverMaxValue = 1000;
		}

		check = XMLUtility.getValue(root, "MANEUVERMAXRESPONSE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				int test = Integer.parseInt(check);
				if ((test >= Rules.IGNORE) && (test <= Rules.DONOTALLOW)) {
					maneuverMaxResponse = test;
				} else {
					maneuverMaxResponse = Rules.IGNORE;
				}
			} catch (NumberFormatException e) {
				maneuverMaxResponse = Rules.IGNORE;
			}
		} else {
			maneuverMaxResponse = Rules.IGNORE;
		}

		check = XMLUtility.getValue(root, "DISADCATEGORYMAXVALUE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				disadCategoryMaxValue = Integer.parseInt(check);
			} catch (NumberFormatException e) {
				disadCategoryMaxValue = 75;
			}
		} else {
			disadCategoryMaxValue = 75;
		}

		check = XMLUtility.getValue(root, "DISADCATEGORYMAXRESPONSE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				int test = Integer.parseInt(check);
				if ((test >= Rules.IGNORE) && (test <= Rules.DONOTALLOW)) {
					disadCategoryMaxResponse = test;
				} else {
					disadCategoryMaxResponse = Rules.IGNORE;
				}
			} catch (NumberFormatException e) {
				disadCategoryMaxResponse = Rules.IGNORE;
			}
		} else {
			disadCategoryMaxResponse = Rules.IGNORE;
		}

		check = XMLUtility.getValue(root, "AVAILDISADPOINTSRESPONSE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				int test = Integer.parseInt(check);
				if ((test >= Rules.IGNORE) && (test <= Rules.DONOTALLOW)) {
					availDisadPointsResponse = test;
				} else {
					availDisadPointsResponse = Rules.IGNORE;
				}
			} catch (NumberFormatException e) {
				availDisadPointsResponse = Rules.IGNORE;
			}
		} else {
			availDisadPointsResponse = Rules.IGNORE;
		}

		check = XMLUtility.getValue(root, "AVAILTOTALPOINTSRESPONSE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				int test = Integer.parseInt(check);
				if ((test >= Rules.IGNORE) && (test <= Rules.DONOTALLOW)) {
					availTotalPointsResponse = test;
				} else {
					availTotalPointsResponse = Rules.IGNORE;
				}
			} catch (NumberFormatException e) {
				availTotalPointsResponse = Rules.IGNORE;
			}
		} else {
			availTotalPointsResponse = Rules.IGNORE;
		}

		check = XMLUtility.getValue(root, "CHARACTERISTICMAXVALUE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				characteristicMaxValue = Integer.parseInt(check);
			} catch (NumberFormatException e) {
				characteristicMaxValue = 1000;
			}
		} else {
			characteristicMaxValue = 1000;
		}

		check = XMLUtility.getValue(root, "CHARACTERISTICMAXRESPONSE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				int test = Integer.parseInt(check);
				if ((test >= Rules.IGNORE) && (test <= Rules.DONOTALLOW)) {
					characteristicMaxResponse = test;
				} else {
					characteristicMaxResponse = Rules.IGNORE;
				}
			} catch (NumberFormatException e) {
				characteristicMaxResponse = Rules.IGNORE;
			}
		} else {
			characteristicMaxResponse = Rules.IGNORE;
		}

		check = XMLUtility.getValue(root, "SKILLMAXVALUE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				skillMaxValue = Integer.parseInt(check);
			} catch (NumberFormatException e) {
				skillMaxValue = 1000;
			}
		} else {
			skillMaxValue = 1000;
		}

		check = XMLUtility.getValue(root, "SKILLMAXRESPONSE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				int test = Integer.parseInt(check);
				if ((test >= Rules.IGNORE) && (test <= Rules.DONOTALLOW)) {
					skillMaxResponse = test;
				} else {
					skillMaxResponse = Rules.IGNORE;
				}
			} catch (NumberFormatException e) {
				skillMaxResponse = Rules.IGNORE;
			}
		} else {
			skillMaxResponse = Rules.IGNORE;
		}

		check = XMLUtility.getValue(root, "PERKMAXVALUE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				perkMaxValue = Integer.parseInt(check);
			} catch (NumberFormatException e) {
				perkMaxValue = 1000;
			}
		} else {
			perkMaxValue = 1000;
		}

		check = XMLUtility.getValue(root, "PERKMAXRESPONSE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				int test = Integer.parseInt(check);
				if ((test >= Rules.IGNORE) && (test <= Rules.DONOTALLOW)) {
					perkMaxResponse = test;
				} else {
					perkMaxResponse = Rules.IGNORE;
				}
			} catch (NumberFormatException e) {
				perkMaxResponse = Rules.IGNORE;
			}
		} else {
			perkMaxResponse = Rules.IGNORE;
		}

		check = XMLUtility.getValue(root, "TALENTMAXVALUE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				talentMaxValue = Integer.parseInt(check);
			} catch (NumberFormatException e) {
				talentMaxValue = 1000;
			}
		} else {
			talentMaxValue = 1000;
		}

		check = XMLUtility.getValue(root, "TALENTMAXRESPONSE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				int test = Integer.parseInt(check);
				if ((test >= Rules.IGNORE) && (test <= Rules.DONOTALLOW)) {
					talentMaxResponse = test;
				} else {
					talentMaxResponse = Rules.IGNORE;
				}
			} catch (NumberFormatException e) {
				talentMaxResponse = Rules.IGNORE;
			}
		} else {
			talentMaxResponse = Rules.IGNORE;
		}

		check = XMLUtility.getValue(root, "POWERMAXVALUE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				powerMaxValue = Integer.parseInt(check);
			} catch (NumberFormatException e) {
				powerMaxValue = 1000;
			}
		} else {
			powerMaxValue = 1000;
		}

		check = XMLUtility.getValue(root, "POWERMAXRESPONSE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				int test = Integer.parseInt(check);
				if ((test >= Rules.IGNORE) && (test <= Rules.DONOTALLOW)) {
					powerMaxResponse = test;
				} else {
					powerMaxResponse = Rules.IGNORE;
				}
			} catch (NumberFormatException e) {
				powerMaxResponse = Rules.IGNORE;
			}
		} else {
			powerMaxResponse = Rules.IGNORE;
		}

		check = XMLUtility.getValue(root, "EQUIPMENTCOSTVALUE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				equipmentCostValue = Integer.parseInt(check);
			} catch (NumberFormatException e) {
				equipmentCostValue = 1000;
			}
		} else {
			equipmentCostValue = 1000;
		}

		check = XMLUtility.getValue(root, "EQUIPMENTCOSTCONVERSION");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				equipmentCostConversion = Double.parseDouble(check);
			} catch (NumberFormatException e) {
				equipmentCostConversion = 1;
			}
		} else {
			equipmentCostConversion = 1;
		}

		check = XMLUtility.getValue(root, "EQUIPMENTCOSTDECIMALPLACES");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				equipmentCostDecimalPlaces = Integer.parseInt(check);
			} catch (NumberFormatException e) {
				equipmentCostDecimalPlaces = 1000;
			}
		} else {
			equipmentCostDecimalPlaces = 1000;
		}

		check = XMLUtility.getValue(root, "EQUIPMENTCOSTRESPONSE");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				int test = Integer.parseInt(check);
				if ((test >= Rules.IGNORE) && (test <= Rules.DONOTALLOW)) {
					equipmentCostResponse = test;
				} else {
					equipmentCostResponse = Rules.IGNORE;
				}
			} catch (NumberFormatException e) {
				equipmentCostResponse = Rules.IGNORE;
			}
		} else {
			equipmentCostResponse = Rules.IGNORE;
		}

		check = XMLUtility.getValue(root, "EQUIPMENTCOSTUNITS");
		if (check != null) {
			equipmentCostUnits = check;
		} else {
			equipmentCostUnits = "$";
		}

		check = XMLUtility.getValue(root, "EQUIPMENTUNITSPREFIX");
		if ((check != null) && check.trim().toUpperCase().startsWith("N")) {
			equipmentUnitsPrefix = false;
		} else {
			equipmentUnitsPrefix = true;
		}

		check = XMLUtility.getValue(root, "USESKILLMAXIMA");
		if ((check != null) && check.trim().toUpperCase().startsWith("Y")) {
			useSkillMaxima = true;
		} else {
			useSkillMaxima = false;
		}
		check = XMLUtility.getValue(root, "USESKILLMULTIPLIERS");
		if ((check != null) && check.trim().toUpperCase().startsWith("Y")) {
			useSkillMultipliers = true;
		} else {
			useSkillMultipliers = false;
		}
		check = XMLUtility.getValue(root, "LANGUAGESASINTSKILL");
		if ((check != null) && check.trim().toUpperCase().startsWith("Y")) {
			languagesAsINTSkill = true;
		} else {
			languagesAsINTSkill = false;
		}
		check = XMLUtility.getValue(root, "SKILLMAXIMALIMIT");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				skillMaximaLimit = Integer.parseInt(check);
			} catch (Exception exp) {
				skillMaximaLimit = 13;
			}
		} else {
			skillMaximaLimit = 13;
		}

		check = XMLUtility.getValue(root, "ONLYSELLONEFIGURED");
		if ((check != null) && check.trim().toUpperCase().startsWith("N")) {
			onlySellOneFigured = false;
		} else {
			onlySellOneFigured = true;
		}
		check = XMLUtility.getValue(root, "USEINCREASEDDAMAGEDIFFERENTIATION");
		if ((check != null) && check.trim().toUpperCase().startsWith("Y")) {
			useIncreasedDamageDifferentiation = true;
		} else {
			useIncreasedDamageDifferentiation = false;
		}

		check = XMLUtility.getValue(root, "NCMSELECTED");
		if ((check != null) && check.trim().toUpperCase().startsWith("N")) {
			ncmSelected = false;
		} else {
			ncmSelected = true;
		}

		check = XMLUtility.getValue(root, "NCMUSERCHANGEABLE");
		if ((check != null) && check.trim().toUpperCase().startsWith("N")) {
			ncmUserChangeable = false;
		} else {
			ncmUserChangeable = true;
		}

		check = XMLUtility.getValue(root, "EQUIPMENTALLOWED");
		if ((check != null) && check.trim().toUpperCase().startsWith("N")) {
			equipmentAllowed = false;
		} else {
			equipmentAllowed = true;
		}

		check = XMLUtility.getValue(root, "PENALIZENOLEVEL1");
		if ((check != null) && check.trim().toUpperCase().startsWith("Y")) {
			penalizeNoLevel1 = true;
		} else {
			penalizeNoLevel1 = false;
		}

		check = XMLUtility.getValue(root, "STANDARDEFFECTALLOWED");
		if ((check != null) && check.trim().toUpperCase().startsWith("N")) {
			standardEffectAllowed = false;
		} else {
			standardEffectAllowed = true;
		}

		check = XMLUtility.getValue(root, "USEEXPANDEDGROWTHCHART");
		if ((check != null) && check.trim().toUpperCase().startsWith("Y")) {
			useExpandedGrowthChart = true;
		} else {
			useExpandedGrowthChart = false;
		}

		check = XMLUtility.getValue(root, "DEFAULTSTANDARDEFFECT");
		if ((check != null) && check.trim().toUpperCase().startsWith("N")) {
			defaultStandardEffect = false;
		} else {
			defaultStandardEffect = true;
		}

		check = XMLUtility.getValue(root, "MULTIPLIERALLOWED");
		if ((check != null) && check.trim().toUpperCase().startsWith("Y")) {
			multiplierAllowed = true;
		} else {
			multiplierAllowed = false;
		}

		check = XMLUtility.getValue(root, "USENOTES1");
		useNotes1 = (check != null)
				&& check.trim().toUpperCase().startsWith("Y");
		check = XMLUtility.getValue(root, "USENOTES2");
		useNotes2 = (check != null)
				&& check.trim().toUpperCase().startsWith("Y");
		check = XMLUtility.getValue(root, "USENOTES3");
		useNotes3 = (check != null)
				&& check.trim().toUpperCase().startsWith("Y");
		check = XMLUtility.getValue(root, "USENOTES4");
		useNotes4 = (check != null)
				&& check.trim().toUpperCase().startsWith("Y");
		check = XMLUtility.getValue(root, "USENOTES5");
		useNotes5 = (check != null)
				&& check.trim().toUpperCase().startsWith("Y");
		check = XMLUtility.getValue(root, "NOTES1LABEL");
		if ((check != null) && (check.trim().length() > 0)) {
			notes1Label = check;
		} else {
			notes1Label = "Notes 1";
		}
		check = XMLUtility.getValue(root, "NOTES2LABEL");
		if ((check != null) && (check.trim().length() > 0)) {
			notes2Label = check;
		} else {
			notes2Label = "Notes 2";
		}
		check = XMLUtility.getValue(root, "NOTES3LABEL");
		if ((check != null) && (check.trim().length() > 0)) {
			notes3Label = check;
		} else {
			notes3Label = "Notes 3";
		}
		check = XMLUtility.getValue(root, "NOTES4LABEL");
		if ((check != null) && (check.trim().length() > 0)) {
			notes4Label = check;
		} else {
			notes4Label = "Notes 4";
		}
		check = XMLUtility.getValue(root, "NOTES5LABEL");
		if ((check != null) && (check.trim().length() > 0)) {
			notes5Label = check;
		} else {
			notes5Label = "Notes 5";
		}

		check = XMLUtility.getValue(root, "LANGUAGESIMILARITIESUSED");
		if ((check != null) && check.trim().toUpperCase().startsWith("Y")) {
			languageSimilaritiesUsed = true;
		} else {
			languageSimilaritiesUsed = false;
		}

		check = XMLUtility.getValue(root, "LITERACYFREE");
		if ((check != null) && check.trim().toUpperCase().startsWith("Y")) {
			literacyFree = true;
		} else {
			literacyFree = false;
		}

		check = XMLUtility.getValue(root, "NATIVELITERACYFREE");
		if ((check != null) && check.trim().toUpperCase().startsWith("Y")) {
			nativeLiteracyFree = true;
		} else {
			nativeLiteracyFree = false;
		}

		dirty = false;

		check = XMLUtility.getValue(root, "LINKACROSSFRAMEWORK");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				int test = Integer.parseInt(check);
				if ((test >= Rules.IGNORE) && (test <= Rules.DONOTALLOW)) {
					linkAcrossFramework = test;
				} else {
					linkAcrossFramework = Rules.DONOTALLOW;
				}
			} catch (NumberFormatException e) {
				linkAcrossFramework = Rules.DONOTALLOW;
			}
		} else {
			linkAcrossFramework = Rules.DONOTALLOW;
		}

		check = XMLUtility.getValue(root, "SPECIALTYPEINFRAMEWORK");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				int test = Integer.parseInt(check);
				if ((test >= Rules.IGNORE) && (test <= Rules.DONOTALLOW)) {
					specialTypeInFramework = test;
				} else {
					specialTypeInFramework = Rules.DONOTALLOW;
				}
			} catch (NumberFormatException e) {
				specialTypeInFramework = Rules.DONOTALLOW;
			}
		} else {
			specialTypeInFramework = Rules.DONOTALLOW;
		}

		check = XMLUtility.getValue(root, "NONENDUSINGABILITYINEC");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				int test = Integer.parseInt(check);
				if ((test >= Rules.IGNORE) && (test <= Rules.DONOTALLOW)) {
					nonENDUsingAbilityInEC = test;
				} else {
					nonENDUsingAbilityInEC = Rules.DONOTALLOW;
				}
			} catch (NumberFormatException e) {
				nonENDUsingAbilityInEC = Rules.DONOTALLOW;
			}
		} else {
			nonENDUsingAbilityInEC = Rules.DONOTALLOW;
		}

		check = XMLUtility.getValue(root, "AUTOMATICALLYAPPLYNOFIGURED");
		if ((check != null) && check.trim().toUpperCase().startsWith("N")) {
			automaticallyApplyNoFigured = false;
		} else {
			automaticallyApplyNoFigured = true;
		}
		
		characteristicMaxima = new Hashtable<String, Integer>();
		List<Attribute> atts = root.getAttributes();
		ArrayList<GenericObject> chars = HeroDesigner.getActiveTemplate().getCharacteristics();
		OUTER: for (int i=0; i<atts.size(); i++) {
			Attribute att = atts.get(i);
			int val = 999;
			try {
				val = Integer.parseInt(att.getValue());
			} catch(Exception exp) {
				val=999;
			}
			if (att.getName().endsWith("_MAX")) {
				String id = att.getName().substring(0, att.getName().indexOf("_MAX"));
				for (GenericObject go:chars) {
					if (go.getXMLID().equals(id)) {
						characteristicMaxima.put(go.getXMLID(),val);
						continue OUTER;
					}
				}
			}
		}
	}

	public void saveRulesDefinition(String filePath) {
		try {
			Element root = getRulesXML();

			Format format = Format.getPrettyFormat();
			format.setEncoding("UTF-8");
			XMLOutputter outputter = new XMLOutputter(format);
			FileOutputStream out = new FileOutputStream(filePath);
			outputter.output(new Document(root), out);
			out.close();
			currentSet = filePath;
			HeroDesigner.getInstance().getPrefs().setLastRule(filePath);
			HeroDesigner.getInstance().getPrefs().setRulesDir(
					new File(filePath).getParent());
			dirty = false;
		} catch (Exception exp) {
			exp.printStackTrace();
			JOptionPane.showMessageDialog(HeroDesigner.getAppFrame(),
					"An error occurred saving the rules file.\n\nError Message: "
							+ exp.getMessage(), "Error saving rules",
					JOptionPane.ERROR_MESSAGE);
		}
	}

	public void setAPPerEND(int val) {
		if (val != APPerEND) {
			dirty = true;
		}
		APPerEND = val;
	}

	/**
	 * @param i
	 */
	public void setAttackAPMaxResponse(int i) {
		if (i != attackAPMaxResponse) {
			dirty = true;
		}
		attackAPMaxResponse = i;
	}

	/**
	 * @param i
	 */
	public void setAttackAPMaxValue(int i) {
		if (i != attackAPMaxValue) {
			dirty = true;
		}
		attackAPMaxValue = i;
	}

	public void setAutomaticallyApplyNoFigured(boolean val) {
		if (val != automaticallyApplyNoFigured) {
			dirty = true;
		}
		automaticallyApplyNoFigured = val;
	}

	/**
	 * @param i
	 */
	public void setAvailDisadPointsResponse(int i) {
		if (i != availDisadPointsResponse) {
			dirty = true;
		}
		availDisadPointsResponse = i;
	}

	/**
	 * @param i
	 */
	public void setAvailTotalPointsResponse(int i) {
		if (i != availTotalPointsResponse) {
			dirty = true;
		}
		availTotalPointsResponse = i;
	}

	public void setBasePoints(int i) {
		if (i != basePoints) {
			dirty = true;
		}
		basePoints = i;
	}

	public void setCampaignSet(String val) {
		campaignSet = val;
	}

	/**
	 * @param i
	 */
	public void setCharacteristicMaxResponse(int i) {
		if (i != characteristicMaxResponse) {
			dirty = true;
		}
		characteristicMaxResponse = i;
	}

	/**
	 * @param i
	 */
	public void setCharacteristicMaxValue(int i) {
		if (i != characteristicMaxValue) {
			dirty = true;
		}
		characteristicMaxValue = i;
	}

	public void setCurrentSet(String val) {
		currentSet = val;
	}

	public void setDefaultStandardEffect(boolean val) {
		defaultStandardEffect = val;
	}

	/**
	 * @param i
	 */
	public void setDefenseAPMaxResponse(int i) {
		if (i != defenseAPMaxResponse) {
			dirty = true;
		}
		defenseAPMaxResponse = i;
	}

	/**
	 * @param i
	 */
	public void setDefenseAPMaxValue(int i) {
		if (i != defenseAPMaxValue) {
			dirty = true;
		}
		defenseAPMaxValue = i;
	}

	/**
	 * @param i
	 */
	public void setDisadCategoryMaxResponse(int i) {
		if (i != disadCategoryMaxResponse) {
			dirty = true;
		}
		disadCategoryMaxResponse = i;
	}

	/**
	 * @param i
	 */
	public void setDisadCategoryMaxValue(int i) {
		if (i != disadCategoryMaxValue) {
			dirty = true;
		}
		disadCategoryMaxValue = i;
	}

	public void setDisadPoints(int i) {
		if (i != disadPoints) {
			dirty = true;
		}
		disadPoints = i;
	}

	public void setEquipmentAllowed(boolean val) {
		equipmentAllowed = val;
	}

	/**
	 * @param d
	 */
	public void setEquipmentCostConversion(double d) {
		if (d != 0) {
			equipmentCostConversion = d;
		}
	}

	/**
	 * @param i
	 */
	public void setEquipmentCostDecimalPlaces(int i) {
		equipmentCostDecimalPlaces = i;
	}

	/**
	 * @param i
	 */
	public void setEquipmentCostResponse(int i) {
		if (i != equipmentCostResponse) {
			dirty = true;
		}
		equipmentCostResponse = i;
	}

	/**
	 * @param string
	 */
	public void setEquipmentCostUnits(String string) {
		if (string.equals(equipmentCostUnits)) {
			dirty = true;
		}
		equipmentCostUnits = string;
	}

	/**
	 * @param i
	 */
	public void setEquipmentCostValue(int i) {
		if (i != equipmentCostValue) {
			dirty = true;
		}
		equipmentCostValue = i;
	}

	public void setEquipmentUnitsPrefix(boolean b) {
		if (b != equipmentUnitsPrefix) {
			dirty = true;
		}
		equipmentUnitsPrefix = b;
	}

	/**
	 * @param b
	 */
	public void setLanguageSimilaritiesUsed(boolean b) {
		if (b != languageSimilaritiesUsed) {
			dirty = true;
		}
		languageSimilaritiesUsed = b;
	}

	public void setLinkAcrossFramework(int val) {
		linkAcrossFramework = val;
	}

	public void setLiteracyFree(boolean b) {
		if (b != literacyFree) {
			dirty = true;
		}
		literacyFree = b;
	}

	/**
	 * @param i
	 */
	public void setManeuverMaxResponse(int i) {
		maneuverMaxResponse = i;
	}

	/**
	 * @param i
	 */
	public void setManeuverMaxValue(int i) {
		maneuverMaxValue = i;
	}

	public void setMultiplierAllowed(boolean val) {
		multiplierAllowed = val;
	}

	public void setName(String val) {
		name = val;
	}

	public void setNativeLiteracyFree(boolean b) {
		if (b != nativeLiteracyFree) {
			dirty = true;
		}
		nativeLiteracyFree = b;
	}

	public void setNCMSelected(boolean val) {
		ncmSelected = val;
	}

	public void setNCMUserChangeable(boolean val) {
		ncmUserChangeable = val;
	}

	public void setNonENDUsingAbilityInEC(int val) {
		nonENDUsingAbilityInEC = val;
	}

	public void setNotes1Label(String val) {
		if (getNotes1Label().equals(val)) {
			return;
		}
		notes1Label = val;
		dirty = true;
	}

	public void setNotes2Label(String val) {
		if (getNotes2Label().equals(val)) {
			return;
		}
		notes2Label = val;
		dirty = true;
	}

	public void setNotes3Label(String val) {
		if (getNotes3Label().equals(val)) {
			return;
		}
		notes3Label = val;
		dirty = true;
	}

	public void setNotes4Label(String val) {
		if (getNotes4Label().equals(val)) {
			return;
		}
		notes4Label = val;
		dirty = true;
	}

	public void setNotes5Label(String val) {
		if (getNotes5Label().equals(val)) {
			return;
		}
		notes5Label = val;
		dirty = true;
	}

	public void setOnlySellOneFigured(boolean val) {
		onlySellOneFigured = val;
	}

	public void setPenalizeNoLevel1(boolean val) {
		penalizeNoLevel1 = val;
	}

	/**
	 * @param i
	 */
	public void setPerkMaxResponse(int i) {
		if (i != perkMaxResponse) {
			dirty = true;
		}
		perkMaxResponse = i;
	}

	/**
	 * @param i
	 */
	public void setPerkMaxValue(int i) {
		if (i != perkMaxValue) {
			dirty = true;
		}
		perkMaxValue = i;
	}

	/**
	 * @param i
	 */
	public void setPowerMaxResponse(int i) {
		if (i != powerMaxResponse) {
			dirty = true;
		}
		powerMaxResponse = i;
	}

	/**
	 * @param i
	 */
	public void setPowerMaxValue(int i) {
		if (i != powerMaxValue) {
			dirty = true;
		}
		powerMaxValue = i;
	}

	public void setSkillMaximaLimit(int skillMaximaLimit) {
		this.skillMaximaLimit = skillMaximaLimit;
	}

	/**
	 * @param i
	 */
	public void setSkillMaxResponse(int i) {
		if (i != skillMaxResponse) {
			dirty = true;
		}
		skillMaxResponse = i;
	}

	/**
	 * @param i
	 */
	public void setSkillMaxValue(int i) {
		if (i != skillMaxValue) {
			dirty = true;
		}
		skillMaxValue = i;
	}

	public void setSpecialTypeInFramework(int val) {
		specialTypeInFramework = val;
	}

	/**
	 * @param b
	 */
	public void setStandardEffectAllowed(boolean b) {
		if (b != standardEffectAllowed) {
			dirty = true;
		}
		standardEffectAllowed = b;
	}

	public void setSTRAPPerEND(int val) {
		STRAPPerEND = val;
	}

	/**
	 * @param i
	 */
	public void setTalentMaxResponse(int i) {
		if (i != talentMaxResponse) {
			dirty = true;
		}
		talentMaxResponse = i;
	}

	/**
	 * @param i
	 */
	public void setTalentMaxValue(int i) {
		if (i != talentMaxValue) {
			dirty = true;
		}
		talentMaxValue = i;
	}

	public void setUseExpandedGrowthChart(boolean val) {
		if (val != useExpandedGrowthChart) {
			dirty = true;
		}
		useExpandedGrowthChart = val;
	}

	public void setUseIncreasedDamageDifferentiation(boolean val) {
		if (useIncreasedDamageDifferentiation != val) {
			dirty = true;
		}
		useIncreasedDamageDifferentiation = val;
	}

	public void setUseNotes1(boolean val) {
		if (useNotes1 == val) {
			return;
		}
		useNotes1 = val;
		dirty = true;
	}

	public void setUseNotes2(boolean val) {
		if (useNotes2 == val) {
			return;
		}
		useNotes2 = val;
		dirty = true;
	}

	public void setUseNotes3(boolean val) {
		if (useNotes3 == val) {
			return;
		}
		useNotes3 = val;
		dirty = true;
	}

	public void setUseNotes4(boolean val) {
		if (useNotes4 == val) {
			return;
		}
		useNotes4 = val;
		dirty = true;
	}

	public void setUseNotes5(boolean val) {
		if (useNotes5 == val) {
			return;
		}
		useNotes5 = val;
		dirty = true;
	}

	public void setUseSkillMaxima(boolean useSkillMaxima) {
		this.useSkillMaxima = useSkillMaxima;
	}

	public void setUseSkillMultipliers(boolean val) {
		useSkillMultipliers = val;
	}
	
	public void setLanguagesAsINTSkill(boolean val) {
		languagesAsINTSkill = val;
	}

	public void useDefault() {
		name = "";
		basePoints = 200;
		disadPoints = 150;
		APPerEND = 10;
		STRAPPerEND = 10;
		ncmSelected = false;
		useSkillMaxima = false;
		skillMaximaLimit = 13;
		ncmUserChangeable = true;
		attackAPMaxValue = 90;
		attackAPMaxResponse = Rules.IGNORE;
		defenseAPMaxValue = 90;
		defenseAPMaxResponse = Rules.IGNORE;
		disadCategoryMaxValue = 75;
		disadCategoryMaxResponse = Rules.IGNORE;
		availDisadPointsResponse = Rules.IGNORE;
		availTotalPointsResponse = Rules.IGNORE;
		characteristicMaxValue = 1000;
		characteristicMaxResponse = Rules.IGNORE;
		skillMaxValue = 1000;
		skillMaxResponse = Rules.IGNORE;
		perkMaxValue = 1000;
		perkMaxResponse = Rules.IGNORE;
		talentMaxValue = 1000;
		talentMaxResponse = Rules.IGNORE;
		powerMaxValue = 1000;
		powerMaxResponse = Rules.IGNORE;
		equipmentCostValue = 1000;
		equipmentCostResponse = Rules.IGNORE;
		equipmentCostUnits = "$";
		equipmentCostConversion = 1;
		equipmentCostDecimalPlaces = 0;
		equipmentUnitsPrefix = true;
		standardEffectAllowed = true;
		useExpandedGrowthChart = false;
		defaultStandardEffect = false;
		multiplierAllowed = false;
		languageSimilaritiesUsed = false;
		literacyFree = false;
		nativeLiteracyFree = true;
		maneuverMaxResponse = Rules.IGNORE;
		maneuverMaxValue = 1000;
		equipmentAllowed = false;
		penalizeNoLevel1 = false;
		onlySellOneFigured = true;
		useIncreasedDamageDifferentiation = false;
		linkAcrossFramework = Rules.DONOTALLOW;
		specialTypeInFramework = Rules.WARN;
		nonENDUsingAbilityInEC = Rules.WARN;
		automaticallyApplyNoFigured = true;
		useNotes1 = false;
		useNotes2 = false;
		useNotes3 = false;
		useNotes4 = false;
		useNotes5 = false;
		notes1Label = "Notes 1";
		notes2Label = "Notes 2";
		notes3Label = "Notes 3";
		notes4Label = "Notes 4";
		notes5Label = "Notes 5";

		currentSet = "Default";
		campaignSet = "";
		dirty = false;
		characteristicMaxima = new Hashtable<String,Integer>();
	}

	public boolean useExpandedGrowthChart() {
		return useExpandedGrowthChart;
	}

	public boolean useIncreasedDamageDifferentiation() {
		return useIncreasedDamageDifferentiation;
	}

	public boolean useNotes1() {
		return useNotes1;
	}

	public boolean useNotes2() {
		return useNotes2;
	}

	public boolean useNotes3() {
		return useNotes3;
	}

	public boolean useNotes4() {
		return useNotes4;
	}

	public boolean useNotes5() {
		return useNotes5;
	}

	public boolean useSkillMultipliers() {
		return useSkillMultipliers;
	}
	
	public boolean useLanguagesAsINTSkill() {
		return languagesAsINTSkill;
	}

}