/**
 * <p>
 * Copyright © 2009-2010, Bruce-Robert Pocock
 * </p>
 * <p>
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or (at
 * your option) any later version.
 * </p>
 * <p>
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 * </p>
 * <p>
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 * </p>
 * 
 * @author brpocock
 */

package org.starhope.appius.user;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

import org.json.JSONException;
import org.json.JSONObject;
import org.starhope.appius.except.GameLogicException;
import org.starhope.appius.except.NotFoundException;
import org.starhope.appius.except.PrivilegeRequiredException;
import org.starhope.appius.except.UserDeadException;
import org.starhope.appius.game.AbstractRoom;
import org.starhope.appius.game.AppiusClaudiusCaecus;
import org.starhope.appius.game.RoomListener;
import org.starhope.appius.game.inventory.ClothingItem;
import org.starhope.appius.game.inventory.HomeDecorItem;
import org.starhope.appius.game.inventory.InventoryItem;
import org.starhope.appius.types.AbstractZone;
import org.starhope.appius.types.Colour;

/**
 * 
 * Any “thing” that exists in the game world and participates therein
 * should implement the AbstractUser interface. This interface provides
 * the “physicality” (no, that's not a word) necessary for something to
 * participate in the game rooms.
 * 
 * @author brpocock
 * 
 */
public interface AbstractUser extends RoomListener {
	/**
	 * @see #acceptAdminMessage(Integer, String)
	 * 
	 * @param room The room in which the administrative message is being
	 *            sent (often ignored)
	 * @param string The administrative message.
	 */
	public void acceptAdminMessage (AbstractRoom room, String string);

	/**
	 * Accept a message from an administrator or the system. If the user
	 * is connected, propagate that message to their client.
	 * 
	 * @param room The room in which the administrative message is being
	 *            sent (often ignored)
	 * @param string The administrative message.
	 */
	public void acceptAdminMessage (final Integer room,
			final String string);

	/**
	 * TODO: document this method (brpocock, Jan 11, 2010)
	 * 
	 * @param content WRITEME
	 * @param title WRITEME
	 * @param label WRITEME
	 * 
	 */
	public void acceptAdminMessage (String content, String title,
			String label);

	/**
	 * @param command WRITEME
	 * @param error WRITEME
	 * @param result WRITEME
	 * @param userCurrentRoomInZone WRITEME
	 */
	public void acceptErrorReply (String command, String error,
			JSONObject result, AbstractRoom userCurrentRoomInZone);

	/**
	 * @param string WRITEME
	 * @param string2 WRITEME
	 * @param string3 WRITEME
	 */
	public void acceptMessage (String string, String string2,
			String string3);

	/**
	 * @param zone WRITEME
	 * @param room WRITEME
	 * @param command WRITEME
	 * @param jsonData WRITEME
	 * @deprecated use {@link #acceptSuccessReply( String, JSONObject,AbstractRoom)}; zone is unnecessary
	 */
	@Deprecated
	public void acceptSuccessReply (AbstractZone zone,
			AbstractRoom room, String command, JSONObject jsonData);

	/**
	 * @param room WRITEME
	 * @param command WRITEME
	 * @param jsonData WRITEME
	 */
	public void acceptSuccessReply (String command, JSONObject jsonData,
			AbstractRoom room);

	/**
	 * @param buddy WRITEME
	 */
	public void addBuddy (AbstractUser buddy);

	/**
	 * @param i WRITEME
	 * @param days WRITEME
	 */
	public void addGiftSubscription (int i, int days);

	/**
	 * @param parseInt WRITEME
	 */
	public void addItem (int parseInt);

	/**
	 * @param staffLevelStaffMember WRITEME
	 * @throws PrivilegeRequiredException WRITEME
	 */
	public void assertStaffLevel (int staffLevelStaffMember)
	throws PrivilegeRequiredException;

	/**
	 * @param byLogin WRITEME
	 */
	public void attend (AbstractUser byLogin);

