package com.hero.objects.skills;

import java.util.ArrayList;
import java.util.Iterator;

import org.jdom.Element;

import com.hero.HeroDesigner;
import com.hero.objects.Adder;
import com.hero.objects.GenericObject;
import com.hero.objects.characteristics.Characteristic;
import com.hero.objects.powers.Automaton;
import com.hero.ui.dialog.GenericDialog;
import com.hero.ui.dialog.SkillDialog;
import com.hero.util.Constants;
import com.hero.util.Rounder;
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 Skill extends GenericObject {
	protected boolean area;

	protected int characteristic;

	protected ArrayList<CharacteristicChoice> characteristicChoices;

	protected boolean contact;

	protected boolean everyman;

	protected boolean familiarity;

	protected int familiarityCost;

	protected int familiarityRoll;

	protected boolean includeFamiliarity;

	protected boolean proficiency;

	protected int proficiencyCost;

	protected int proficiencyRoll;

	protected boolean includeProficiency;

	protected boolean knowledge;

	protected boolean language;

	protected boolean professional;

	protected boolean levelsOnly;

	protected boolean displayLevelsOnly;

	protected boolean scientist;

	protected boolean rollBased = true;

	public Skill(Element template) {
		super(template);
	}

	public Skill(Element template, String xmlID) {
		super(template, xmlID);
	}

	@Override
	public double getBaseCost() {
		if (isFamiliarity() && isEveryman()) {
			return 0;
		} else if (isFamiliarity() && (familiarityCost < super.getBaseCost())) {
			return familiarityCost;
		} else if (isProficiency() && (proficiencyCost < super.getBaseCost())) {
			return proficiencyCost;
		} else if (levelsOnly) {
			return 0;
		} else {
			return super.getBaseCost();
		}
	}

	/**
	 * Returns the Characteristic that the Skill is based off of (if
	 * applicable).
	 * 
	 * @see com.hero.util.Constants
	 * @return
	 */
	public int getCharacteristic() {
		return characteristic;
	}
	
	/**
	 * Returns the string value of the Characteristic that the Skill is based off of (if applicable)
	 * If no Characteristic has been assigned, an empty string will be returned.
	 * 
	 * @return
	 */
	public String getCharacteristicString() {
		if (characteristic < 0) return "";
		return Constants.getCharacteristicString(getCharacteristic());
	}

	/**
	 * Returns a Vector of CharacteristicChoice objects which are available for
	 * this Skill.
	 * 
	 * @see com.hero.objects.skills.CharacteristicChoice
	 * @return
	 */
	public ArrayList<CharacteristicChoice> getCharacteristicChoices() {
		if (characteristicChoices == null) {
			characteristicChoices = new ArrayList<CharacteristicChoice>();
		}
		return characteristicChoices;
	}
	
	protected boolean showRoll = true;
	public String getColumn2OutputWithoutRoll() {
		showRoll = false;
		String holder = getName();
		setName("");
		String ret = getColumn2Output();
		showRoll = true;
		setName(holder);
		return ret;
	}

	@Override
	public String getColumn2Output() {
		if (levelsOnly) {
			return getLevelOnlyOutput();
		}
		String ret = getAlias();
		if (displayLevelsOnly) {
			if (getLevels() > 0) {
				ret = "+";
			} else {
				ret = "";
			}
			ret += getLevels();
		}
		if ((getName() != null) && (getName().trim().length() > 0)) {
			ret = "<i>" + getName() + ":</i>  " + ret;
		}
		if ((getInput() != null) && (getInput().trim().length() > 0)) {
			ret += ":  " + getInput();
		}
		if (getSelectedOption() != null) {
			if (!displayLevelsOnly) {
				ret += ":  " + getSelectedOption().getAlias();
			} else {
				ret += " " + getSelectedOption().getAlias();
			}
		}
		if (!HeroDesigner.getInstance().getPrefs().useWG()
				&& (getCharacteristicChoices() != null)
				&& (getCharacteristicChoices().size() > 1)
				&& !(getCharacteristic() == Constants.GENERAL)) {
			ret += " ("
					+ Constants.getCharacteristicString(getCharacteristic())
					+ "-based)";
		}
		String adderString = getAdderString();
		if (adderString.trim().length() > 0) {
			ret += " (";
			ret += adderString;
			ret += ")";
		}
		if (!displayLevelsOnly && showRoll) {
			ret += " " + getRoll();
		}
		ret += getModifierString();
		if ((getEndUsage() > 0)
				&& (GenericObject.findObjectByID(HeroDesigner.getActiveHero()
						.getPowers(), "ENDURANCERESERVE") != null)
				&& (GenericObject.findObjectByID(getAllAssignedModifiers(),
						"ENDRESERVEOREND") == null)
				&& !HeroDesigner.getInstance().getPrefs().useWG()) {
			if (getUseENDReserve()) {
				ret += " (uses END Reserve)";
			} else {
				ret += " (uses Personal END)";
			}
		}
		return ret;
	}

	@Override
	public String getColumn3Output() {
		if (getEndUsage() > 0) {
			return "" + getEndUsage();
		} else {
			return "";
		}
	}

	@Override
	public GenericDialog getDialog(boolean isNew, boolean isPower) {
		SkillDialog dialog = new SkillDialog(this, isNew, isPower);
		return dialog;
	}

	/**
	 * Returns the roll value to use if the Skill is a Familiarity only
	 * (typically 8).
	 * 
	 * @return
	 */
	public int getFamiliarityRoll() {
		return familiarityRoll;
	}

	public int getProficiencyRoll() {
		return proficiencyRoll;
	}

	protected String getLevelOnlyOutput() {
		String ret = getLevels() >= 0 ? "+" : "-";
		if ((getName() != null) && (getName().trim().length() > 0)) {
			ret = "<i>" + getName() + ":</i>  " + ret;
		}
		ret += getLevels() + " with " + getAlias();
		if (getInput().trim().length() > 0) {
			ret += ": " + getInput();
		}
		String adderString = getAdderString();
		if (adderString.trim().length() > 0) {
			ret += " (";
			ret += adderString;
			ret += ")";
		}
		ret += getModifierString();
		if ((getEndUsage() > 0)
				&& (GenericObject.findObjectByID(HeroDesigner.getActiveHero()
						.getPowers(), "ENDURANCERESERVE") != null)
				&& (GenericObject.findObjectByID(getAllAssignedModifiers(),
						"ENDRESERVEOREND") == null)
				&& !HeroDesigner.getInstance().getPrefs().useWG()) {
			if (getUseENDReserve()) {
				ret += " (uses END Reserve)";
			} else {
				ret += " (uses Personal END)";
			}
		}
		return ret;
	}

	@Override
	public int getLevels() {
		if (isFamiliarity()) {
			return 0;
		} else if (isProficiency()) {
			return 0;
		} else {
			return super.getLevels();
		}
	}

	@Override
	public double getMinimumCost() {
		if (isEveryman()) {
			return 0;
		}
		if (isFamiliarity()) {
			return familiarityCost;
		}
		if (isProficiency()) {
			return proficiencyCost;
		}
		if (levelsOnly()) {
			return 0;
		} else {
			return minimumCost;
		}
	}

	@Override
	public double getRealCostPreList() {
		boolean customAdders = false;
		for (int i = 0; i < getAssignedAdders().size(); i++) {
			Adder ad = getAssignedAdders().get(i);
			if (GenericObject.findObjectByID(getAvailableAdders(), ad
					.getXMLID()) == null) {
				// custom adder
				customAdders = true;
				break;
			}
		}

		if (customAdders) {
			return super.getRealCostPreList();
		}
		if (isFamiliarity() && isEveryman()) {
			return 0;
		} else {
			return super.getRealCostPreList();
		}
	}

	/**
	 * Returns a String representing the roll required for this Skill (split if
	 * necessary).
	 * 
	 * @return
	 */
	public String getRoll() {
		if (displayLevelsOnly) {
			return "";
		}
		if (levelsOnly) {
			String ret = getLevels() >= 0 ? "+" : "-";
			ret += getLevels() + " with " + getAlias();
			return ret;
		}
		if ((levelValue < 1) && (levelCost < 1)) {
			return "";
		}
		int roll1 = getRollValue();
		int roll2 = getSecondaryRollValue();
		String ret = "";
		if (roll1 == 0) {
			return "";
		}
		if (roll1 != roll2) {
			ret = roll1 + "-" + " (" + roll2 + "-)";
		} else {
			ret = roll1 + "-";
		}
		return ret;
	}

	/**
	 * Returns an int representing the value that must be rolled under to
	 * succeed with the Skill.
	 * 
	 * @return
	 */
	public int getRollValue() {
		int ret = 0;
		if (isFamiliarity()) {
			if (getFamiliarityRoll() > 0) {
				ret = getFamiliarityRoll();
			} else {
				ret = 8;
			}
		} else if (isProficiency()) {
			if (getProficiencyRoll() > 0) {
				ret = getProficiencyRoll();
			} else {
				ret = 10;
			}
		} else if (isFocus() && HeroDesigner.getActiveHero() != null) {
			int roll = HeroDesigner.getActiveHero().getRules()
					.getSkillRollBase();
			if (getLevels() < 0) {
				roll = getMinimumLevel();
			} else {
				roll = roll + getLevels();
			}
			ret = roll;
		} else if (HeroDesigner.getActiveHero() != null) {
			Characteristic charac = HeroDesigner.getActiveHero()
					.getCharacteristic(characteristic);
			int roll = HeroDesigner.getActiveHero().getRules()
					.getSkillRollBase();
			if ((charac != null) && !charac.getXMLID().equals("GENERAL")) {
				roll = HeroDesigner.getActiveHero().getRules()
						.getSkillRollBase()
						+ (int) (Rounder.roundHalfUp(charac.getPrimaryValue()
								/ HeroDesigner.getActiveHero().getRules()
										.getSkillRollDenominator()) + getLevels()
								* getLevelValue());
			} else if (characteristic == Constants.GENERAL) {
				roll = HeroDesigner.getActiveHero().getRules()
						.getSkillRollBase()
						+ (int) (Rounder.roundHalfUp(HeroDesigner
								.getActiveTemplate().getGeneralLevel()
								/ HeroDesigner.getActiveHero().getRules()
										.getSkillRollDenominator()) + getLevels()
								* getLevelValue());
			} else {
				roll = HeroDesigner.getActiveHero().getRules()
						.getSkillRollBase()
						+ (int) Rounder.roundHalfUp(getLevels()
								* getLevelValue());
			}
			ret = roll;
		} else {
			int roll = 9
					+ (int) (Rounder.roundHalfUp(HeroDesigner
							.getActiveTemplate().getGeneralLevel()
							/ 5) + getLevels()
							* getLevelValue());
			ret = roll;
		}

		return ret;
	}

	@Override
	public Element getSaveXML() {
		Element root = getGeneralSaveXML();
		root.setName("SKILL");
		root.setAttribute("CHARACTERISTIC", Constants
				.getCharacteristicString(getCharacteristic()));
		root.setAttribute("FAMILIARITY", isFamiliarity() ? "Yes" : "No");
		root.setAttribute("PROFICIENCY", isProficiency() ? "Yes" : "No");
		if (levelsOnlyAllowed()) {
			root.setAttribute("LEVELSONLY", levelsOnly() ? "Yes" : "No");
		}
		if (isFamiliarity()) {
			root.setAttribute("EVERYMAN", isEveryman() ? "Yes" : "No");
		}
		return root;
	}

	/**
	 * Returns the secondary value for the roll (may be the same as
	 * getRollValue()).
	 * 
	 * @return
	 */
	public int getSecondaryRollValue() {
		int ret = 0;
		if (isFamiliarity()) {
			if (getFamiliarityRoll() > 0) {
				ret = getFamiliarityRoll();
			} else {
				ret = 8;
			}
		} else if (isProficiency()) {
			if (getProficiencyRoll() > 0) {
				ret = getProficiencyRoll();
			} else {
				ret = 10;
			}
		} else if (isFocus() && HeroDesigner.getActiveHero() != null) {
			int roll = HeroDesigner.getActiveHero().getRules()
					.getSkillRollBase();
			if (getLevels() < 0) {
				roll = getMinimumLevel();
			} else {
				roll = roll + getLevels();
			}
			ret = roll;
		} else if (HeroDesigner.getActiveHero() != null) {
			Characteristic charac = HeroDesigner.getActiveHero()
					.getCharacteristic(characteristic);
			int roll = HeroDesigner.getActiveHero().getRules()
					.getSkillRollBase();
			int roll2 = HeroDesigner.getActiveHero().getRules()
					.getSkillRollBase();

			if ((charac != null) && !charac.getXMLID().equals("GENERAL")) {
				roll = HeroDesigner.getActiveHero().getRules()
						.getSkillRollBase()
						+ (int) (Rounder.roundHalfUp(charac.getPrimaryValue()
								/ HeroDesigner.getActiveHero().getRules()
										.getSkillRollDenominator()) + getLevels()
								* getLevelValue());
				roll2 = HeroDesigner.getActiveHero().getRules()
						.getSkillRollBase()
						+ (int) (Rounder.roundHalfUp(charac.getSecondaryValue()
								/ HeroDesigner.getActiveHero().getRules()
										.getSkillRollDenominator()) + getLevels()
								* getLevelValue());
			} else if (characteristic == Constants.GENERAL) {
				roll = HeroDesigner.getActiveHero().getRules()
						.getSkillRollBase()
						+ (int) (Rounder.roundHalfUp(HeroDesigner
								.getActiveTemplate().getGeneralLevel()
								/ HeroDesigner.getActiveHero().getRules()
										.getSkillRollDenominator()) + getLevels()
								* getLevelValue());
				roll2 = roll;
			} else {
				roll = HeroDesigner.getActiveHero().getRules()
						.getSkillRollBase()
						+ (int) Rounder.roundHalfUp(getLevels()
								* getLevelValue());
				roll2 = roll;
			}
			ret = roll2;
		} else {
			int roll = 9
					+ (int) (Rounder.roundHalfUp(HeroDesigner
							.getActiveTemplate().getGeneralLevel()
							/ 5) + getLevels()
							* getLevelValue());
			ret = roll;
		}

		return ret;
	}

	@Override
	public double getTotalCost() {
		double total = getBaseCost();
		ArrayList<Adder> availAds = getAvailableAdders();
		if (getLevelValue() != 0) {
			total += getLevels() / getLevelValue() * getLevelCost();
			if ((getLevels() > 0)
					&& HeroDesigner.getActiveHero().getRules()
							.getUseSkillMaxima() && rollBased) {
				int limit = HeroDesigner.getActiveHero().getRules()
						.getSkillMaximaLimit();
				int roll = getRollValue();
				int sec = getSecondaryRollValue();
				if (sec > roll) {
					roll = sec;
				}
				if (roll > limit) {
					int expensive = roll - limit;
					if (expensive > getLevels()) {
						expensive = getLevels();
					}
					total += expensive / getLevelValue() * getLevelCost();
				}
			}
			if (getLevelCost() < getLevelValue()) {
				if ((total > 0) && (total < 1)) {
					total = 1;
				} else {
					total = Rounder.roundHalfDown(total);
				}
			}
		}
		for (Adder ad : getAssignedAdders()) {
			if (ad.isRequired()) {
				total += ad.getRealCost();
			}
		}
		for (Adder ad : getAssignedAdders()) {
			if (!ad.isRequired()
					&& (GenericObject.findObjectByID(availAds, ad.getXMLID()) != null)) {
				total += ad.getRealCost();
			}
		}
		if ((total < getMinimumCost()) && isMinSet() && !levelsOnly) {
			total = getMinimumCost();
		} else if ((total > getMaxCost()) && isMaxSet() && !levelsOnly) {
			total = getMaxCost();
		}
		for (Adder ad : getAssignedAdders()) {
			if (!ad.isRequired()
					&& (GenericObject.findObjectByID(availAds, ad.getXMLID()) == null)) {
				total += ad.getRealCost();
			}
		}
		if (getTypes().contains("DEFENSE")
				&& (HeroDesigner.getActiveHero() != null)) {
			if (GenericObject.findObjectByID(HeroDesigner.getActiveHero()
					.getPowers(), "AUTOMATON") != null) {
				Automaton auto = (Automaton) GenericObject.findObjectByID(
						HeroDesigner.getActiveHero().getPowers(), "AUTOMATON");
				if (auto.getSelectedOption().getXMLID().toUpperCase()
						.startsWith("NOSTUN")) {
					total = total * auto.getDefenseCostMultiplier();
				}
			}
		}
		return total;
	}

	/**
	 * Whether or not to include the Familiarity only checkbox.
	 * 
	 * @return
	 */
	public boolean includeFamiliarity() {
		return includeFamiliarity;
	}

	public boolean includeProficiency() {
		return includeProficiency;
	}

	@Override
	protected void init(Element element) {
		characteristicChoices = new ArrayList<CharacteristicChoice>();
		familiarityRoll = 8;
		proficiencyRoll = 10;
		includeFamiliarity = false;
		includeProficiency = false;
		proficiencyCost = 2;
		duration = "CONSTANT";

		super.init(element);
		target = "SELFONLY";
		if (!types.contains("SPECIAL")) {
			types.add("SPECIAL");
		}
		if (types.contains("SCIENCE")) {
			scientist = true;
		} else {
			scientist = false;
		}
		if (types.contains("PROFESSIONAL")) {
			professional = true;
		} else {
			professional = false;
		}
		if (types.contains("LANGUAGE")) {
			language = true;
		} else {
			language = false;
		}
		if (types.contains("KNOWLEDGE")) {
			knowledge = true;
		} else {
			knowledge = false;
		}
		if (types.contains("AREA")) {
			area = true;
		} else {
			area = false;
		}
		if (types.contains("CONTACT")) {
			contact = true;
		} else {
			contact = false;
		}
		Element charChoice = element.getChild("CHARACTERISTIC_CHOICE");
		if (charChoice != null) {
			java.util.List choices = charChoice.getChildren("ITEM");
			Iterator iterator = choices.iterator();
			while (iterator.hasNext()) {
				Element item = (Element) iterator.next();
				if (item == null) {
					continue;
				}
				CharacteristicChoice charCh = new CharacteristicChoice(item);
				characteristicChoices.add(charCh);
			}
		}
		String check = XMLUtility.getValue(element, "FAMILIARITYROLL");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				familiarityRoll = Integer.parseInt(check);
			} catch (NumberFormatException ex) {
			}
		}
		check = XMLUtility.getValue(element, "PROFICIENCYROLL");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				proficiencyRoll = Integer.parseInt(check);
			} catch (NumberFormatException ex) {
			}
		}
		check = XMLUtility.getValue(element, "TARGET");
		if ((check != null) && (check.trim().length() > 0)) {
			target = check;
		}
		check = XMLUtility.getValue(element, "FAMILIARITYCOST");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				familiarityCost = Integer.parseInt(check);
				includeFamiliarity = true;
			} catch (NumberFormatException ex) {
				includeFamiliarity = false;
			}
		} else {
			includeFamiliarity = false;
		}
		check = XMLUtility.getValue(element, "PROFICIENCYCOST");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				proficiencyCost = Integer.parseInt(check);
				includeProficiency = true;
			} catch (NumberFormatException ex) {
				includeProficiency = false;
			}
		} else {
			includeProficiency = includeFamiliarity;
		}

		check = XMLUtility.getValue(element, "DISPLAYLEVELSONLY");
		displayLevelsOnly = (check != null)
				&& check.trim().toUpperCase().startsWith("Y");

		/*
		 * check = XMLUtility.getValue(element, "ROLL_BASED"); if (check != null
		 * && check.trim().length()>0) { rollBased =
		 * check.trim().toUpperCase().startsWith("Y"); }
		 */
	}

	/**
	 * Whether the Skill is an Everyman Skill.
	 * 
	 * @return
	 */
	public boolean isEveryman() {
		if (!isFamiliarity()) {
			return false;
		}
		return everyman;
	}

	/**
	 * Whether the Skill is a Familiarity.
	 * 
	 * @return
	 */
	public boolean isFamiliarity() {
		return familiarity && !proficiency;
	}

	public boolean isProficiency() {
		return proficiency;
	}

	protected boolean isFocus() {
		if (GenericObject.findObjectByID(getAssignedModifiers(), "FOCUS") != null) {
			return true;
		}
		if (getParentList() != null) {
			if (GenericObject.findObjectByID(getParentList()
					.getAssignedModifiers(), "FOCUS") != null) {
				return true;
			}
		}
		return false;
	}

	/**
	 * If true, then the base Skill is not purchased, only the levels. This is
	 * useful for assigning different Modifiers to the levels than to the base
	 * Skill (e.g. "Gloves of Lockpicking" and the like).
	 * 
	 * @return
	 */
	public boolean levelsOnly() {
		if ((getRoll().trim().length() > 0) && (getLevelCost() > 0)
				&& (getLevelValue() != 0)) {
			return levelsOnly;
		}
		return false;
	}

	/**
	 * Whether to allow the user to specify levels only purchase. Just a utility
	 * method which checks to be sure that the Skill is level-based.
	 * 
	 * @return
	 */
	public boolean levelsOnlyAllowed() {
		return (getRoll().trim().length() > 0) && (getLevelCost() > 0)
				&& (getLevelValue() != 0);
	}

	@Override
	public void restoreFromSave(Element root) {
		super.restoreFromSave(root);
		String check = XMLUtility.getValue(root, "CHARACTERISTIC");
		if ((check != null) && (check.trim().length() > 0)) {
			setCharacteristic(Constants.getCharacteristicInteger(check));
		}
		check = XMLUtility.getValue(root, "FAMILIARITY");
		if ((check != null) && (check.trim().length() > 0)) {
			setFamiliarity(check.toUpperCase().startsWith("Y"));
		}
		check = XMLUtility.getValue(root, "PROFICIENCY");
		if ((check != null) && (check.trim().length() > 0)) {
			setProficiency(check.toUpperCase().startsWith("Y"));
		}
		check = XMLUtility.getValue(root, "LEVELSONLY");
		if ((check != null) && (check.trim().length() > 0)) {
			setLevelsOnly(check.toUpperCase().startsWith("Y"));
		}
		check = XMLUtility.getValue(root, "EVERYMAN");
		if ((check != null) && check.trim().toUpperCase().startsWith("Y")) {
			setEveryman(true);
		} else {
			setEveryman(false);
		}
	}

	/**
	 * Sets the characteristic to base this skill's roll off of.
	 * 
	 * @param val
	 */
	public void setCharacteristic(int val) {
		for (CharacteristicChoice choice : getCharacteristicChoices()) {
			if (choice.getCharacteristic() == val) {
				characteristic = val;
				if (choice.getBaseCost() >= 0) {
					setBaseCost(choice.getBaseCost());
				}
				if (choice.getLevelCost() >= 0) {
					setLevelCost(choice.getLevelCost());
				}
				if (choice.getLevelValue() >= 0) {
					setLevelValue(choice.getLevelValue());
				}
				if (choice.isMinSet()) {
					setMinimumCost(choice.getMinimumCost());
				}
				if (choice.getMinimumLevel() >= 0) {
					setMinimumLevel(choice.getMinimumLevel());
				}
			}
		}
	}

	/**
	 * Sets whether this is an Everyman Skill.
	 * 
	 * @param val
	 */
	public void setEveryman(boolean val) {
		if (val) {
			levelsOnly = false;
		}
		everyman = val;
	}

	/**
	 * Sets whether this is a Familiarity.
	 * 
	 * @param val
	 */
	public void setFamiliarity(boolean val) {
		if (val) {
			levelsOnly = false;
		}
		familiarity = val;
	}

	public void setProficiency(boolean val) {
		if (val) {
			levelsOnly = false;
		}
		proficiency = val;
	}

	/**
	 * Sets whether the Skill purchase is for levels only (not purchasing the
	 * base Skill).
	 * 
	 * @param val
	 */
	public void setLevelsOnly(boolean val) {
		if (val) {
			familiarity = false;
			everyman = false;
			proficiency = false;
		}
		if ((getRoll().trim().length() > 0) && (getLevelCost() > 0)
				&& (getLevelValue() != 0)) {
			levelsOnly = val;
		} else {
			levelsOnly = false;
		}
	}

}