key0-96/
key0-96/doc/key/
key0-96/doc/key/credits/
key0-96/doc/key/developers/
key0-96/doc/key/developers/resources/
key0-96/setup/caves/
key0-96/setup/help/
key0-96/setup/ruins/
key0-96/src/
key0-96/src/commands/
key0-96/src/events/
key0-96/src/hack/
key0-96/src/sql/
key0-96/src/swing/
key0-96/src/talker/forest/
key0-96/src/talker/objects/
key0-96/src/terminals/
/*
**               j###t  ########## ####   ####
**              j###t   ########## ####   ####
**             j###T               "###L J###"
**          ######P'    ##########  #########
**          ######k,    ##########   T######T
**          ####~###L   ####
**          #### q###L  ##########   .#####
**          ####  \###L ##########   #####"
*/

package key;

import java.util.Enumeration;
import java.util.StringTokenizer;
import java.io.*;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
  *  Material
  *
  *  The base class for most user-manipulatable objects
 */
public class MaterialContainer extends Container implements Thing
{
	private static final long serialVersionUID = 1249752029572260365L;
	
	public static final AtomicElement[] ELEMENTS =
	{
		AtomicElement.construct( MaterialContainer.class, Material.class, "material",
			AtomicElement.PUBLIC_FIELD,
			"the material of this container - all requests will be passed to it" )
	};
	
	public static final AtomicStructure STRUCTURE = new AtomicStructure( Container.STRUCTURE, ELEMENTS );
	
	public Reference material = Reference.EMPTY;
	
	public MaterialContainer()
	{
	}

	private final Material getMaterial()
	{
		try
		{
			return( (Material) material.get() );
		}
		catch( OutOfDateReferenceException e )
		{
			material = Reference.EMPTY;
			return( null );
		}
		catch( ClassCastException e )
		{
			Log.error( getId() + ".material", e );
			material = Reference.EMPTY;
			return( null );
		}
	}
	
	public AtomicStructure getDeclaredStructure()
	{
		return( STRUCTURE );
	}
	
	public String getFullPortrait( Player p )
	{
		try
		{
			return( getMaterial().getFullPortrait( p, this ) );
		}
		catch( NullPointerException e )
		{
			return( "the object" );
		}
	}
	
	public void use( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom m )
	{
		try
		{
			getMaterial().use( p, args, ic, flags, this );
		}
		catch( NullPointerException e )
		{
		}
	}
	
	public void wear( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom m )
	{
		try
		{
			getMaterial().wear( p, args, ic, flags, this );
		}
		catch( NullPointerException e )
		{
		}
	}
	
	public void remove( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom m )
	{
		try
		{
			getMaterial().remove( p, args, ic, flags, this );
		}
		catch( NullPointerException e )
		{
		}
	}
	
	public void wield( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom m )
	{
		try
		{
			getMaterial().wield( p, args, ic, flags, this );
		}
		catch( NullPointerException e )
		{
		}
	}
	
	public void give( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom m )
	{
		try
		{
			getMaterial().give( p, args, ic, flags, this );
		}
		catch( NullPointerException e )
		{
		}
	}
	
	public void read( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom m )
	{
		try
		{
			getMaterial().read( p, args, ic, flags, this );
		}
		catch( NullPointerException e )
		{
		}
	}
	
	public void look( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom m )
	{
		try
		{
			getMaterial().look( p, args, ic, flags, this );
		}
		catch( NullPointerException e )
		{
		}
	}
	
	public boolean isMethodSpecial( Method m )
	{
		Class dc = m.getDeclaringClass();
		
		return( dc != MaterialContainer.class &&
				!Modifier.isFinal( m.getModifiers() ) &&
				!Modifier.isAbstract( m.getModifiers() )
			  );
	}
	
	protected final void defaultInspect( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom m )
	{
		Material.standardInspect( p, args, ic, flags, this );
	}
	
	public void inspect( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom actual )
	{
		Material m = getMaterial();
		
		if( m != null )
			ic.send( new HeadingParagraph( "Container" ) );
		
		defaultInspect( p, args, ic, flags, this );
		
		if( m != null )
		{
			ic.send( new HeadingParagraph( "Material" ) );
			m.inspect( p, args, ic, flags, this );
		}
	}
	
	public void get( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom m )
	{
		try
		{
			getMaterial().get( p, args, ic, flags, this );
		}
		catch( NullPointerException e )
		{
		}
	}
	
	public void drop( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom m )
	{
		try
		{
			getMaterial().drop( p, args, ic, flags, this );
		}
		catch( NullPointerException e )
		{
		}
	}
	
	public void sit( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom m )
	{
		try
		{
			getMaterial().sit( p, args, ic, flags, this );
		}
		catch( NullPointerException e )
		{
		}
	}
	
	public void stand( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom m )
	{
		try
		{
			getMaterial().stand( p, args, ic, flags, this );
		}
		catch( NullPointerException e )
		{
		}
	}
	
	public void drink( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom m )
	{
		try
		{
			getMaterial().drink( p, args, ic, flags, this );
		}
		catch( NullPointerException e )
		{
		}
	}
	
	public void eat( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom m )
	{
		try
		{
			getMaterial().eat( p, args, ic, flags, this );
		}
		catch( NullPointerException e )
		{
		}
	}
	
	public void open( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom m )
	{
		try
		{
			getMaterial().open( p, args, ic, flags, this );
		}
		catch( NullPointerException e )
		{
		}
	}
	
	public void close( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom m )
	{
		try
		{
			getMaterial().close( p, args, ic, flags, this );
		}
		catch( NullPointerException e )
		{
		}
	}
	
	public void fill( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom m )
	{
		try
		{
			getMaterial().fill( p, args, ic, flags, this );
		}
		catch( NullPointerException e )
		{
		}
	}
	
	public void lock( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom m )
	{
		try
		{
			getMaterial().lock( p, args, ic, flags, this );
		}
		catch( NullPointerException e )
		{
		}
	}
	
	public void unlock( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom m )
	{
		try
		{
			getMaterial().unlock( p, args, ic, flags, this );
		}
		catch( NullPointerException e )
		{
		}
	}
	
	public Reference build( Player p )
	{
		MaterialContainer mc = (MaterialContainer) Factory.makeAtom( getClass(), getName() );
		try
		{
			p.objects.add( mc );
		}
		catch( Exception e )
		{
			p.sendFeedback( "Could not create object: " + e.toString() );
			return( Reference.EMPTY );
		}
		
		return( mc.getThis() );
	}
}