/******************************************************************************
 *                                                                         
 *               (C) COPYRIGHT Pacific MindWorks, Inc. 2001-2005
 *                          All rights reserved.
 *
 *****************************************************************************/

#ifndef __NTLRANGECHECK_INCLUDED
#define __NTLRANGECHECK_INCLUDED

#include <atlcoll.h>

///////////////////////////////////////////////////////////////////////////////
//
//	CParameterValidationPolicy
//

class CParameterValidationPolicy
	: public CModelBasedType
{
public:
	CParameterValidationPolicy(const CString& strModel = _T("")) 
		: CModelBasedType(strModel) {}

	virtual bool Validate(double dVal) const = 0;
};

///////////////////////////////////////////////////////////////////////////////
//
//	CMinMaxParameterValidationPolicy
//

class CMinMaxParameterValidationPolicy
	: public CParameterValidationPolicy
{
public:
	CMinMaxParameterValidationPolicy(double dMin, double dMax, const CString& strModel = _T("")) 
		: m_dMin(dMin), m_dMax(dMax), CParameterValidationPolicy(strModel) {}

	virtual bool Validate(double dVal) const
	{
		return (dVal >= m_dMin) && (dVal <= m_dMax); 
	}

private:
	double m_dMin;
	double m_dMax;
};

///////////////////////////////////////////////////////////////////////////////
//
//	CNullParameterValidationPolicy
//

class CNullParameterValidationPolicy
	: public CParameterValidationPolicy
{
public:
	CNullParameterValidationPolicy(const CString& strModel = _T("")) 
		: CParameterValidationPolicy(strModel) {}

	virtual bool Validate(double dVal) const
	{
		NTL_UNUSED(dVal);

		return true;; 
	}
};

///////////////////////////////////////////////////////////////////////////////
//
//	CParameterValidator
//


class CParameterValidator 
{
public:
	CParameterValidator(CParameterValidationPolicy* pPolicy, ...);

	bool Validate(double dVal, const CString& strModel) const;

private:
	typedef CModelBasedMap<CParameterValidationPolicy> ValidationPolicyMap;			// key = model, value = ValidationPolicy
	ValidationPolicyMap m_mapPolicies;
};

inline CParameterValidator::CParameterValidator(CParameterValidationPolicy* pFirstPolicy, ...)
{
	va_list argPtr;
	va_start(argPtr, pFirstPolicy);

	m_mapPolicies.BuildMap(pFirstPolicy, argPtr);

	va_end(argPtr);
}

inline bool CParameterValidator::Validate(double dVal, const CString& strModel) const
{
	bool bValid = true;
	CParameterValidationPolicy* pPolicy = NULL;
	m_mapPolicies.Lookup(strModel, pPolicy);
	if (pPolicy == NULL)
	{
		// No model-specific policy provided, so use default policy
		m_mapPolicies.Lookup(_T(""), pPolicy);
	}

	if (pPolicy != NULL)
	{
		bValid = pPolicy->Validate(dVal); 
	}
	
	return bValid;
}


#endif // __NTLRANGECHECK_INCLUDED
