/**
 * Copyright © 2009-2010, Bruce-Robert Pocock & Res Interactive, LLC.
 * All Rights Reserved. Licensed for perpetual use, modification, and/or
 * distribution by either party.
 * 
 * @author brpocock@star-hope.org
 */
package com.tootsville.game;

import java.math.BigInteger;

import org.json.JSONException;
import org.json.JSONObject;
import org.starhope.appius.except.AlreadyExistsException;
import org.starhope.appius.except.NotFoundException;
import org.starhope.appius.except.UserDeadException;
import org.starhope.appius.game.AppiusClaudiusCaecus;
import org.starhope.appius.game.GameEvent;
import org.starhope.appius.game.Zone;
import org.starhope.appius.room.Room;
import org.starhope.appius.user.AbstractUser;
import org.starhope.appius.user.GeneralUser;
import org.starhope.appius.user.Nomenclator;
import org.starhope.appius.util.AppiusConfig;

import com.tootsville.user.Toot;

/**
 * Shaddow Falls is the home of the evil Shade, arch-nemesis of the
 * Toots. Toots standing in Shaddow Falls are subject to an attrition of
 * peanuts, except: God, Shade, Zap, and Catullus.
 * 
 * @author brpocock@star-hope.org
 */
public class ShaddowFalls extends GameEvent {
	/**
	 * Java serialization. serialVersionUID (long)
	 */
	private static final long serialVersionUID = -6938078638060403764L;
	/**
	 * Time at which to next punish users
	 */
	private long tPunish = System.currentTimeMillis ();

	/**
	 * @param z The zone containing this event
	 */
	public ShaddowFalls (final Zone z) {
		super (z, 'P');
		z
				.trace ("Shaddow Falls has become bad for Toots (except Zap, of course!)");
		rooms.clear ();
		Room shaddowFallsRoom;
		try {
			shaddowFallsRoom = z.getRoom ("shaddowFalls");
		} catch (NotFoundException e) {
			AppiusClaudiusCaecus
					.reportBug (
							"Caught a NotFoundException in ShaddowFalls.ShaddowFalls ",
							e);
			throw new RuntimeException (e);
		}
		rooms.add (shaddowFallsRoom);
		shaddowFallsRoom.add (this);
		AppiusClaudiusCaecus.add (this);
	}
	
	/**
	 * This is an overriding method.
	 * 
	 * @see org.starhope.appius.room.RoomListener#acceptGameAction(AbstractUser,
	 *      JSONObject)
	 */
	@Override
	public void acceptGameAction (final AbstractUser sender,
			final JSONObject action) {
		// No op

	}
	
	/**
	 * This is an overriding method.
	 * 
	 * @see org.starhope.appius.room.RoomListener#acceptOutOfBandMessage(AbstractUser,
	 *      Room, JSONObject)
	 */
	@Override
	public void acceptOutOfBandMessage (final AbstractUser sender,
			final Room room, final JSONObject body) {
		// No op

	}
	
	/**
	 * This is an overriding method.
	 * 
	 * @see org.starhope.appius.room.RoomListener#acceptPublicMessage(AbstractUser,
	 *      Room, String)
	 */
	@Override
	public void acceptPublicMessage (final AbstractUser sender,
			final Room room, final String message) {
		noOp ();
	}
	
	/**
	 * This is an overriding method.
	 * 
	 * @see org.starhope.appius.room.RoomListener#acceptPublicMessage(org.starhope.appius.user.AbstractUser,
	 *      java.lang.String)
	 */
	@Override
	public void acceptPublicMessage (final AbstractUser from,
			final String message) {
		noOp ();
	}

	/**
	 * @see org.starhope.appius.room.RoomListener#acceptUserAction(org.starhope.appius.room.Room, org.starhope.appius.user.AbstractUser)
	 */
	@Override
	public void acceptUserAction (final Room r, final AbstractUser u) {
		// no op
	}

	/**
	 * This is an overriding method.
	 *
	 * @see org.starhope.appius.game.GameEvent#getGameEventPrefix()
	 */
	@Override
	public String getGameEventPrefix () {
		return "shaddowFalls";
	}

	/**
	 * This is an overriding method.
	 *
	 * @see org.starhope.appius.util.HasName#getName()
	 */
	@Override
	public String getName () {
		return "ShaddowFalls in "
				+ rooms.first ().getZone ().getName ();
	}

	/**
	 * No op
	 */
	public void noOp () {
		// Yep. No op.
	}

	/**
	 * This is an overriding method.
	 *
	 * @see org.starhope.appius.game.GameEvent#tick(long, long)
	 */
	@Override
	public void tick (final long t, final long dT)
			throws UserDeadException {
		super.tick (t, dT);
		if (tPunish < t) {
			long stolen = 0;
			final int attrition = -AppiusConfig.getIntOrDefault (
					"com.tootsville.ShaddowFalls.attrition", 5);
			if (0 == attrition) {
				return;
			}
			final BigInteger attritionNum = BigInteger
					.valueOf (attrition);
			final int userID_Shade = 99236;
			for (final AbstractUser thing : getSpectators ()) {
				if (thing instanceof GeneralUser) {
					final GeneralUser user = (GeneralUser) thing;
					final int userID_God = 1;
					final int userID_Catullus = 8260;
					final int userID_Zap = 110;
					if (user.getUserID () != userID_Shade
							&& user.getUserID () != userID_God
							&& user.getUserID () != userID_Catullus
							&& user.getUserID () != userID_Zap) {
						try {
							if (user instanceof Toot) {
								((Toot) user).giftPeanuts (
										attritionNum, "shaddowFalls");
							}
						} catch (final AlreadyExistsException e) {
							// ignore
						} catch (final JSONException e) {
							// ignore
						}
						stolen -= attrition; // double negative
					}
				}
			}
			if (stolen > 0) {
				try {
					((Toot) Nomenclator.getUserByID (userID_Shade))
							.giftPeanuts (BigInteger.valueOf (stolen),
									"shaddowFalls");
				} catch (final AlreadyExistsException e) {
					// ignore
				} catch (final JSONException e) {
					// ignore
				}
			}
			tPunish = tPunish
					+ AppiusConfig.getIntOrDefault (
							"com.tootsville.ShaddowFalls.rate", 30000);
		}
	}

}
