/*
....[@@@..[@@@..............[@.................. MUD++ is a written from
....[@..[@..[@..[@..[@..[@@@@@....[@......[@.... scratch multi-user swords and
....[@..[@..[@..[@..[@..[@..[@..[@@@@@..[@@@@@.. sorcery game written in C++.
....[@......[@..[@..[@..[@..[@....[@......[@.... This server is an ongoing
....[@......[@..[@@@@@..[@@@@@.................. development project.  All 
................................................ contributions are welcome. 
....Copyright(C).1995.Melvin.Smith.............. Enjoy. 
------------------------------------------------------------------------------
Melvin Smith (aka Fusion)         msmith@falcon.mercer.peachnet.edu 
MUD++ development mailing list    mudpp-list@spice.com
------------------------------------------------------------------------------
thing.h
*/

#ifndef _THING_H
#define _THING_H

#include "bit.h"
#include "string.h"
#include "nameable.h"
#include "file.h"

class Object;
class Repop;
class Char;
class Room;
class Affect;

// Size on objects associated with the listed species

const int SIZE_TINY		= 1;	// Imps
const int SIZE_SMALL	= 2;	// Gnomes
const int SIZE_NORMAL	= 3;	// Humans, elves, orcs, hobgoblins
const int SIZE_LARGE	= 4;	// Trolls, ogres 
const int SIZE_HUGE		= 5;	// Medium giants, medium dragons
const int SIZE_GIGANTIC	= 6;	// Largest giants, hydra, dragons, leviathans, etc.


const int MAX_AFFECT_BIT_FIELDS		= 1;

class Thing : public Nameable
{
	protected:
		String shortdesc;
		String longdesc;
		Room *in_room;
		unsigned long aff_bits[ MAX_AFFECT_BIT_FIELDS ];
		short size;   // Tiny, Small, Normal, etc.
		long weight;
		long volume;

	public:
		Thing()
		:	in_room(0), size(SIZE_NORMAL), weight(1), volume(1)
		{
			memset( aff_bits, 0, sizeof( aff_bits[0] ) * MAX_AFFECT_BIT_FIELDS ); 
		}

		// Copy constructor
		Thing( const Thing & x )
		:	Nameable( x ),
			shortdesc( x.shortdesc ), longdesc( x.longdesc ),
			in_room(0), size(x.size), weight(x.weight), volume(x.volume)
		{
			memcpy( (void *)aff_bits, (void *)x.aff_bits,
					sizeof( aff_bits[0] ) * MAX_AFFECT_BIT_FIELDS ); 
		}

		Thing( const char * x )
		:	Nameable(x), size(SIZE_NORMAL), in_room(0), weight(1), volume(1)
		{
			memset( aff_bits, 0, sizeof( aff_bits[0] ) * MAX_AFFECT_BIT_FIELDS ); 
		}

		Thing( const String & x )
		:	Nameable(x), in_room(0), size(SIZE_NORMAL), weight(1), volume(1)
		{
			memset( aff_bits, 0, sizeof( aff_bits[0] ) * MAX_AFFECT_BIT_FIELDS ); 
		}

		Thing( const char *name, const char *sdesc, const char *ldesc )
		:	Nameable(name),
			shortdesc(sdesc), longdesc(ldesc),
			in_room(0), size(SIZE_NORMAL), weight(1), volume(1)
		{
			memset( aff_bits, 0, sizeof( aff_bits[0] ) * MAX_AFFECT_BIT_FIELDS ); 
		}

		virtual ~Thing();

		// Interface for all 'Things'
		// Child classes must implement all pure virtual
		// functions and fulfill the requirement of a 'Thing'

		// Replace casts with an interface, yech
		virtual Object * asObj() { return 0; } 
		virtual Char * asChar() { return 0; }

		virtual void setRepop( Repop * ) = 0;
		virtual Repop * getRepop() { return 0; }

		virtual void out( const char * )  = 0;  // send a message to Thing
		virtual void out( const String & )  = 0; // send a message to Thing
	
		void  setShort( const String & );
		const String & getShort() const; 
		void  setLong( const String & );
		const String & getLong() const;
 
		Room *inRoom() { return in_room; }

		int getSize() { return size; }
		void setSize( int s ) { size = s; }
		int getWeight() { return weight; }
		void setWeight( int lbs ) { weight = lbs; }
		int getVol() { return volume; }
		void setVol( int v ) { volume = v; }
 
		// flags and affects
		virtual void addAffect( Affect * ) = 0; 
		virtual void rmAffect( int ) = 0; 
		virtual bool affected ( int bit ) { return IS_SET( aff_bits, bit ); }
};

#endif