package com.hero.objects;

import java.util.ArrayList;

import javax.swing.JPanel;

import org.jdom.Element;

import com.hero.HeroDesigner;
import com.hero.Rules;
import com.hero.objects.modifiers.Linked;
import com.hero.objects.modifiers.Modifier;
import com.hero.objects.powers.CompoundPower;
import com.hero.ui.dialog.GenericDialog;
import com.hero.ui.dialog.MultipowerDialog;
import com.hero.ui.widgets.PopupMessage;
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 Multipower extends List {

	private String error;

	public Multipower(Element root) {
		super(root);
		minimumCost = 1;
		maxCost = 9999;
		minSet = true;
		maxSet = true;
	}

	public Multipower(Element root, String xmlID) {
		super(root, xmlID);
		minimumCost = 1;
		maxCost = 9999;
		minSet = true;
		maxSet = true;
	}

	public Multipower(String name) {
		super(name);
		minimumCost = 1;
		baseCost = 5;
		maxCost = 9999;
		minSet = true;
		maxSet = true;
	}

	@Override
	public String getColumn1Suffix(GenericObject child) {
		updateChildPositions();
		if (HeroDesigner.getActiveTemplate().is6E()) {
			if (child.isUltra()) {
				return "f";
			} else {
				return "v";
			}
		} else {
			if (child.isUltra()) {
				return "u";
			} else {
				return "m";
			}
		}
	}

	@Override
	public String getColumn2Output() {
		String ret = "";
		if (getName().trim().length() > 0) {
			ret += "<i>" + getName() + ":</i>  ";
		}
		ret += getAlias() + ", " + (int) getBaseCost() + "-point reserve";
		String a = getAdderString();
		if (a.trim().length() > 0) {
			ret += ", " + a;
		}
		String m = getModifierString();
		ret += m;
		return ret;
	}

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

	@Override
	public double getRealCostForChild(GenericObject child) {
		double val = super.getRealCostForChild(child);
		boolean costsPoints = true;
		if ((val == 0) || (val < 0)) {
			costsPoints = false;
		}
		if (child.isUltra()) {
			val = val / 10d;
		} else {
			val = val / 5d;
		}
		val = Rounder.roundHalfDown(val);
		if (costsPoints && (val < 1)) {
			val = 1;
		}
		return val;
	}

	@Override
	public String getRejectionMessage() {
		if (error == null) {
			return "You cannot add a List into a Multipower.  New list will be placed outside of Multipower.";
		} else {
			return error;
		}
	}

	@Override
	public Element getSaveXML() {
		Element root = getGeneralSaveXML();
		root.setName("MULTIPOWER");
		root.setAttribute("QUANTITY", getQuantity() + "");
		return root;
	}

	@Override
	public void init(Element root) {
		super.init(root);
		abbreviation = "MP";
	}

	@Override
	public boolean objectAllowed(GenericObject o, boolean displayPopup) {
		boolean ret = true;
		o = o.clone();
		o.setMainPower(null);
		com.hero.objects.List old = o.getParentList();
		o.setParent(this);
		if (o instanceof CompoundPower) {
			o.setParent(null);
			CompoundPower cp = (CompoundPower) o;
			for (int i = 0; i < cp.getPowers().size(); i++) {
				GenericObject obj = cp.getPowers().get(i);
				boolean check = objectAllowed(obj, displayPopup);
				if (!check) {
					o.setParent(old);
					return check;
				}
			}
			if (o.getActiveCost() > getBaseCost()) {
				error = "The Active Cost of " + o.getAlias()
						+ " exceeds the Base Cost of the Multipower.  "
						+ o.getAlias()
						+ " will be placed outside of this Multipower.";
				o.setParent(old);
				return false;
			}
			if (cp.getPowers().size() > 0) {
				o.setParent(old);
				return true;
			}
		}
		if (!o.allowsOtherModifiers() && (getAssignedModifiers().size() > 0)) {
			error = o.getAlias()
					+ " is not allowed to have Modifiers assigned to it in its current configuration.\n\n"
					+ o.getAlias() + " will be placed outside of the list.";
			return false;
		}
		if (o instanceof List) {
			error = "You cannot add a List into a Multipower.  New list will be placed outside of Multipower.";
			ret = false;
		} else if (o instanceof VariablePowerPool) {
			error = "You cannot add a VPP into a Multipower.  The Variable Power Pool will be placed outside of Multipower.";
			ret = false;
		} else if (o.getActiveCost() > getBaseCost()) {
			error = "The Active Cost of " + o.getAlias()
					+ " exceeds the Base Cost of the Multipower.  "
					+ o.getAlias()
					+ " will be placed outside of this Multipower.";
			ret = false;
		} else if ((getAssignedModifiers().size() > 0)
				&& HeroDesigner.getInstance().getPrefs()
						.isModifierIntelligenceOn()) {
			List oldParent = o.getParentList();
			o.setParent(null);

			ArrayList<Modifier> listMods = getAssignedModifiers();
			ArrayList<Modifier> orig = o.getAssignedModifiers();
			ArrayList<Modifier> slotMods = (ArrayList<Modifier>) orig.clone();
			ArrayList<Modifier> addFromList = new ArrayList<Modifier>();
			for (int i = 0; i < listMods.size(); i++) {
				Modifier mod = listMods.get(i);
				if (GenericObject.findObjectByID(orig, mod.getXMLID()) == null) {
					addFromList.add(mod);
				}
			}
			slotMods.addAll(addFromList);
			o.setAssignedModifiers(slotMods);
			INNER: for (int j = addFromList.size() - 1; j >= 0; j--) {
				Modifier mod = addFromList.get(j);
				slotMods.remove(mod);
				o.setAssignedModifiers(slotMods);
				String check = mod.included(o);
				if (check.trim().length() > 0) {
					error = mod.getAlias() + " cannot be applied to "
							+ o.getAlias() + ".\n\nReason:  " + check + "\n\n"
							+ o.getAlias()
							+ " will be placed outside of the Multipower.";
					ret = false;
					break INNER;
				}
				slotMods.add(mod);
				o.setAssignedModifiers(slotMods);
			}
			o.setAssignedModifiers(orig);
			o.setParent(oldParent);
		}

		if (!ret) {
			o.setParent(old);
			return ret;
		} else if ((GenericObject.findObjectByID(o.getAssignedModifiers(),
				"LINKED") != null)
				&& (HeroDesigner.getActiveHero().getRules()
						.getLinkAcrossFramework() > Rules.IGNORE)) {
			Linked link = (Linked) GenericObject.findObjectByID(o
					.getAssignedModifiers(), "LINKED");
			GenericObject linkObj = link.getValue();
			if ((linkObj != null)
					&& (linkObj.getParentList() != null)
					&& ((o.getMainPower() == null)
							|| (linkObj.getMainPower() == null) || !o
							.getMainPower().equals(linkObj.getMainPower()))) {
				if ((linkObj.getParentList() instanceof Multipower)
						|| (linkObj.getParentList() instanceof ElementalControl)
						|| (linkObj.getParentList() instanceof VariablePowerPool)) {
					if (HeroDesigner.getActiveHero().getRules()
							.getLinkAcrossFramework() == Rules.DONOTALLOW) {
						error = "You cannot Link two different slots of a Power Framework";
						ret = false;
					} else {
						String msg = "Warning!  You should not Link two different slots of a Power Framework.  Use a Compound Power instead.";
						if (displayPopup) {
							PopupMessage popup = PopupMessage.getInstance(
									HeroDesigner.getAppFrame(),
									(JPanel) HeroDesigner.getAppFrame()
											.getContentPane(), msg, true);
							popup.setVisible(true);
							displayPopup = false;
						}
					}
				}
			}
		}
		if (!ret) {
			return ret;
		}
		if (o.getTypes().contains("SPECIAL")
				&& (HeroDesigner.getActiveHero().getRules()
						.getSpecialTypeInFramework() > Rules.IGNORE)) {
			String msg = "Warning!  "
					+ o.getDisplay()
					+ " should not be placed in an Multipower (or any other Power Framework).";
			if (displayPopup
					&& (HeroDesigner.getActiveHero().getRules()
							.getSpecialTypeInFramework() == Rules.WARN)) {
				PopupMessage popup = PopupMessage.getInstance(HeroDesigner
						.getAppFrame(), (JPanel) HeroDesigner.getAppFrame()
						.getContentPane(), msg, true);
				popup.setVisible(true);
			} else if (HeroDesigner.getActiveHero().getRules()
					.getSpecialTypeInFramework() == Rules.DONOTALLOW) {
				error = msg;
				return false;
			}
			ret = true;
		}
		o.setParent(old);
		return ret;
	}

	@Override
	public void restoreFromSave(Element root) {
		super.restoreFromSave(root);
		String check = XMLUtility.getValue(root, "QUANTITY");
		if ((check != null) && (check.trim().length() > 0)) {
			try {
				quantity = Integer.parseInt(check);
			} catch (Exception exp) {
				quantity = 1;
			}
		} else {
			quantity = 1;
		}
	}
}