require 'drb'

module RubyMud

class BaseObject

	include DRbUndumped

	attr_accessor :name,:parent,:container,:description,:longDescription

	@@classes = []
	
	def BaseObject.addClass(someclass)
		@@classes.push(someclass)
	end	
	
	def BaseObject.removeClass(someclass)
		@@classes.delete(someclass)
	end	

	def BaseObject.getClasses
		@@classes
	end	

	def initialize(parent,name,description)
		@parent = parent
		@name = name
		@description = description
		@longDescription = ""
		@flags = []		
		@effects = []
		@stats = []
		@container = []
		@num = $autoNumber.get()
		
		# Add the item to it's parent
		@parent.container.push(self) if @parent != nil
		
		# Check the method for more info
		onLoad()
	end

	# This will take a hell of a long time
	# How do other muds handle getting global 
	# objects ? hashtables ? a sorted array ?
	# It just feels wrong to duplicate this
	# data ... maybe the build in ruby id should be used ?
	def BaseObject.findObject(num)
		ObjectSpace.each_object do |object|
			if (object.is_a?(BaseObject))
				return object if object.num == num
			end
		end
		return nil
	end	
	
	# This is called when the state is loaded
	# after serialization.
	# Use it for setting up things that doesnt
	# serialize with the state, eg.Ticking info
	# NOTE: This is called automatically by 
	# your subclass when you call super in the
	# intialize methods
	def onLoad()		
	end	
	
	# ##########
	# Properties
	# ##########

	# a unique number for this object, calculated in the constructor
	def num
		@num
	end	
	
	# Should only be used for debugging
	# use the class methods to add/remove
	def Effects
		@effects
	end
	
	
	# #####
	# Flags
	# #####	

	def flags
		@flags
	end	

	
	def removeFlagByClassName(flagClassName)
		for f in @flags
			if (f.class.name == flagClassName)
				f.beforeRemove()
				@flags.delete(f)
				return true
			end
		end
		return false
	end	
	
	# Remove a flag instance from the object's 
	# flag list
	def removeFlag(flag)
		# The flag might not be on the object
		# we need to check before calling the 
		# BeforeRemove() method
		
		for f in @flags
			if f == flag
				f.beforeRemove()
				@flags.delete(f)
				break
			end
		end	
	end		
	
	def getFlagByClass(flagClass)	
		for f in @flags
			return f if (f.class == flagClass)
		end
		return nil
	end	
	
	def getFlagByClassName(flagClassName)	
		for f in @flags
			return f if (f.class.name == flagClassName)
		end
		return nil
	end		
	
	def addFlag(flag)
	
		# If there cant be more than one check if its already here
		if (!flag.class.moreThanOne?)		
			for f in @flags
				if (f.class.name == flag.class.name)
					return
				end
			end		
		end
		
		# It isnt, so add it
		@flags.push(flag)
	end		
	
	def clearAllFlags()
		@flags = []
	end
	
	# #########
	# Stats
	# #########	

	def stats
		@stats
	end	
	
	def addStat(stat)
		@stats.push(stat)
	end	
	
	def removeStat(stat)
		return @stats.delete(stat)
	end
	
	def getStat(name)
		for i in @stats
			if (i.name == name)
				return i
			end
		end
		return nil
	end
	
	def getStatByClass(statClass)
		for i in @stats
			if (i.class == statClass)
				return i
			end
		end
		return nil
	end	
	
	# #######
	# Effects
	# #######	
	
	def removeEffect(effect)	
		for e in @effects
			if (e == effect)
				e.removing()
				@effects.delete(e)
				return true
			end
		end
		return false
	end		
	
	def getEffect(name)
		for e in @effects
			if (e.name == name)
				return e
			end
		end
		return nil
	end	
	
	# #########
	# Container
	# #########	
	
	def getObjectByName(objectName)	
		for i in @container
			if (i.name.downcase == objectName.downcase)
				return i
			end
		end
		return nil
	end		

	def removeItem(item)
		for i in @container
			if (i == item)
				@container.delete(i)
				return i
			end
		end
		return nil
	end		
	
end

end