#ifndef _COMMON_CALLBACK_HPP_
#define _COMMON_CALLBACK_HPP_
#ifndef _COMMON_CALLBACKDATA_HPP_
#include <common/cbdata.hpp>
#endif
#ifndef _COMMON_PURECALLBACK_HPP_
#include <common/pcallbck.hpp>
#endif
#ifndef _COMMON_CALLBACKPOINTER_HPP_
#include <common/cbptr.hpp>
#endif

#if defined(_MSC_VER)
#pragma warning(disable:4355)
#endif

template <class T>
class Callback : public PureCallback
{
public:
  typedef CallbackData::ReturnType (T::*PFNMETHOD)(CallbackData &callbackData);
	Callback(void);
	Callback(const Callback<T> &someCallback);
	Callback(T *lpObject,PFNMETHOD lpMethod);
	virtual ~Callback();
	void setObject(T *lpObject);
	void setMethod(PFNMETHOD lpMethod);
	void setCallback(T *lpObject,PFNMETHOD lpMethod);
	WORD operator==(const Callback<T> &someCallback)const;
	void operator=(const Callback<T> &someCallback);
	CallbackData::ReturnType operator*(CallbackData &someCallbackData);
private:
	T *mlpObject;
	CallbackData::ReturnType (T::*mlpMethod)(CallbackData &someCallbackData);
};

#ifndef _MSC_VER
template <class T>
inline
CallbackData::ReturnType Callback<T>::operator*(CallbackData &someCallbackData)
{
	if((!mlpObject)||(!mlpMethod))return (CallbackData::ReturnType)0;
	return (mlpObject->*mlpMethod)(someCallbackData);
}
#else	 // the rocket scientists at microsoft have problems compiling the preceeding, must do the following...
template <class T>
inline
CallbackData::ReturnType Callback<T>::operator*(CallbackData &someCallbackData)
{
  CallbackData::ReturnType (T::*lpMethod)(CallbackData &someCallbackData)=0;
	if((lpMethod==mlpMethod)||!mlpObject)return (CallbackData::ReturnType)0;
	return (mlpObject->*mlpMethod)(someCallbackData);
}
#endif
#if defined(_MSC_VER)  // the rocket scientists at microsoft have trouble expanding templates
#include <common/callback.tpp>
#endif
#endif
