package com.hero.objects.powers;

import java.math.BigDecimal;
import java.text.DecimalFormat;

import org.jdom.Element;

import com.hero.HeroDesigner;
import com.hero.objects.GenericObject;
import com.hero.ui.dialog.GenericDialog;
import com.hero.ui.dialog.PowerDialog;
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 Growth extends Power {

	private static String xmlID = "GROWTH";

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

	@Override
	public String getColumn2Output() {
		String ret = getAlias() + " (" + getPlainDamageDisplay() + ")";
		if (getName().trim().length() > 0) {
			ret = "<i>" + getName() + ":</i>  " + ret;
		}
		if ((getInput() != null) && (getInput().trim().length() > 0)) {
			ret += ":  " + getInput();
		}
		if (getSelectedOption() != null && !HeroDesigner.getActiveTemplate().is6E()) {
			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() {
		return "<html>" + getPlainDamageDisplay() + "</html>";
	}

	@Override
	public GenericDialog getDialog(boolean isNew, boolean isPower) {
		PowerDialog d = new PowerDialog(this, isNew, isPower);
		d.setSize(d.getSize().width + 100, d.getSize().height);
		return d;
	}

	private String getPlainDamageDisplay() {
		if (HeroDesigner.getActiveTemplate().is6E() && getSelectedOption() != null) {
			DecimalFormat formatter = new DecimalFormat("#,###");
			long g = Rounder.roundHalfUp(HeroDesigner.getActiveHero()
					.getWeight() * 453.5924);
			if (HeroDesigner.getInstance().getPrefs().isMetric()) {
				g = HeroDesigner.getActiveHero().getWeight() * 1000;
			}
			g = g
					* (long) Math
							.pow(
									massMultiplier,
									((double) getLevels() / (double) massMultiplierLevels));
			BigDecimal wght = new BigDecimal(g / 100000d);
			wght = wght.setScale(0, BigDecimal.ROUND_HALF_UP);
			wght = new BigDecimal(wght.doubleValue() * 100);
			wght = wght.setScale(0, BigDecimal.ROUND_HALF_UP);
			if (g / 100000d > 9999) {
				formatter = new DecimalFormat("#.###E0");
			}
			String weight = formatter.format(g / 1000d) + " kg";
			
			double cm = HeroDesigner.getActiveHero().getHeight() * 2.54;
			if (HeroDesigner.getInstance().getPrefs().isMetric()) {
				cm = HeroDesigner.getActiveHero().getHeight();
			}
			if (getLevels() >= getHeightIncreaseLevels()) {
				if (HeroDesigner.getActiveHero().getRules()
						.useExpandedGrowthChart()) {
					cm = Math
							.pow(
									getHeightIncrease(),
									((double) getLevels() / (double) getHeightIncreaseLevels()))
							* cm;
				} else {
					cm = Math.pow(getHeightIncrease(),
							(getLevels() / getHeightIncreaseLevels()))
							* cm;
				}
			} else if (HeroDesigner.getActiveHero().getRules()
					.useExpandedGrowthChart()) {
				cm = Math
						.pow(
								getHeightIncrease(),
								((double) getLevels() / (double) getHeightIncreaseLevels()))
						* cm;
			}
			double ht = cm / 100;
			double wd = cm / 200;
			formatter = new DecimalFormat("#,###");
			if (ht > 9999) {
				formatter = new DecimalFormat("#.###E0");
			} else if (HeroDesigner.getActiveHero().getRules()
					.useExpandedGrowthChart()) {
				formatter = new DecimalFormat("#,###.#");
			}
			String size = formatter.format(ht) + " m tall, ";
			formatter = new DecimalFormat("#,###");
			if (wd > 9999) {
				formatter = new DecimalFormat("#.###E0");
			} else if (HeroDesigner.getActiveHero().getRules()
					.useExpandedGrowthChart()) {
				formatter = new DecimalFormat("#,###.#");
			}
			size += formatter.format(wd) + " m wide";

			int STR = 0;
			int CON = 0;
			int PRE = 0;
			int PD = 0;
			int ED = 0;
			int BODY = 0;
			int STUN = 0;
			int reach = 0;
			int running = 0;
			int kb = 0;
			int radius = 0;
			int ocv = 0;
			int per = 0;
			if (getSelectedOption().getXMLID().equals("LARGE")) {
				STR = 15;
				CON =5;
				PRE = 5;
				PD = 3;
				ED = 3;
				BODY =3;
				STUN = 6;
				reach = 1;
				running = 12;
				kb = 6;
				radius = 0;
				ocv = 2;
				per = 2;
				weight="101-800 kg";
				size = "2-4m tall, 1-2m wide";
			} else if (getSelectedOption().getXMLID().equals("ENORMOUS")) {
				STR = 30;
				CON =10;
				PRE = 10;
				PD = 6;
				ED = 6;
				BODY =6;
				STUN = 12;
				reach = 3;
				running = 24;
				kb = 12;
				radius = 0;
				ocv = 4;
				per = 4;
				weight="801-6,400 kg";
				size = "5-8m tall, 3-4m wide";
			} else if (getSelectedOption().getXMLID().equals("HUGE")) {
				STR = 45;
				CON =15;
				PRE = 15;
				PD = 9;
				ED = 9;
				BODY =9;
				STUN = 18;
				reach = 7;
				running = 36;
				kb = 18;
				radius = 1;
				ocv = 6;
				per = 6;
				weight="6,401-50,000 kg";
				size = "9-16m tall, 5-8m wide";
			} else if (getSelectedOption().getXMLID().equals("GIGANTIC")) {
				STR = 60;
				CON =20;
				PRE = 20;
				PD = 12;
				ED = 12;
				BODY =12;
				STUN = 24;
				reach = 15;
				running = 48;
				kb = 24;
				radius = 2;
				ocv = 8;
				per = 8;
				weight="50,001-400,000 kg";
				size = "17-32m tall, 9-16m wide";
			}  else if (getSelectedOption().getXMLID().equals("GARGANTUAN")) {
				STR = 75;
				CON =25;
				PRE = 25;
				PD = 15;
				ED = 15;
				BODY =15;
				STUN = 30;
				reach = 31;
				running = 60;
				kb = 30;
				radius = 3;
				ocv = 10;
				per = 10;
				weight="40,001-3.2 mil kg";
				size = "33-64m tall, 17-32m wide";
			} else if (getSelectedOption().getXMLID().equals("COLOSSAL")) {
				STR = 90;
				CON =30;
				PRE = 30;
				PD = 18;
				ED = 18;
				BODY =18;
				STUN = 36;
				reach = 63;
				running = 72;
				kb = 36;
				radius = 4;
				ocv = 12;
				per = 12;
				weight="3.3-25.6 mil kg";
				size = "65-125m tall, 33-64m wide";
			}
			String ret = "+"+STR+" STR, " +
					"+"+CON+" CON, " +
					"+"+PRE+" PRE, " +
					"+"+PD+" PD, " +
					"+"+ED+" ED, " +
					"+"+BODY+" BODY, " +
					"+"+STUN+" STUN, " +
					"+"+reach+"m Reach, " +
					"+"+running+"m Running, " +
					"-"+kb+"m KB, " +
					(radius>0?"hands/feet are Area Of Effect ("+radius+"m Radius) attacks, ":"") +
					weight +
					", +"+ocv+" to OCV to hit, " +
					"+"+per+" to PER Rolls to perceive character, " +
					size;
			return ret;
		} else {
			DecimalFormat formatter = new DecimalFormat("#,###");
			long g = Rounder.roundHalfUp(HeroDesigner.getActiveHero()
					.getWeight() * 453.5924);
			if (HeroDesigner.getInstance().getPrefs().isMetric()) {
				g = HeroDesigner.getActiveHero().getWeight() * 1000;
			}
			g = g
					* (long) Math
							.pow(
									massMultiplier,
									((double) getLevels() / (double) massMultiplierLevels));
			BigDecimal wght = new BigDecimal(g / 100000d);
			wght = wght.setScale(0, BigDecimal.ROUND_HALF_UP);
			wght = new BigDecimal(wght.doubleValue() * 100);
			wght = wght.setScale(0, BigDecimal.ROUND_HALF_UP);
			if (g / 100000d > 9999) {
				formatter = new DecimalFormat("#.###E0");
			}
			String weight = formatter.format(g / 1000d) + " kg";
			String str = "+"
					+ (int) getStrIncrease()
					* Rounder.roundDown((double) getLevels()
							/ (double) strIncreaseLevels) + " STR";
			int bd = (int) Rounder.roundHalfUp(bodyIncrease
					* Rounder.roundDown((double) getLevels()
							/ (double) bodyIncreaseLevels));
			int kb = (int) Rounder.roundHalfUp(kbIncrease
					* Rounder.roundDown((double) getLevels()
							/ (double) kbIncreaseLevels));
			int st = (int) Rounder.roundHalfUp(stunIncrease
					* Rounder.roundDown((double) getLevels()
							/ (double) stunIncreaseLevels));
			int dcv = (int) Rounder.roundHalfUp(dcvIncrease
					* Rounder.roundDown((double) getLevels()
							/ (double) dcvIncreaseLevels));
			int per = (int) Rounder.roundHalfUp(perIncrease
					* Rounder.roundDown((double) getLevels()
							/ (double) perIncreaseLevels));

			if (HeroDesigner.getActiveHero().getRules()
					.useExpandedGrowthChart()) {
				str = "+"
						+ (int) getStrIncrease()
						* Rounder.roundHalfUp((double) getLevels()
								/ (double) strIncreaseLevels) + " STR";
				bd = (int) (bodyIncrease / Math.abs(bodyIncrease) * Rounder
						.roundDown(Math.abs(bodyIncrease) * getLevels()
								/ bodyIncreaseLevels));
				kb = (int) (kbIncrease / Math.abs(kbIncrease) * Rounder
						.roundDown(Math.abs(kbIncrease) * getLevels()
								/ kbIncreaseLevels));
				st = (int) (stunIncrease / Math.abs(stunIncrease) * Rounder
						.roundDown(Math.abs(stunIncrease) * getLevels()
								/ stunIncreaseLevels));
				dcv = (int) (dcvIncrease / Math.abs(dcvIncrease) * Rounder
						.roundDown(Math.abs(dcvIncrease) * getLevels()
								/ dcvIncreaseLevels));
				per = (int) (perIncrease / Math.abs(perIncrease) * Rounder
						.roundDown(Math.abs(perIncrease) * getLevels()
								/ perIncreaseLevels));
			}

			String PER = "+" + per + " PER Rolls to perceive character";
			String DCV = (dcv < 0 ? "" : "+") + dcv + " DCV";
			String kbdec = (kb < 0 ? "" : "+") + kb + "\" KB";
			if (HeroDesigner.getActiveTemplate().is6E()) {
				kbdec = (kb < 0 ? "" : "+") + kb + "m KB";
			}
			String body = "+" + bd + " BODY";
			String stun = "+" + st + " STUN";

			double cm = HeroDesigner.getActiveHero().getHeight() * 2.54;
			if (HeroDesigner.getInstance().getPrefs().isMetric()) {
				cm = HeroDesigner.getActiveHero().getHeight();
			}
			if (getLevels() >= getHeightIncreaseLevels()) {
				if (HeroDesigner.getActiveHero().getRules()
						.useExpandedGrowthChart()) {
					cm = Math
							.pow(
									getHeightIncrease(),
									((double) getLevels() / (double) getHeightIncreaseLevels()))
							* cm;
				} else {
					cm = Math.pow(getHeightIncrease(),
							(getLevels() / getHeightIncreaseLevels()))
							* cm;
				}
			} else if (HeroDesigner.getActiveHero().getRules()
					.useExpandedGrowthChart()) {
				cm = Math
						.pow(
								getHeightIncrease(),
								((double) getLevels() / (double) getHeightIncreaseLevels()))
						* cm;
			}
			double ht = cm / 100;
			double wd = cm / 200;
			formatter = new DecimalFormat("#,###");
			if (ht > 9999) {
				formatter = new DecimalFormat("#.###E0");
			} else if (HeroDesigner.getActiveHero().getRules()
					.useExpandedGrowthChart()) {
				formatter = new DecimalFormat("#,###.#");
			}
			String size = formatter.format(ht) + " m tall, ";
			formatter = new DecimalFormat("#,###");
			if (wd > 9999) {
				formatter = new DecimalFormat("#.###E0");
			} else if (HeroDesigner.getActiveHero().getRules()
					.useExpandedGrowthChart()) {
				formatter = new DecimalFormat("#,###.#");
			}
			size += formatter.format(wd) + " m wide";

			double rch = 0;
			if (getLevels() / getReachIncreaseLevels() >= 1) {
				if (getLevels() / getReachIncreaseLevels() >= 2) {
					if (getLevels() / getReachIncreaseLevels() >= 3) {
						double pow = (double) getLevels()
								/ (double) getReachIncreaseLevels();
						pow = pow - 1;
						rch = (int) Math.pow(reachIncrease, pow);
					} else {
						rch = 2;
					}
				} else {
					rch = 1;
				}
			}
			formatter = new DecimalFormat("#,###");
			if (rch > 9999) {
				formatter = new DecimalFormat("#.###E0");
				// String reach = formatter.format(rch)+"\" reach";
			}

			String ret = str + ", " + body + ", " + stun + ", " + kbdec + ", "
					+ weight + ", " + DCV + ", " + PER + ", " + size;
			return ret;
		}
	}
}