/**
 * Copyright © 2010, Res Interactive, LLC. All Rights Reserved.
 */
package com.tootsville.items;

import java.math.BigInteger;

import org.json.JSONException;
import org.starhope.appius.except.AlreadyExistsException;
import org.starhope.appius.except.NotFoundException;
import org.starhope.appius.game.AppiusClaudiusCaecus;
import org.starhope.appius.game.DamageArea;
import org.starhope.appius.game.DamageTypeRanks;
import org.starhope.appius.game.inventory.InventoryItem;
import org.starhope.appius.game.inventory.effects.SimpleRangedWeapon;
import org.starhope.appius.game.npc.DamageHitHandler;
import org.starhope.appius.game.npc.DamageMissHandler;
import org.starhope.appius.game.npc.Projectile;
import org.starhope.appius.user.AbstractUser;
import org.starhope.appius.user.AvatarClass;
import org.starhope.appius.user.Nomenclator;
import org.starhope.appius.user.events.Quaestor;
import org.starhope.appius.util.AppiusConfig;

import com.tootsville.user.Toot;

/**
 * Item that projects “balls of Shadow” at a target.
 * 
 * @author brpocock@star-hope.org
 */
public class ShadowCaster extends SimpleRangedWeapon implements
		DamageHitHandler, DamageMissHandler {

	/**
	 * Java serialisation unique ID
	 */
	private static final long serialVersionUID = -349178325942694675L;

	/**
	 * @param theItem The item associated with this effect
	 */
	public ShadowCaster (final InventoryItem theItem) {
		super (theItem);
		setLimitedAmmunition (false);
		setAmmunition (theItem.getHealth ().intValueExact ());
		setMaxAmmunition (10);
		setAvatarUseAction (null);
		try {
			setProjectileAvatar (Nomenclator.getDataRecord (
					AvatarClass.class, "Shade.Shot"));
		} catch (final NotFoundException e) {
			throw AppiusClaudiusCaecus.fatalBug (
					"Can't get the bullet avatar ", e);
		}
		setHitHandler (this);
		setHitAvatar (null);
		setMissAvatar (null);
		setMissHandler (this);
		setRepeatRateMillis (500);
		setShotDelayMillis (250);
		setTravelRate (75);
		travelsToEdgeOfScreen = true;
	}

	/**
	 * @see org.starhope.appius.game.npc.DamageMissHandler#damageMiss(org.starhope.appius.game.npc.Projectile)
	 */
	@Override
	public void damageMiss (final Projectile projectile) {
		// no op
	}

	/**
	 * @see org.starhope.appius.game.npc.DamageHitHandler#hitForDamage(org.starhope.appius.game.npc.Projectile,
	 *      org.starhope.appius.user.AbstractUser)
	 */
	@Override
	public void hitForDamage (final Projectile projectile,
			final AbstractUser victim) {
		final BigInteger shadeHurtValue = BigInteger
				.valueOf ( -AppiusConfig.getIntOrDefault (
						"com.tootsville.shade.hurts", 100));
		DamageTypeRanks shadowDamage = new DamageTypeRanks ();
		try {
			shadowDamage.add (Nomenclator.getDataRecord (
					DamageArea.class, "Shadow"), shadeHurtValue
					.intValue ()
					/ -10);
		} catch (final NotFoundException e) {
			throw AppiusClaudiusCaecus.fatalBug (e);
		}
		if ( !victim.takeAttack (shadowDamage)) {
			return;
		}
		if (victim instanceof Toot) {
			try {
				((Toot) victim).transferPeanuts (shadeHurtValue,
						(Toot) item.getOwner (), "shaddowFalls");
			} catch (AlreadyExistsException e) {
				AppiusClaudiusCaecus
						.reportBug (
								"Caught a AlreadyExistsException in ShadeHitHandler.hitWithoutShield ",
								e);
			} catch (JSONException e) {
				AppiusClaudiusCaecus
						.reportBug (
								"Caught a JSONException in ShadeHitHandler.hitWithoutShield ",
								e);
			}
		}
	}

	/**
	 * @see org.starhope.appius.game.inventory.ItemEffects#takeDamage(org.starhope.appius.game.DamageTypeRanks)
	 */
	@Override
	public void takeDamage (final DamageTypeRanks attacks) {
		double wishDamage = 0;
		try {
			final DamageArea wishType = Nomenclator.getDataRecord (
					DamageArea.class, "Wish");
			wishDamage = attacks.get (wishType);
			if (wishDamage > 0) {
				try {
					Quaestor.startEvent (item.getOwner (), "givenuts")
							.end (
									BigInteger
											.valueOf ((long) ( -10L * wishDamage)));
				} catch (AlreadyExistsException e) {
					AppiusClaudiusCaecus
							.reportBug (
									"Caught a AlreadyExistsException in ShadowCaster.takeDamage ",
									e);
				} catch (NotFoundException e) {
					AppiusClaudiusCaecus
							.reportBug (
									"Caught a NotFoundException in ShadowCaster.takeDamage ",
									e);
				}
				attacks.subtract (wishType, wishDamage);
			}
		} catch (NotFoundException e) {
			AppiusClaudiusCaecus
					.reportBug (
							"Caught a NotFoundException in ShadowCaster.takeDamage ",
							e);
		}
		super.takeDamage (attacks);
	}

}
