// Author : Chris Tolley
// Date   : 8/2/2004
// SmartPointer.h contains the class declaration for a class of smart pointers
// that will delete the dynamic memory stored inside them and know when an object
// that they point to has been deleted

#if !defined(AFX_SMARTPOINTER_H__AA02590A_FD6B_4DD5_A649_27B787384FF5__INCLUDED_)
#define AFX_SMARTPOINTER_H__AA02590A_FD6B_4DD5_A649_27B787384FF5__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "Object.h"

class SmartPointer  
{
public:
	// Constructor
	SmartPointer();

	// Constructor.  newObject must be declared with new
	SmartPointer( Object* newObject );

	// Copy Constructor
	SmartPointer( const SmartPointer& rhs );

	// Destructor
	virtual ~SmartPointer();

	// Operator equals
	SmartPointer& operator = ( const SmartPointer& rhs );

	// Returns the object inside this SmartPointer
	inline Object* Get() { return m_Target; };

	// Deletes Target
//	inline void Delete() { delete m_Target; *m_bValid = false; };
	void Delete();

	// Returns true if the data is valid
	inline bool isValid() const { return ( m_bValid != NULL ) && *m_bValid; };

	// The deference operator
	inline Object& operator*() { return *m_Target; };

	// The arrow operator
	inline Object* operator->() const { return m_Target; };

	// Returns true if the stored objects are equal
	inline bool operator== ( SmartPointer& rhs ) const
	{ return *m_Target == *rhs.m_Target; };

	// Returns true if the stored objects are not equal
	inline bool operator != ( SmartPointer& rhs ) const
	{ return *m_Target != *rhs.m_Target; };
private:
	// The thing this pointer is pointing to
	Object* m_Target;

	// A pointer to a number that keeps track of how many things are pointing
	// to Target
	int* m_iRefCount;

	// A pointer to a bool which is true until Target is deleted
	bool* m_bValid;

	// A bool for debug
	bool m_bThisValid;

	// The id of this smartpointer
	unsigned int m_uiId;

	// The id generator
	static unsigned int m_uiIdGenerator;
};

#endif // !defined(AFX_SMARTPOINTER_H__AA02590A_FD6B_4DD5_A649_27B787384FF5__INCLUDED_)