	/**
	 * @param u WRITEME
	 * @param banReason WRITEME
	 * @throws PrivilegeRequiredException WRITEME
	 */
	public void ban (AbstractUser u, String banReason)
	throws PrivilegeRequiredException;

	/**
	 * TODO: document this method (brpocock, Jan 15, 2010)
	 * 
	 * @param eventID the ID returned from startEvent
	 */
	public void cancelEvent (int eventID);

	/**
	 * @return WRITEME
	 */
	public boolean canTalk ();

	/**
	 * WRITEME
	 */
	public void doffClothes ();

	/**
	 * WRITEME
	 */
	public void doTransport ();

	/**
	 * WRITEME: document this method (brpocock, Jan 15, 2010)
	 * 
	 * @param eventID the ID returned from startEvent
	 * @param moniker the event's moniker
	 * @param score the user's score
	 * @param medal any medal earned
	 * @return results of ending the event WRITEME
	 * @throws JSONException WRITEME
	 */
	public JSONObject endEvent (int eventID, String moniker,
			BigDecimal score, String medal) throws JSONException;

	/**
	 * @param eventID WRITEME
	 * @param gameMoniker WRITEME
	 * @param string WRITEME
	 * @param playerScoreDecimal WRITEME
	 * @param sortedScores WRITEME
	 * @return WRITEME
	 * @throws JSONException WRITEME
	 */
	public JSONObject endMultiplayerEvent (Integer eventID,
			String gameMoniker, String string,
			BigDecimal playerScoreDecimal,
			LinkedHashMap <Integer, Integer> sortedScores)
	throws JSONException;

	/**
	 * @param roomInHouse WRITEME
	 * @return WRITEME
	 * @throws NotFoundException WRITEME
	 */
	public Collection <HomeDecorItem> getActiveDecorations (
			int roomInHouse) throws NotFoundException;

	/**
	 * @return WRITEME
	 */
	public int getAge ();

	/**
	 * @return WRITEME
	 */
	public String getApprovedDateString ();

	/**
	 * @return WRITEME
	 */
	public AvatarClass getAvatarClass ();

	/**
	 * The avatar label is the text block that is displayed with the
	 * avatar for this object. It should be unique but isn't guaranteed
	 * to be distinct as user names are. (At any given moment, there can
	 * be only one object with a given avatar label in the room, but
	 * there can be only one user with a given name in the multiverse.)
	 * For users, this is the user name.
	 * 
	 * @return The avatar label
	 */
	public String getAvatarLabel ();

	/**
	 * TODO: document this method (brpocock, Jan 11, 2010)
	 * 
	 * @return WRITEME
	 */
	public Collection <String> getBuddyListNames ();

	/**
	 * @return WRITEME
	 */
	public String getDialect ();

	/**
	 * @return WRITEME
	 */
	public String getDisplayName ();

	/**
	 * Get the string identifying the direction which this object is
	 * facing. One of: N,S,E,W,NE,NW,SW,SE.
	 * 
	 * @return The facing direction of this object
	 */
	public String getFacing ();

	/**
	 * @param int1 WRITEME
	 * @return WRITEME
	 * @throws NotFoundException WRITEME
	 */
	public HomeDecorItem getFurnitureBySlot (int int1)
	throws NotFoundException;

	/**
	 * @return WRITEME
	 */
	public String getIPAddress ();

	/**
	 * @param typeString WRITEME
	 * @return WRITEME
	 */
	public Collection <InventoryItem> getItemsByType (String typeString);

	/**
	 * @return WRITEME
	 */
	public int getKickedByUserID ();

	/**
	 * @return WRITEME
	 */
	public String getKickedMessage ();

	/**
	 * @return WRITEME
	 */
	public String getKickedReasonCode ();

	/**
	 * String?? TODO? FIXME?
	 * 
	 * @return WRITEME
	 */
	public Timestamp getKickedUntil ();

