// __author__ = Juan Carlos De Abreu (jcabreur@gmail.com)
//
// This file provide some utilities functions to check types and number of
// parameters for a method or a function.

#ifndef SCENE_PARSER_CHECKS_H__
#define SCENE_PARSER_CHECKS_H__

BEGIN_TEG_NAMESPACE();

// Macro to check the number of parameters.
#define CHECK_PARAMETERS(nParamNeeded, nParamPassed) \
    checkNumberOfParameters(nParamNeeded, nParamPassed, __FUNCTION__)

// Macro to check the type of a parameter.
#define CHECK_TYPE(param, paramIndex, typeExpected) \
    checkParameterType(param, paramIndex, typeExpected, __FUNCTION__)

// Function to check the number of parameters.
//   The function return true if nParamNeeded == nParamPassed otherwise false.
inline bool checkNumberOfParameters(
    const int& nParamNeeded, const int& nParamPassed, const _TCHAR* function) {
  // Check if the number of parameters is the expected.
  if (nParamNeeded != nParamPassed) {
    PRINT_LOG(
        TYPE_ERROR,
        _T("Error: '%s' : function does not take %d arguments"),
        function,
        nParamPassed);
    return false;
  }
  return true;
}

// Function to check the type of a parameter.
//   The function return true if the the parameter is equal to the expected
//   otherwise false.
template<typename _T> inline bool checkParameterType(
    const SmartPointer<_T>& param,
    const int& paramIndex,
    const _TCHAR* typeExpected,
    const _TCHAR* function) {
  // Check if the parameter type is the expected.
  if (param == NULL) {
    PRINT_LOG(
        TYPE_ERROR,
        _T("Error: '%s' : cannot convert parameter %d to '%s'"),
        function,
        paramIndex,
        typeExpected);
	return false;
  }
  return true;
}

// Function to check if a method has the correct number of parameters.
//   The function return true if the methodNameExpected == methodNamePassed
//   otherwise return false.
inline bool checkMethodParameters(
    const int& nParamNeeded,
    const int& nParamPassed,
    const _TCHAR* className,
    const _TCHAR* methodNameExpected,
    const _TCHAR* methodNamePassed) {
  // Check if the methdo is the expected.
  if (strcmp(methodNameExpected, methodNamePassed) == 0) {
    // Check if the number of parameters is the expected.
    if (nParamNeeded == nParamPassed) return true;
    PRINT_LOG(
        TYPE_ERROR,
		_T("Error: '%s::%s' : function does not take %d arguments"),
        className,
		methodNamePassed,
        nParamPassed);
  }
  return false;
}

// Function to check the type of a parameter of a method.
//   The function return true if the the parameter is equal to the expected
//   otherwise return false.
template<typename _T> inline bool checkMethodParameterType(
    const SmartPointer<_T>& param,
    const int& paramIndex,
    const _TCHAR* typeExpected,
    const _TCHAR* className,
    const _TCHAR* methodName) {
  // Check if the parameter type is the expected.
  if (param == NULL) {
    PRINT_LOG(
        TYPE_ERROR,
		_T("Error: '%s::%s' : cannot convert parameter %d to '%s'"),
        className,
		methodName,
        paramIndex,
        typeExpected);
	return false;
  }
  return true;
}

END_TEG_NAMESPACE();

#endif  // SCENE_PARSER_CHECKS_H__
