// Author: Juan Carlos De Abreu (jcabreur@gmail.com)

#include "DataCallFunction.h"
#include "../SceneFile.h"

BEGIN_TEG_NAMESPACE();

SmartPointer<IData> DataCallFunction::resolve(std::map<std::string, SmartPointer<IData>>& variables) {
  // Resolve all the expresions int the parameters and call the function with the values of the response ...
  std::vector<SmartPointer<IData>> params;
  const int nParams = static_cast<int> (param.size());
  if (name != _T("Timer") && name != _T("setKeyFunc") && name != _T("SetRasterButtonFunc")) {
    for (int i = 0; i < nParams; ++i)
      params.push_back(param[i]->resolve(variables));
  }

  if (name == _T("Timer")) {
    if (nParams != 4) return NULL;
    params.push_back(param[0]->resolve(variables));
    params.push_back(param[1]->resolve(variables));
    params.push_back(param[2]);
    params.push_back(param[3]);
  }

  // Chec if the function exist in least one file..
  const int nFiles = SceneFileManagement::GetInstance().sceneFiles.size();
  const std::pair<std::string, int> p(name, nParams);
  std::list<SceneFile>::iterator it = SceneFileManagement::GetInstance().sceneFiles.begin();
  std::list<SceneFile>::iterator end = SceneFileManagement::GetInstance().sceneFiles.end();
  for (int i = 0; i < nFiles; ++i, ++it) {
    if (it->functions.find(p) != it->functions.end()) {
      SmartPointer<Function> function = it->functions[p];
      const SmartPointer<IData> tmp = function->call(params);
      return tmp;
    }
  }
	
  if (SceneFileManagement::GetInstance().DATAfunctions.find(name) != SceneFileManagement::GetInstance().DATAfunctions.end()) {
    if (name == _T("setKeyFunc")) {
      const SmartPointer<IData> tmp = SceneFileManagement::GetInstance().DATAfunctions[name].call(param);
      return tmp; 
    }

    const SmartPointer<IData> tmp = SceneFileManagement::GetInstance().DATAfunctions[name].call(params);
    return tmp;
  }

  // Report in the log that the funcion is not defined ... and abort the application
  PRINT_LOG(TYPE_ERROR, "error: Function \'%s\'is not defined", name.c_str());
  return NULL;
}

END_TEG_NAMESPACE();