	/**
	 * @return WRITEME
	 */
	public String getLanguage ();

	/**
	 * @return WRITEME
	 */
	public String getMail ();

	/**
	 * @return WRITEME
	 */
	public Date getNameApprovedAt ();

	/**
	 * @return WRITEME
	 */
	public Date getNameRequestedAt ();

	/**
	 * TODO: document this method (brpocock, Oct 31, 2009)
	 * 
	 * avatar, userName, clothes, colors
	 * 
	 * @return WRITEME
	 */
	JSONObject getPublicInfo ();

	/**
	 * @return WRITEME
	 */
	public String getRegisteredDateString ();

	/**
	 * @return WRITEME
	 */
	public String getResponsibleMail ();

	/**
	 * TODO: document this method (brpocock, Jan 11, 2010)
	 * 
	 * @return WRITEME
	 */
	public int getRoomNumber ();

	/**
	 * @return WRITEME
	 */
	public AppiusClaudiusCaecus getServerThread ();

	/**
	 * TODO: document this method (brpocock, Jan 11, 2010)
	 * 
	 * @return WRITEME
	 */
	public int getStaffLevel ();

	/**
	 * TODO: document this method (brpocock, Oct 31, 2009)
	 * 
	 * @return WRITEME
	 */
	public double getTargetX ();

	/**
	 * TODO: document this method (brpocock, Oct 31, 2009)
	 * 
	 * @return WRITEME
	 */
	public double getTargetY ();

	/**
	 * TODO: document this method (brpocock, Nov 24, 2009)
	 * 
	 * @return WRITEME
	 */
	public double getTravelRate ();

	/**
	 * TODO: document this method (brpocock, Nov 24, 2009)
	 * 
	 * @return the time at which the object started moving (msec since
	 *         epoch)
	 */
	public long getTravelStart ();

	/**
	 * TODO: document this method (brpocock, Oct 31, 2009)
	 * 
	 * @return WRITEME
	 */
	public int getUserID ();

	/**
	 * TODO: document this method (brpocock, Jan 11, 2010)
	 * 
	 * @return WRITEME
	 */
	public Map <String, String> getUserVariables ();

	/**
	 * TODO: document this method (brpocock, Oct 31, 2009)
	 * 
	 * @param string WRITEME
	 * @return WRITEME
	 */
	public String getVariable (String string);

	/**
	 * TODO: document this method (brpocock, Oct 31, 2009)
	 * 
	 * @return WRITEME
	 */
	public double getX ();

	/**
	 * TODO: document this method (brpocock, Oct 31, 2009)
	 * 
	 * @return WRITEME
	 */
	public double getY ();

	/**
	 * @param i WRITEME
	 * @return WRITEME
	 */
	public boolean hasStaffLevel (int i);

	/**
	 * TODO: document this method (brpocock, Nov 30, 2009)
	 * 
	 * @param string WRITEME
	 * @return WRITEME
	 */
	public boolean hasVariable (String string);

	/**
	 * @param byLogin WRITEME
	 */
	public void ignore (AbstractUser byLogin);

	/**
	 * @return WRITEME
	 */
	public boolean isBanned ();

	/**
	 * @return WRITEME
	 */
	public boolean isCanceled ();

	/**
	 * @return WRITEME
	 */
	public boolean isKicked ();

	/**
	 * TODO: document this method (brpocock, Oct 31, 2009)
	 * 
	 * @return WRITEME
	 */
	boolean isNPC ();

	/**
	 * TODO: document this method (brpocock, Oct 31, 2009)
	 * 
	 * @return WRITEME
	 */
	boolean isOnline ();

	/**
	 * @return WRITEME
	 */
	public boolean isPaidMember ();

	/**
	 * @param u WRITEME
	 * @param kickReason WRITEME
	 * @param duration WRITEME
	 * @throws PrivilegeRequiredException WRITEME
	 */
	public void kick (AbstractUser u, String kickReason, int duration)
	throws PrivilegeRequiredException;

