package com.hero.objects.powers;

import java.util.ArrayList;

import org.jdom.Element;

import com.hero.HeroDesigner;
import com.hero.objects.ElementalControl;
import com.hero.objects.GenericObject;
import com.hero.objects.Multipower;
import com.hero.objects.characteristics.Characteristic;
import com.hero.objects.modifiers.Modifier;
import com.hero.util.Constants;
import com.hero.util.Rounder;

/**
 * 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 MentalDefense extends Power {

	private static String xmlID = "MENTALDEFENSE";

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

	@Override
	public double getActiveCost() {
		double total = getTotalCost();
		Characteristic ego = HeroDesigner.getActiveHero().getCharacteristic(
				Constants.EGO);
		int secNum = 0;
		if ((ego != null) && (getLevels() > 0)) {
			secNum += (int) Rounder.roundHalfUp(ego.getSecondaryValue() / 5d);
		}
		if (!HeroDesigner.getActiveTemplate().is6E()) {
			total += secNum * getLevelCost() / getLevelValue();
		}
		double advantageTotal = 0d;
		boolean advantagesApplied = false;
		for (int i = 0; i < assignedModifiers.size(); i++) {
			Modifier mod = assignedModifiers.get(i);
			if (mod.getTotalValue() > 0) {
				advantageTotal += mod.getTotalValue();
				advantagesApplied = true;
			}
		}
		if (getParentList() != null) {
			ArrayList<Modifier> parentMods = getParentList()
					.getAssignedModifiers();
			LOOP: for (Modifier mod : parentMods) {
				if (mod.getTypes().contains("VPP")) {
					continue LOOP;
				}
				if (mod.getXMLID().equals("CHARGES")
						&& (getParentList() instanceof Multipower)) {
					continue LOOP;
				}
				if ((mod.getTotalValue() > 0)
						&& ((GenericObject.findObjectByID(assignedModifiers,
								mod.getXMLID()) == null)
								|| mod.getXMLID().equals("GENERIC_OBJECT") || mod
								.getXMLID().equals("CUSTOM_MODIFIER"))) {
					if ((getParentList() instanceof Multipower)
							|| (getParentList() instanceof ElementalControl)) {
						continue;
					} else {
						advantageTotal += mod.getTotalValue();
					}
					advantagesApplied = true;
				}
			}
		}
		double val = total * (1 + advantageTotal);
		if (!HeroDesigner.getActiveTemplate().is6E()) {
			val -= secNum * getLevelCost() / getLevelValue();
		}
		if (advantagesApplied) {
			val = Rounder.roundHalfDown(val);
		}
		return val;
	}

	@Override
	public double getActiveCost(String excludeID) {
		double total = getTotalCost();
		Characteristic ego = HeroDesigner.getActiveHero().getCharacteristic(
				Constants.EGO);
		int secNum = 0;
		if ((ego != null) && (getLevels() > 0)) {
			secNum += (int) Rounder.roundHalfUp(ego.getSecondaryValue() / 5d);
		}
		if (!HeroDesigner.getActiveTemplate().is6E()) {
			total += secNum * getLevelCost() / getLevelValue();
		}
		double advantageTotal = 0d;
		boolean advantagesApplied = false;
		for (Modifier mod : assignedModifiers) {
			if ((mod.getTotalValue() > 0) && !mod.getXMLID().equals(excludeID)) {
				advantageTotal += mod.getTotalValue();
				advantagesApplied = true;
			}
		}
		if (getParentList() != null) {
			ArrayList<Modifier> parentMods = getParentList()
					.getAssignedModifiers();
			LOOP: for (Modifier mod : parentMods) {
				if (mod.getTypes().contains("VPP")) {
					continue LOOP;
				}
				if (mod.getXMLID().equals("CHARGES")
						&& (getParentList() instanceof Multipower)) {
					continue LOOP;
				}
				if ((mod.getTotalValue() > 0)
						&& !mod.getXMLID().equals(excludeID)
						&& ((GenericObject.findObjectByID(assignedModifiers,
								mod.getXMLID()) == null)
								|| mod.getXMLID().equals("GENERIC_OBJECT") || mod
								.getXMLID().equals("CUSTOM_MODIFIER"))) {
					if ((getParentList() instanceof Multipower)
							|| (getParentList() instanceof ElementalControl)) {
						continue;
					} else {
						advantageTotal += mod.getTotalValue();
					}
					advantagesApplied = true;
				}
			}
		}
		double val = total * (1 + advantageTotal);
		if (!HeroDesigner.getActiveTemplate().is6E()) {
			val -= secNum * getLevelCost() / getLevelValue();
		}
		if (advantagesApplied) {
			val = Rounder.roundHalfDown(val);
		}
		return val;
	}

	@Override
	public String getColumn2Output() {
		String ret = getAlias() + " (" + getDamageDisplay() + ")";
		boolean first = false;
		if (isEquipment()) {
			for (GenericObject o : HeroDesigner.getActiveHero().getEquipment()) {
				if (o instanceof MentalDefense) {
					MentalDefense md = (MentalDefense) o;
					if (md.getID() == getID()) {
						first = true;
					}
					break;
				}
			}
		} else {
			for (GenericObject o : HeroDesigner.getActiveHero().getPowers()) {
				if (o instanceof MentalDefense) {
					MentalDefense md = (MentalDefense) o;
					if (md.getID() == getID()) {
						first = true;
					}
					break;
				}
			}
		}
		if (!first) {
			ret = "+" + getLevels() + " " + ret;
		}
		if (getName().trim().length() > 0) {
			ret = "<i>" + getName() + ":</i>  " + ret;
		}
		if ((getInput() != null) && (getInput().trim().length() > 0)) {
			ret += ":  " + getInput();
		}
		if (getSelectedOption() != null) {
			ret += " (";
			ret += getSelectedOption().getAlias();

			String adderString = getAdderString();
			if (adderString.trim().length() > 0) {
				ret += "; " + adderString;
			}
			ret += ")";
		} else {
			String adderString = getAdderString();
			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;
	}

	@Override
	public String getDamageDisplay() {
		if (HeroDesigner.getActiveTemplate().is6E()) {
			int num = getMdLevels();
			int secNum = num;
			if (num != secNum) {
				return num + "/" + secNum + " points total";
			} else {
				return num + " points total";
			}
		} else {
			Characteristic ego = HeroDesigner.getActiveHero()
					.getCharacteristic(Constants.EGO);
			int num = getMdLevels();
			int secNum = num;
			if ((ego != null) && (num > 0)) {
				num += (int) Rounder.roundHalfUp(ego.getPrimaryValue() / 5d);
				secNum += (int) Rounder
						.roundHalfUp(ego.getSecondaryValue() / 5d);
			}
			if (num != secNum) {
				return num + "/" + secNum + " points total";
			} else {
				return num + " points total";
			}
		}
	}

	@Override
	public int getMdLevels() {
		int ret = getLevels();
		for (GenericObject o : HeroDesigner.getActiveHero().getPowers()) {
			if (o instanceof MentalDefense) {
				MentalDefense md = (MentalDefense) o;
				if (md.getID() != getID()) {
					ret += md.getLevels();
				}
			} else if (o instanceof ForceField) {
				ForceField ff = (ForceField) o;
				ret += ff.getMdLevels();
			} else if (o instanceof CompoundPower) {
				CompoundPower cp = (CompoundPower) o;
				for (GenericObject o2 : cp.getPowers()) {
					if (o2 instanceof MentalDefense) {
						MentalDefense md = (MentalDefense) o2;
						if (md.getID() != getID()) {
							ret += md.getLevels();
						}
					} else if (o2 instanceof ForceField) {
						ForceField ff = (ForceField) o2;
						ret += ff.getMdLevels();
					}
				}
			}
		}
		for (GenericObject o : HeroDesigner.getActiveHero().getEquipment()) {
			if (o instanceof MentalDefense) {
				MentalDefense md = (MentalDefense) o;
				if (md.getID() != getID()) {
					ret += md.getLevels();
				}
			} else if (o instanceof ForceField) {
				ForceField ff = (ForceField) o;
				ret += ff.getMdLevels();
			} else if (o instanceof CompoundPower) {
				CompoundPower cp = (CompoundPower) o;
				for (GenericObject o2 : cp.getPowers()) {
					if (o2 instanceof MentalDefense) {
						MentalDefense md = (MentalDefense) o2;
						if (md.getID() != getID()) {
							ret += md.getLevels();
						}
					} else if (o2 instanceof ForceField) {
						ForceField ff = (ForceField) o2;
						ret += ff.getMdLevels();
					}
				}
			}
		}
		return ret;
	}
}