// ------------------------------------------------------------------------
/*
	author: Jaap Suter
   
	Copyright (C) Electronic Arts Canada Inc. 2002.  All rights reserved.	
*/
// ------------------------------------------------------------------------

/*! \file */

#ifndef REVEAL_SINGLETON_H
#define REVEAL_SINGLETON_H

#include <assert.h>
#include "reveal/tweaker.h"

namespace Reveal {

// ------------------------------------------------------------------------------
/*!
	\brief Singleton wrapper for the tweaker system;

	\warning See http://c2.com/cgi/wiki?SingletonsAreEvil for an interesting discussion
			 about the drawbacks of singletons. I don't like them in C++, because it is 
			 impossible to control life-time issues. This singleton checkes life-time issues
			 and asserts on problems (the dead-reference idiom used in Modern C++ Design), but
			 if it is at all possible, try to avoid this singleton, and use the tweaker 
			 directly (make it a member of your global application class for example).

	\warning	Then why do I provide a singleton? Because it is the least ugly way to provide the
				current FIFA sourcebase access to the tweaker. The only other option is using a global. Basically
				this singleton is a global, but at least it's all encapsulated and defined in one place;

	\note		Why is it called Singleton? Because it's in the Reveal namespace, and I think the Reveal::Singleton makes sense.
				It's maybe not the best naming convention, but in that case consider it a reason no to use the singleton :) hehe.
*/
// ------------------------------------------------------------------------------
class Singleton : public Tweaker
{
public:

	/*!
		\brief	To get the singleton instance;
		\return Returns a reference to the single tweaker instance;

		\warning Behaviour of calling this method once main() has exited his 
				 undefined. Some problems will be caught using an assertion, but it
				 is best to not call this method in any code that might be called
				 after main() (e.g. destructors of static objects);
	*/
    static Singleton& Instance();

	//! Returns true when the singleton is killed;
	static bool Dead() { return mDeadReference; }

	~Singleton() { mDeadReference = true; }    
    
private:

	//! Private default constructor;
	Singleton() : Tweaker() { mDeadReference = false; }

	Singleton( const Singleton& );				//!< Not implemented;
    Singleton& operator = ( const Singleton& ); //!< Not implemented;

    static bool mDeadReference;	//!< Provides a way of checking life-time issues;
};

} // Namespace Reveal;

#endif
