package com.hero.objects.powers;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
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.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 Clairsentience extends Power {

	private static String xmlID = "CLAIRSENTIENCE";

	protected double nontargetingGroupCost;

	protected double nontargetingSenseCost;

	private boolean oldMethod;

	protected double targetingGroupCost;

	protected double targetingSenseCost;

	public Clairsentience(Element root) {
		super(root, Clairsentience.xmlID);
	}

	public ArrayList<Adder> getAssignedAdders() {
		ArrayList<Adder> ret = super.getAssignedAdders();
		for (int i = ret.size() - 1; i >= 0; i--) {
			Adder ad = ret.get(i);
			if (ad.getXMLID().equals("CONCEALED")) {
				if (GenericObject.findObjectByID(ret, "TRANSMIT") != null) {
					ad.setDisplay("Concealed (-[LVL] with " + getAlias()
							+ " PER Rolls)");
					ad.setAlias(ad.getDisplay());
				} else {
					ret.remove(i);
					continue;
				}
			} else if (ad.getXMLID().equals("ANALYZESENSE")) {
				if (GenericObject.findObjectByID(ret, "DISCRIMINATORY") == null) {
					//ret.remove(i);
					//not entirely sure why, but this is causing problems...
					//removal of analyze is taken care of by the requires, regardless
				}
			}
		}
		if (oldMethod) {
			return ret;
		}
		ArrayList<Adder> adjusted = new ArrayList<Adder>();
		ArrayList<SenseGroup> allGroups = SenseGroup.getAllGroups();
		ArrayList<Sense> allSenses = Sense.getAllSenses();
		// take care of the conversions from old to new...
		for (Adder ad : ret) {
			if (ad.getXMLID().equals("ADDITIONAL_GROUP")
					|| ad.getXMLID().equals("GROUP")
					|| ad.getXMLID().equals("SENSEGROUP")) {
				if (ad.getSelectedOption() == null) {
					adjusted.add(ad);
				} else {
					GROUPS: for (SenseGroup group : allGroups) {
						if (group.getXMLID().equals(
								ad.getSelectedOption().getXMLID())) {
							if (group.getDefaultSenseAdders().contains(
									"TARGETINGSENSE")
									&& (targetingGroupCost >= 0)) {
								Adder swap = new Adder(group);
								swap.setLevelCost(-1);
								swap.setLevelValue(-1);
								swap.setAvailableAdders(new ArrayList<Adder>());
								swap.setBaseCost(targetingGroupCost);
								swap.setExclusive(true);
								swap
										.setAlias(ad.getSelectedOption()
												.getAlias());
								swap.setSelected(true);
								adjusted.add(swap);
							} else if (!group.getDefaultSenseAdders().contains(
									"TARGETINGSENSE")
									&& (nontargetingGroupCost >= 0)) {
								Adder swap = new Adder(group);
								swap.setLevelCost(-1);
								swap.setLevelValue(-1);
								swap.setAvailableAdders(new ArrayList<Adder>());
								swap.setBaseCost(nontargetingGroupCost);
								swap.setExclusive(true);
								swap
										.setAlias(ad.getSelectedOption()
												.getAlias());
								swap.setSelected(true);
								adjusted.add(swap);
							}
						}
						break GROUPS;
					}
				}
			} else if (ad.getXMLID().equals("ADDITIONAL_SENSE")
					|| ad.getXMLID().equals("SINGLE")) {
				if (ad.getSelectedOption() == null) {
					adjusted.add(ad);
				} else {
					SENSES: for (Sense sense : allSenses) {
						if (sense.getXMLID().equals(
								translateSense(ad.getSelectedOption()
										.getXMLID()))) {
							if (sense.getBuiltInSenseAdders().contains(
									"TARGETINGSENSE")
									&& (targetingSenseCost >= 0)) {
								Adder swap = new Adder(sense);
								swap.setLevelCost(-1);
								swap.setLevelValue(-1);
								swap.setAvailableAdders(new ArrayList<Adder>());
								swap.setBaseCost(targetingSenseCost);
								swap
										.setAlias(ad.getSelectedOption()
												.getAlias());
								swap.setSelected(true);
								swap.setExclusive(true);
								adjusted.add(swap);
							} else if (!sense.getBuiltInSenseAdders().contains(
									"TARGETINGSENSE")
									&& (nontargetingSenseCost >= 0)) {
								Adder swap = new Adder(sense);
								swap.setLevelCost(-1);
								swap.setLevelValue(-1);
								swap.setAvailableAdders(new ArrayList<Adder>());
								swap.setBaseCost(nontargetingSenseCost);
								swap
										.setAlias(ad.getSelectedOption()
												.getAlias());
								swap.setSelected(true);
								swap.setExclusive(true);
								adjusted.add(swap);
							}
							break SENSES;
						}
					}
				}
			} else {
				adjusted.add(ad);
			}
		}
		// now we need to go through and check if any of them need to be
		// removed, based on other purchases...
		ArrayList<SenseGroup> purchasedGroups = new ArrayList<SenseGroup>();
		if (selectedOption != null) {
			SenseGroup option = SenseGroup.getGroupByID(selectedOption
					.getXMLID());
			if (option != null) {
				purchasedGroups.add(option);
			}
		}
		for (int i = adjusted.size() - 1; i >= 0; i--) {
			Adder ad = adjusted.get(i);
			if (ad.getXMLID().endsWith("GROUP")) {
				SenseGroup group = SenseGroup.getGroupByID(ad.getXMLID());
				if (group != null) {
					if (purchasedGroups.contains(group)) {
						adjusted.remove(i);
					} else {
						purchasedGroups.add(group);
					}
				}
			}
		}
		// now check the senses
		for (int i = adjusted.size() - 1; i >= 0; i--) {
			Adder ad = adjusted.get(i);
			if (!ad.getXMLID().endsWith("GROUP")) {
				Sense sense = Sense.getSenseByID(ad.getXMLID());
				if (sense != null) {
					SenseGroup group = sense.getGroup();
					if (purchasedGroups.contains(group)) {
						adjusted.remove(i);
					}
				}
			}
		}
		assignedAdders = adjusted;
		return adjusted;
	}

	public ArrayList<Adder> getAvailableAdders() {
		ArrayList<Adder> ret = (ArrayList<Adder>) super.getAvailableAdders()
				.clone();
		if (oldMethod) {
			return ret;
		}

		ArrayList<String> added = new ArrayList<String>();
		ArrayList<Adder> automatic = new ArrayList<Adder>();
		ArrayList<SenseAdder> all = SenseAdder.getAllSenseAdders();
		ArrayList<Adder> assigned = getAssignedAdders();
		ArrayList<Adder> avail = new ArrayList<Adder>();
		for (Adder ad : assigned) {
			if (ad.getXMLID().equals("GENERIC_OBJECT")) {
				continue;
			}
			if (GenericObject.findObjectByID(ret, ad.getXMLID()) != null) {
				continue;
			}
			avail.add(ad);
			added.add(ad.getXMLID());
		}
		for (SenseAdder o : all) {
			if (o.getXMLID().equals("RANGE")
					|| o.getXMLID().equals("CONCEALED")
					|| o.getXMLID().equals("MAKEASENSE")) {
				continue;
			}
			if (!added.contains(o.getXMLID())) {
				if (o.getXMLID().equals("INCREASEDARC240")) {
					continue;
				}
				Adder ad = new Adder(o);
				ad.setExclusive(true);
				if (o.getXMLID().equals("ANALYZESENSE")) {
					ad.getRequires().add("DISCRIMINATORY");
				} else if (ad.getXMLID().equals("ENHANCEDPERCEPTION")) {
					ad.setDisplay("+[LVL] to PER Roll");
					ad.setAlias(ad.getDisplay());
				}
				SenseAdder add = o;
				if (add.getLevelValue() > 0) {
					ad.setLevelCost(add.senseCost);
				} else {
					ad.setBaseCost(add.senseCost);
				}
				ret.add(ad);
				added.add(ad.getXMLID());
			} else if (!added.contains(o.getXMLID())) {
				Adder ad = new Adder(o);
				ad.setAlias(ad.getAlias() + " (built in)");
				ad.setBaseCost(0);
				ad.setLevelCost(0);
				ad.setSelected(false);
				ad.setSelectable(false);
				automatic.add(ad);
			}
		}
		automatic.addAll(avail);

		Collections.sort(ret);
		automatic.addAll(ret);
		ret = automatic;
		ArrayList<String> assignedGroups = new ArrayList<String>();
		for (Adder ad : assigned) {
			if (!added.contains(ad.getXMLID())) {
				added.add(ad.getXMLID());

			}
			if (ad.getXMLID().endsWith("GROUP")) {
				assignedGroups.add(ad.getXMLID());
			}
		}
		ArrayList<SenseGroup> allGroups = SenseGroup.getAllGroups();
		ArrayList<Sense> allSenses = Sense.getAllSenses();
		Adder selected = getSelectedOption();
		if (selected != null) {
			assignedGroups.add(selected.getXMLID());
		}
		if ((targetingGroupCost >= 0) || (nontargetingGroupCost >= 0)) {
			for (SenseGroup group : allGroups) {
				if (assignedGroups.contains(group.getXMLID())) {
					continue;
				} else if (group.getXMLID().equals("UNUSUALGROUP")
						|| group.getXMLID().equals("NOGROUP")) {
					continue;
				} else {
					if (group.getDefaultSenseAdders()
							.contains("TARGETINGSENSE")
							&& (targetingGroupCost >= 0)) {
						Adder swap = new Adder(group);
						swap.setAlias(group.getDisplay());
						swap.setOptions(new ArrayList<Adder>());
						swap.setSelectedOption(null);
						swap.setAvailableAdders(new ArrayList<Adder>());
						swap.setExclusive(true);
						swap.setLevelCost(-1);
						swap.setLevelValue(-1);
						swap.setBaseCost(targetingGroupCost);
						swap.setSelected(true);
						ret.add(swap);
						added.add(group.getXMLID());
					} else if (!group.getDefaultSenseAdders().contains(
							"TARGETINGSENSE")
							&& (nontargetingGroupCost >= 0)) {
						Adder swap = new Adder(group);
						swap.setAlias(group.getDisplay());
						swap.setOptions(new ArrayList<Adder>());
						swap.setSelectedOption(null);
						swap.setAvailableAdders(new ArrayList<Adder>());
						swap.setExclusive(true);
						swap.setLevelCost(-1);
						swap.setLevelValue(-1);
						swap.setBaseCost(nontargetingGroupCost);
						swap.setSelected(true);
						ret.add(swap);
						added.add(group.getXMLID());
					}
				}
			}
		}
		if ((targetingSenseCost >= 0) || (nontargetingSenseCost >= 0)) {
			for (Sense sense : allSenses) {
				if (added.contains(sense.getXMLID())
						|| assignedGroups.contains(sense.getGroup().getXMLID())) {
					continue;
				} else {
					if (sense.getBuiltInSenseAdders()
							.contains("TARGETINGSENSE")
							&& (targetingSenseCost >= 0)) {
						Adder swap = new Adder(sense);
						swap.setAlias(sense.getDisplay());
						swap.setOptions(new ArrayList<Adder>());
						swap.setSelectedOption(null);
						swap.setAvailableAdders(new ArrayList<Adder>());
						swap.setExclusive(true);
						swap.setLevelCost(-1);
						swap.setLevelValue(-1);
						swap.setBaseCost(targetingSenseCost);
						swap.setSelected(true);
						ret.add(swap);
						added.add(sense.getXMLID());
					} else if (!sense.getBuiltInSenseAdders().contains(
							"TARGETINGSENSE")
							&& (nontargetingSenseCost >= 0)) {
						Adder swap = new Adder(sense);
						swap.setAlias(sense.getDisplay());
						swap.setOptions(new ArrayList<Adder>());
						swap.setSelectedOption(null);
						swap.setAvailableAdders(new ArrayList<Adder>());
						swap.setExclusive(true);
						swap.setLevelCost(-1);
						swap.setLevelValue(-1);
						swap.setBaseCost(nontargetingSenseCost);
						swap.setSelected(true);
						ret.add(swap);
						added.add(sense.getXMLID());
					}
				}
			}
		}
		return ret;
	}

	public String getColumn2Output() {
		String ret = getAlias();
		boolean check = false;
		ArrayList<String> groups = new ArrayList<String>();
		ArrayList<String> senses = new ArrayList<String>();
		String group = "[Unknown]";
		if (getSelectedOption() != null) {
			group = getSelectedOption().getAlias();
		}
		if (group.toUpperCase().indexOf("GROUP") > 0) {
			group = group.substring(0, group.toUpperCase().indexOf("GROUP"))
					.trim();
		}
		groups.add(group);
		String adderString = "";
		int count = -1;
		for (Adder ad : getAssignedAdders()) {
			count++;
			if (ad.getXMLID().equals("INCREASEDRANGE")) {
				ad.setDisplayInString(false);
				getAssignedAdders().remove(count);
				if (HeroDesigner.getActiveTemplate().is6E()) {
					adderString += ad.getAlias()
					+ " ("
					+ NumberFormat.getIntegerInstance().format(
							Rounder.roundHalfUp(getActiveCost()
									* 10
									* Math.pow(ad.getLevelPower(), ad
											.getLevels()))) + "m)";
				} else {
				adderString += ad.getAlias()
						+ " ("
						+ NumberFormat.getIntegerInstance().format(
								Rounder.roundHalfUp(getActiveCost()
										* 5
										* Math.pow(ad.getLevelPower(), ad
												.getLevels()))) + "\")";
				}
				getAssignedAdders().add(count, ad);
			}
			if (ad.getXMLID().equals("PERCEIVEPAST")) {
				ad.setDisplayInString(false);
				String val = "Retrocognitive";
				if (check) {
					val += ",";
				}
				val += " ";
				ret = val + ret;
				check = true;
			} else if (ad.getXMLID().equals("PERCEIVEFUTURE")) {
				ad.setDisplayInString(false);
				String val = "Precognitive";
				if (check) {
					val += ",";
				}
				val += " ";
				ret = val + ret;
				check = true;
			} else if (ad.getXMLID().equals("ADDITIONAL_GROUP")
					&& (ad.getSelectedOption() != null)) {
				ad.setDisplayInString(false);
				group = ad.getSelectedOption().getAlias();
				if (group.toUpperCase().indexOf("GROUP") > 0) {
					group = group.substring(0,
							group.toUpperCase().indexOf("GROUP")).trim();
				}
				groups.add(group);
			} else if (ad.getXMLID().equals("ADDITIONAL_SENSE")
					&& (ad.getSelectedOption() != null)) {
				ad.setDisplayInString(false);
				String sense = ad.getSelectedOption().getAlias();
				senses.add(sense);
			} else if (ad.getXMLID().endsWith("GROUP")
					&& !ad.getXMLID().equals("DIMENSIONGROUP")) {
				ad.setDisplayInString(false);
				group = ad.getAlias();
				if (group.toUpperCase().indexOf("GROUP") > 0) {
					group = group.substring(0,
							group.toUpperCase().indexOf("GROUP")).trim();
				}
				groups.add(group);
			} else {
				Sense sense = Sense.getSenseByID(ad.getXMLID());
				if (sense != null) {
					ad.setDisplayInString(false);
					String senseStr = ad.getAlias();
					senses.add(senseStr);
				}
			}
		}
		if (getName().trim().length() > 0) {
			ret = "<i>" + getName() + ":</i>  " + ret;
		}
		ret += " (";
		for (int i = 0; i < groups.size(); i++) {
			if ((i > 0) && (i < groups.size() - 1)) {
				ret += ", ";
			} else if ((i == groups.size() - 1) && (i > 0)) {
				ret += " And ";
			}
			ret += groups.get(i);
		}
		if (groups.size() > 1) {
			ret += " Groups";
		} else {
			ret += " Group";
		}
		for (int i = 0; i < senses.size(); i++) {
			if (i < senses.size() - 1) {
				ret += ", ";
			} else {
				ret += " And ";
			}
			ret += senses.get(i);
		}
		ret += ")";
		if ((getInput() != null) && (getInput().trim().length() > 0)) {
			ret += ":  " + getInput();
		}
		String ads = getAdderString();
		if (ads.trim().length() > 0) {
			if (adderString.trim().length() > 0) {
				adderString += ", ";
			}
			adderString += ads;
		}
		if (adderString.trim().length() > 0) {
			ret += ", " + adderString;
		}
		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;
	}

	public ArrayList<Adder> getOptions() {
		ArrayList<Adder> ret = new ArrayList<Adder>();
		ArrayList<SenseGroup> allGroups = SenseGroup.getAllGroups();
		for (SenseGroup group : allGroups) {
			if (group.getXMLID().equals("UNUSUALGROUP")) {
				continue;
			}
			if (group.getXMLID().equals("NOGROUP")) {
				continue;
			}
			if (group.getDefaultSenseAdders().contains("TARGETINGSENSE")) {
				Adder ad = new Adder(group);
				if (levelValue <= 0) {
					ad.setBaseCost(baseCost);
					ad.setLevelCost(-1);
					ad.setLevelValue(-1);
				} else {
					ad.setBaseCost(0);
					ad.setLevelCost(levelCost);
					ad.setLevelValue(levelValue);
				}
				ret.add(ad);
			} else if (!group.getDefaultSenseAdders()
					.contains("TARGETINGSENSE")) {
				Adder ad = new Adder(group);
				if (levelValue <= 0) {
					ad.setBaseCost(baseCost);
					ad.setLevelCost(-1);
					ad.setLevelValue(-1);
				} else {
					ad.setBaseCost(0);
					ad.setLevelCost(levelCost);
					ad.setLevelValue(levelValue);
				}
				ret.add(ad);
			}
		}
		if (ret.size() == 0) {
			oldMethod = true;
			return super.getOptions();
		}
		Collections.sort(ret);
		return ret;
	}

	public int getRangeValue() {
		int ret = super.getRangeValue();
		if (ret <= 0) {
			return ret;
		}
		for (int i = getAssignedAdders().size() - 1; i >= 0; i--) {
			Adder ad = getAssignedAdders().get(i);
			getAssignedAdders().remove(i);
			ret = super.getRangeValue();
			getAssignedAdders().add(ad);
			if (ad.getXMLID().equals("INCREASEDRANGE")) {
				ret = (int) Rounder.roundHalfUp(ret
						* Math.pow(ad.getLevelPower(), ad.getLevels()));
				return ret;
			}
		}
		return ret;
	}

	protected void init(Element element) {
		duration = "CONSTANT";
		target = "HEX";
		range = "Yes";
		end = 10;
		display = "Clairsentience";
		levelCost = 0;
		levelValue = 0;
		minimumCost = 20;
		baseCost = 20;
		super.init(element);
		targetingGroupCost = -1;
		targetingSenseCost = -1;
		nontargetingGroupCost = -1;
		nontargetingSenseCost = -1;
		oldMethod = false;
		String check = XMLUtility.getValue(element, "TARGETINGGROUPCOST");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				targetingGroupCost = Double.parseDouble(check);
			} catch (Exception exp) {

			}
		}
		check = XMLUtility.getValue(element, "NONTARGETINGGROUPCOST");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				nontargetingGroupCost = Double.parseDouble(check);
			} catch (Exception exp) {

			}
		}
		check = XMLUtility.getValue(element, "TARGETINGSENSECOST");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				targetingSenseCost = Double.parseDouble(check);
			} catch (Exception exp) {

			}
		}
		check = XMLUtility.getValue(element, "NONTARGETINGSENSECOST");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				nontargetingSenseCost = Double.parseDouble(check);
			} catch (Exception exp) {

			}
		}
	}

	public void restoreFromSave(Element root) {

		super.restoreFromSave(root);
		getOptions(); // sets whether to use the old methods or the new
		if (oldMethod) {
			return;
		}

		ArrayList<Adder> holder = availableAdders;
		ArrayList<Adder> assignedHolder = assignedAdders;
		assignedAdders = new ArrayList<Adder>();
		availableAdders = new ArrayList<Adder>();
		ArrayList<Adder> avail = getAvailableAdders();
		availableAdders = holder;
		ArrayList<Adder> assigned = new ArrayList<Adder>();
		Iterator iter = root.getChildren("ADDER").iterator();
		OUTER: while (iter.hasNext()) {
			Element element = (Element) iter.next();
			String id = XMLUtility.getValue(element, "XMLID");
			if ((id != null)
					&& (id.trim().equals("SINGLE") || id.trim().equals("GROUP")
							|| id.trim().equals("ADDITIONAL_GROUP")
							|| id.trim().equals("ADDITIONAL_SENSE")
							|| id.trim().equals("SENSEGROUP") || id.trim()
							.equals("SENSE"))) {
				String adop = null;
				String val = XMLUtility.getValue(element, "OPTIONID");
				if ((val != null) && (val.trim().length() > 0)) {
					adop = val;
				} else {
					val = XMLUtility.getValue(element, "OPTION");
					if ((val != null) && (val.trim().length() > 0)) {
						adop = val;
					}
				}
				if ((adop != null) && (adop.trim().length() > 0)) {
					if (id.indexOf("GROUP") >= 0) {
						if (adop.toUpperCase().indexOf("GROUP") < 0) {
							if (adop.equals(adop.toUpperCase())) {
								adop = adop + "GROUP";
							} else {
								adop = adop.trim() + " Group";
							}
						}
					}
					if (adop.equals(adop.toUpperCase())) {
						adop = translateSense(adop);
					}
					for (Adder ad : avail) {
						if (ad.getXMLID().startsWith(adop.trim().toUpperCase())
								|| adop.trim().toUpperCase().startsWith(
										ad.getXMLID())
								|| ad.getDisplay().equals(adop)) {
							try {
								ad = (Adder) ad.clone();
								ad.setSelected(true);
								assigned.add(ad);
								continue OUTER;
							} catch (Exception exp) {

							}
						}
					}
					Adder ad = getSelectedOption();
					if (ad != null) {
						if (ad.getXMLID().startsWith(adop.trim().toUpperCase())
								|| adop.trim().toUpperCase().startsWith(
										ad.getXMLID())
								|| ad.getDisplay().equals(adop)) {
							try {
								ad = (Adder) ad.clone();
								ad.setSelected(true);
								assigned.add(ad);
								continue OUTER;
							} catch (Exception exp) {

							}
						}
					}

				}
			} else if (GenericObject.findObjectByID(assignedHolder, id) != null) {
				assigned.add((Adder) GenericObject.findObjectByID(
						assignedHolder, id));
				continue OUTER;
			}

			Adder ad = new Adder(element);
			ad.setExclusive(false);
			ad.setAvailableCheck(false);
			ad.restoreFromSave(element);
			assigned.add(ad);
		}
		assignedAdders = assigned;

		String option = null;
		String check = XMLUtility.getValue(root, "OPTIONID");
		if ((check != null) && (check.trim().length() > 0)) {
			option = check;
		} else {
			check = XMLUtility.getValue(root, "OPTION");
			if ((check != null) && (check.trim().length() > 0)) {
				option = check;
			}
		}
		if (option != null) {
			option = translateSense(option);
			avail = getOptions();
			boolean matched = false;
			LOOP: for (Adder ad : avail) {
				if (ad.getXMLID().startsWith(option)
						|| option.startsWith(ad.getXMLID())
						|| ad.getDisplay().toUpperCase().startsWith(
								option.toUpperCase())
						|| option.toUpperCase().startsWith(
								ad.getDisplay().toUpperCase())) {
					setSelectedOption(ad);
					matched = true;
					break LOOP;
				}
			}
			if (!matched) {
				String opalias = XMLUtility.getValue(root, "OPTION_ALIAS");
				if ((opalias != null) && (opalias.trim().length() > 0)) {
					LOOP: for (Adder ad : avail) {
						if (ad.getDisplay().toUpperCase().startsWith(
								opalias.trim().toUpperCase())
								|| opalias.trim().toUpperCase().startsWith(
										ad.getDisplay())) {
							setSelectedOption(ad);
							matched = true;
							break LOOP;
						}
					}
				}
				if (!matched) {
					LOOP: for (int i = 0; i < avail.size(); i++) {
						Adder ad = avail.get(i);
						if (ad.getBaseCost() == baseCost) {
							setSelectedOption(ad);
							matched = true;
							break LOOP;
						}
					}
				}
			}
		}

		getAssignedAdders(); // takes care of the assigned adders...
		setSelectedOption(getSelectedOption());
		// adjusts the selected option and related costs (if necessary);
	}

	private String translateSense(String val) {
		String ret = val;
		if (oldMethod) {
			return ret;
		}
		if (val.equals("HEARING")) {
			ret = "NORMALHEARING";
		}
		if (val.equals("SONAR")) {
			ret = "ACTIVESONAR";
		}
		if (val.equals("MA")) {
			ret = "MENTALAWARENESS";
		}
		if (val.equals("MS")) {
			ret = "MINDSCAN";
		}
		if (val.equals("RP")) {
			ret = "RADIOPERCEPTION";
		}
		if (val.equals("RT")) {
			ret = "RADIOPERCEIVETRANSMIT";
		}
		if (val.equals("RADIOTRANSMISSION")) {
			ret = "RADIOPERCEIVETRANSMIT";
		}
		if (val.equals("SIGHT")) {
			ret = "NORMALSIGHT";
		}
		if (val.equals("SMELL")) {
			ret = "NORMALSMELL";
		}
		if (val.equals("TASTE")) {
			ret = "NORMALTASTE";
		}
		if (val.equals("TOUCH")) {
			ret = "NORMALTOUCH";
		}
		if (val.equals("IR")) {
			ret = "INFRAREDPERCEPTION";
		}
		if (val.equals("IRPERCEPTION")) {
			ret = "INFRAREDPERCEPTION";
		}
		if (val.equals("NRAY")) {
			ret = "NRAYPERCEPTION";
		}
		if (val.equals("SENSORYTALENTS")) {
			ret = "DANGER_SENSE";
		}
		if (val.equals("UV")) {
			ret = "ULTRAVIOLETPERCEPTION";
		}
		if (val.equals("UVPERCEPTION")) {
			ret = "ULTRAVIOLETPERCEPTION";
		}
		if (val.equals("ULTRASONIC")) {
			ret = "ULTRASONICPERCEPTION";
		}
		return ret;
	}
}