	/**
	 * WRITEME
	 * 
	 * @param authority WRITEME
	 * @throws PrivilegeRequiredException WRITEME
	 */
	public void liftBan (AbstractUser authority)
	throws PrivilegeRequiredException;

	/**
	 * @param room WRITEME
	 */
	public void notifyFurnitureInventory (AbstractRoom room);

	/**
	 * @param byLogin WRITEME
	 */
	public void removeBuddy (AbstractUser byLogin);

	/**
	 * @param u WRITEME
	 */
	public void reportedToModeratorBy (AbstractUser u);

	/**
	 * @param room WRITEME
	 * @param string WRITEME
	 */
	public void sendEarnings (AbstractRoom room, String string);

	/**
	 * TODO: document this method (brpocock, Jan 11, 2010)
	 * 
	 * @param refugeeZone WRITEME
	 * @throws UserDeadException WRITEME
	 */
	public void sendMigrate (AbstractZone refugeeZone)
	throws UserDeadException;

	/**
	 * WRITEME
	 */
	public void sendOops ();

	/**
	 * @param result WRITEME
	 */
	public void sendResponse (JSONObject result);

	/**
	 * Sends the user an asynchronous notification of their user lists'
	 * status. This is normally triggered by a change in the status of
	 * one of the users on these lists. (Note, User Lists are the buddy
	 * list and ignore list.)
	 */
	public void sendUserLists ();

	/**
	 */
	public void sendWardrobe ();

	/**
	 * WRITEME
	 */
	public void setAgeGroupToSystem ();

	/**
	 * @param colour WRITEME
	 */
	public void setBaseColor (Colour colour);

	/**
	 * @param b WRITEME
	 */
	public void setCanTalk (boolean b);

	/**
	 * @param colour WRITEME
	 */
	public void setExtraColor (Colour colour);

	/**
	 * WRITEME
	 */
	public void setLastActive ();

	/**
	 * @param email WRITEME
	 * @throws GameLogicException WRITEME
	 */
	public void setMail (String email) throws GameLogicException;

	/**
	 * @param room WRITEME
	 * @return WRITEME
	 */
	public int setRoom (AbstractRoom room);

	/**
	 * TODO: document this method (brpocock, Nov 24, 2009)
	 * 
	 * @param when WRITEME
	 */
	public void setStartT (long when);

	/**
	 * @param item WRITEME
	 */
	public void setStructure (HomeDecorItem item);

	/**
	 * TODO: document this method (brpocock, Nov 24, 2009)
	 * 
	 * @param rate WRITEME
	 */
	public void setTravelRate (double rate);

	/**
	 * @param varName WRITEME
	 * @param varValue WRITEME
	 */
	public void setVariable (String varName, String varValue);

	/**
	 * TODO: document this method (brpocock, Nov 24, 2009)
	 * 
	 * @param x2 WRITEME
	 */
	public void setX (double x2);

	/**
	 * TODO: document this method (brpocock, Nov 24, 2009)
	 * 
	 * @param y2 WRITEME
	 */
	public void setY (double y2);

	/**
	 * @param room WRITEME
	 * @param string WRITEME
	 */
	public void speak (AbstractRoom room, String string);

	/**
	 * @param gameMoniker WRITEME
	 * @return WRITEME
	 */
	public JSONObject startEvent (String gameMoniker);

	/**
	 * TODO: document this method (brpocock, Jan 11, 2010)
	 * 
	 * @return WRITEME WRITEME
	 */
	public JSONObject toJSON ();

	/**
	 * TODO: document this method (brpocock, Oct 31, 2009)
	 * 
	 * @return WRITEME
	 */
	public String toSFSXML ();

	/**
	 * @param asClothing WRITEME
	 */
	public void wear (ClothingItem asClothing);

	/**
	 * @param asClothing WRITEME
	 * @param colour WRITEME
	 */
	public void wear (ClothingItem asClothing, Colour colour);
}
