package com.hero.objects.powers;

import java.util.ArrayList;

import org.jdom.Element;

import com.hero.HeroDesigner;
import com.hero.objects.Adder;
import com.hero.objects.GenericObject;

/**
 * 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 Concealed extends SenseAdder {

	private static String xmlID = "CONCEALED";

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

	@Override
	public ArrayList<Adder> getAssignedAdders() {
		ArrayList<Adder> ret = super.getAssignedAdders();
		ArrayList<String> purchasedGroups = getSenseGroups();
		ArrayList<Sense> allSenses = Sense.getOwnedSenses();
		if (purchasedGroups == null) {
			purchasedGroups = new ArrayList<String>();
		}
		if (levelValue < 1) {
			return ret;
		}
		OUTER: for (int i = ret.size() - 1; i >= 0; i--) {
			Adder ad = ret.get(i);
			if (ad.getXMLID().equals("GROUP")
					&& (ad.getSelectedOption() != null)) {
				if (ad.getSelectedOption().getXMLID().equals(
						getSelectedOption().getXMLID())) {
					ret.remove(i);
					continue OUTER;
				}
				ArrayList<SenseGroup> groups = SenseGroup.getAllGroups();
				GROUPS: for (SenseGroup group : groups) {
					if (group.getXMLID().equals(
							ad.getSelectedOption().getXMLID())) {
						ArrayList<String> adders = group
								.getSenseAdders(getID());
						if (adders.contains(getXMLID())) {
							ret.remove(i);
							continue OUTER;
						}
						boolean allowed = false;
						SENSELOOP: for (Sense sense : allSenses) {
							if (sense.getGroup().equals(group)) {
								if (sense.isActive()
										|| sense.getBuiltInSenseAdders()
												.contains("TRANSMIT")) {
									allowed = true;
									break SENSELOOP;
								}
							}
						}
						if (!allowed) {
							ret.remove(i);
							continue OUTER;
						}
						if (levelValue < 1) {
							ad.setBaseCost(groupCost);
						} else {
							ad.setBaseCost(groupCost * levels);
						}
						break GROUPS;
					}
				}
			} else if (ad.getXMLID().endsWith("GROUP")) {
				if (ad.getXMLID().equals(getSelectedOption().getXMLID())) {
					ret.remove(i);
					continue OUTER;
				}
				ArrayList<SenseGroup> groups = SenseGroup.getAllGroups();
				GROUPS: for (SenseGroup group : groups) {
					if (group.getXMLID().equals(ad.getXMLID())) {
						ArrayList<String> adders = group
								.getSenseAdders(getID());
						if (adders.contains(getXMLID())) {
							ret.remove(i);
							continue OUTER;
						}
						boolean allowed = false;
						SENSELOOP: for (Sense sense : allSenses) {
							if (sense.getGroup().equals(group)) {
								if (sense.isActive()
										|| sense.getBuiltInSenseAdders()
												.contains("TRANSMIT")) {
									allowed = true;
									break SENSELOOP;
								}
							}
						}
						if (!allowed) {
							ret.remove(i);
							continue OUTER;
						}
						if (levelValue < 1) {
							ad.setBaseCost(groupCost);
						} else {
							ad.setBaseCost(groupCost * levels);
						}
						break GROUPS;
					}
				}
			} else if (ad.getXMLID().equals("SINGLE")
					&& (ad.getSelectedOption() != null)) {
				if (ad.getSelectedOption().getXMLID().equals(
						getSelectedOption().getXMLID())) {
					ret.remove(i);
					continue OUTER;
				}
				boolean found = false;
				SENSES: for (Sense sense : allSenses) {
					if (sense.getXMLID().equals(
							ad.getSelectedOption().getXMLID())) {
						found = true;
						if (purchasedGroups.contains(sense.getGroup()
								.getXMLID())) {
							ret.remove(i);
							continue OUTER;
						}
						ArrayList<String> adders = sense
								.getBuiltInSenseAdders(getID());
						if (adders.contains(getXMLID())) {
							ret.remove(i);
							continue OUTER;
						}
						if (!sense.isActive() && !adders.contains("TRANSMIT")) {
							ret.remove(i);
							continue OUTER;
						}
						if (levelValue < 1) {
							ad.setBaseCost(senseCost);
						} else {
							ad.setBaseCost(senseCost * levels);
						}
						break SENSES;
					}
				}
				if (!found) {
					ret.remove(i);
					continue OUTER;
				}
			} else {
				if (ad.getXMLID().equals(getSelectedOption().getXMLID())
						&& ad.getDisplay().equals(
								getSelectedOption().getDisplay())) {
					ret.remove(i);
					continue OUTER;
				}
				boolean found = false;
				SENSES: for (Sense sense : allSenses) {
					if (sense.getXMLID().equals(ad.getXMLID())) {
						if (sense.getXMLID().equals("DETECT")) {
							String comp = SenseAdder
									.getDetectDisplay((Detect) sense);
							if (!comp.equals(ad.getDisplay())) {
								continue SENSES;
							}
						}
						found = true;
						if ((sense.getGroup() != null)
								&& purchasedGroups.contains(sense.getGroup()
										.getXMLID())) {
							ret.remove(i);
							continue OUTER;
						}
						ArrayList<String> adders = sense
								.getBuiltInSenseAdders(getID());
						if (adders.contains(getXMLID())) {
							ret.remove(i);
							continue OUTER;
						}
						if (!sense.isActive() && !adders.contains("TRANSMIT")) {
							ret.remove(i);
							continue OUTER;
						}
						if (levelValue < 1) {
							ad.setBaseCost(senseCost);
						} else {
							ad.setBaseCost(senseCost * levels);
						}
						break SENSES;
					}
				}
				if (!found) {
					ret.remove(i);
					continue OUTER;
				}
			}
		}
		return ret;
	}

	@Override
	protected ArrayList<Adder> getAutomaticAdders() {
		ArrayList<Adder> ret = new ArrayList<Adder>();
		ArrayList<String> purchasedGroups = getSenseGroups();
		ArrayList<Sense> allSenses = Sense.getOwnedSenses();
		if ((getSelectedOption() == null)
				|| (getSelectedOption().getXMLID() == null)) {
			return ret;
		}
		if ((groupCost > 0) && !getSelectedOption().getXMLID().equals("ALL")) {
			ArrayList<String> groups = getSenseGroups();
			ArrayList<SenseGroup> allGroups = SenseGroup.getOwnedGroups();
			for (SenseGroup group : allGroups) {
				if (group.getXMLID().equals("UNUSUALGROUP")
						|| group.getXMLID().equals("NOGROUP")) {
					continue;
				} else if (groups.contains(group.getXMLID())) {
					continue;
				} else {
					boolean allowed = false;
					SENSELOOP: for (Sense sense : allSenses) {
						if (sense.getGroup().equals(group)) {
							if (sense.isActive()
									|| sense.getBuiltInSenseAdders().contains(
											"TRANSMIT")) {
								allowed = true;
								break SENSELOOP;
							}
						}
					}
					if (!allowed) {
						continue;
					}
					ArrayList<String> adders = group.getSenseAdders(getID());
					if (adders.contains(getXMLID())) {
						continue;
					}
					Adder g = new Adder(group);
					g.setAvailableAdders(new ArrayList<Adder>());
					g.setAssignedAdders(new ArrayList<Adder>());
					g.setExclusive(true);
					if (levelValue < 1) {
						g.setBaseCost(groupCost);
					} else {
						g.setLevelValue(-1);
						g.setBaseCost(groupCost * levels);
					}
					ret.add(g);
				}
			}
		}
		if (senseCost > 0) {
			ArrayList<String> senses = getSenses();
			LOOP: for (Sense sense : allSenses) {
				if (senses.contains(sense.getXMLID())
						&& !sense.getXMLID().equals("DETECT")) {
					continue;
				} else if (purchasedGroups
						.contains(sense.getGroup().getXMLID())) {
					continue;
				} else {
					if (sense.getXMLID().equals("DETECT")) {
						String comp = SenseAdder
								.getDetectDisplay((Detect) sense);
						if (comp.equals(getSelectedOption().getDisplay())) {
							continue LOOP;
						}
						ArrayList<Adder> assigned = getAssignedAdders();
						for (Adder ad : assigned) {
							if (ad.getDisplay().equals(comp)) {
								continue LOOP;
							}
						}
					}
					ArrayList<String> adders = sense
							.getBuiltInSenseAdders(getID());
					if (adders.contains(getXMLID())) {
						continue;
					}
					if (!sense.isActive() && !adders.contains("TRANSMIT")) {
						continue;
					}
					Adder g = new Adder(sense);
					if (sense.getXMLID().equals("DETECT")) {
						g.setDisplay(SenseAdder
								.getDetectDisplay((Detect) sense));
						g.setAlias(SenseAdder.getDetectDisplay((Detect) sense));
						g.setOptions(new ArrayList<Adder>());
						g.setLevelValue(-1);
						g.setLevelCost(-1);
						g.setSelectedOption(null);
					}
					g.setExclusive(true);
					g.setAvailableAdders(new ArrayList<Adder>());
					g.setAssignedAdders(new ArrayList<Adder>());
					if (levelValue < 1) {
						g.setBaseCost(senseCost);
					} else {
						g.setBaseCost(senseCost * levels);
					}
					ret.add(g);
				}
			}
		}
		return ret;
	}

	@Override
	public String getColumn2Output() {
		String ret = getAlias();
		if (getName().trim().length() > 0) {
			ret = "<i>" + getName() + ":</i>  " + ret;
		}

		String withString = " (-" + getLevels() + " to ";
		if (getSelectedOption() != null) {
			withString += getSelectedOption().getAlias();

			String adderString = getAdderString();
			if (adderString.trim().length() > 0) {
				withString += ", " + adderString;
				withString = withString.substring(0, withString
						.lastIndexOf(","))
						+ " and"
						+ withString.substring(withString.lastIndexOf(",") + 1,
								withString.length());
			}
		} else {
			String adderString = getAdderString();
			if (adderString.trim().length() > 0) {
				withString += " " + adderString;
				if (withString.indexOf(", ") > 0) {
					withString = withString.substring(0, withString
							.lastIndexOf(","))
							+ " and"
							+ withString.substring(
									withString.lastIndexOf(",") + 1, withString
											.length());
				}
			}
		}
		ret += withString + " PER Rolls)";

		if ((getInput() != null) && (getInput().trim().length() > 0)) {
			ret += ":  " + getInput();
		}
		ret += getModifierString();
		if ((getEndUsage() > 0)
				&& (GenericObject.findObjectByID(HeroDesigner.getActiveHero()
						.getPowers(), "ENDURANCERESERVE") != null)
				&& (GenericObject.findObjectByID(getAssignedModifiers(),
						"ENDRESERVEOREND") == null)
				&& !HeroDesigner.getInstance().getPrefs().useWG()) {
			if (getUseENDReserve()) {
				ret += " (uses END Reserve)";
			} else {
				ret += " (uses Personal END)";
			}
		}

		return ret;
	}

	@Override
	public String getDamageDisplay() {
		return "";
	}

	@Override
	public ArrayList<Adder> getOptions() {
		ArrayList<Adder> ret = new ArrayList<Adder>();
		ArrayList<Sense> allSenses = Sense.getOwnedSenses();
		int groupCount = 0;

		if (groupCost > 0) {
			ArrayList<SenseGroup> all = SenseGroup.getOwnedGroups();
			for (SenseGroup gr : all) {
				if ((GenericObject.findObjectByID(ret, gr.getXMLID()) == null)
						&& !gr.getSenseAdders().contains(getXMLID())) {
					boolean allowed = false;
					SENSELOOP: for (Sense sense : allSenses) {
						if (sense.getGroup().equals(gr)) {
							if (sense.isActive()
									|| sense.getBuiltInSenseAdders().contains(
											"TRANSMIT")) {
								allowed = true;
								break SENSELOOP;
							}
						}
					}
					if (!allowed) {
						continue;
					}
					Adder ad = new Adder(gr);
					if (levelValue > 0) {
						ad.setLevelCost(groupCost);
					} else {
						ad.setBaseCost(groupCost);
					}
					ret.add(ad);
					groupCount++;
				}
			}
		}
		if ((groupCount > 1) && (allCost > 0)
				&& (GenericObject.findObjectByID(ret, "ALL") == null)) {
			Adder allAdder = new Adder(new Element("ADDER"));
			allAdder.setXMLID("ALL");
			if (levelValue > 0) {
				allAdder.setLevelCost(allCost);
			} else {
				allAdder.setBaseCost(allCost);
			}
			allAdder.setDisplay("all Sense Groups");
			allAdder.setAlias("all Sense Groups");
			ret.add(0, allAdder);
		}
		if (senseCost > 0) {
			OUTER: for (Sense gr : allSenses) {
				ArrayList<String> adders = gr.getBuiltInSenseAdders();
				if (!adders.contains(getXMLID())) {
					String comp = gr.getDisplay();
					if (gr.getXMLID().equals("DETECT")) {
						comp = SenseAdder.getDetectDisplay((Detect) gr);
					}
					for (Adder ad : ret) {
						if (ad.getDisplay().equals(comp)) {
							continue OUTER;
						}
					}
					if (!gr.isActive() && !adders.contains("TRANSMIT")) {
						continue OUTER;
					}
					Adder ad = new Adder(gr);
					if (levelValue > 0) {
						ad.setBaseCost(0);
						ad.setLevelCost(senseCost);
					} else {
						ad.setLevelCost(0);
						ad.setLevelValue(-1);
						ad.setBaseCost(senseCost);
					}
					if (gr.getXMLID().equals("DETECT")) {
						ad.setDisplay(comp);
						ad.setAlias(comp);
						ad.setAvailableAdders(new ArrayList<Adder>());
						ad.setAssignedAdders(new ArrayList<Adder>());
					}
					ret.add(ad);
				}
			}
		}
		return ret;
	}

}