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

#include "ModelManagement.h"
#include "../Util/Funcs.h"
#include "ModelObj.h"
#include "../base/LogManagement.h"

BEGIN_TEG_NAMESPACE();

ModelManagement::ModelManagement() {}

ModelManagement::~ModelManagement() {
	release();
}

void ModelManagement::release() {	
  // Delete the display list of each model
  std::map<std::tstring, SmartPointer<IModel>>::iterator it = models_.begin();
  std::map<std::tstring, SmartPointer<IModel>>::iterator end = models_.end();

  for (; it != end; ++it) {	
    // Delete the new dl
    const int kNumberOfGroups = static_cast<int>(it->second->groupList.size());
    for (int i = 0; i < kNumberOfGroups; ++i) {
      const int kNumberOfDisplayLists = static_cast<int>(it->second->groupList[i].dl.size());
      for (int j = 0; j < kNumberOfDisplayLists; ++j) {
        glDeleteLists(it->second->groupList[i].dl[j], 1);
      }
    }

    // 
    glDeleteLists(it->second->pointDL, 1);
    glDeleteLists(it->second->gridDL, 1);
    glDeleteLists(it->second->boundingBoxDL, 1);

    // Delete the AABBTree of each model
    it->second->bb.Release();
  }
  models_.clear();
}


// Method to load a model
SmartPointer<IModel> ModelManagement::load(const _TCHAR *lpszPathName) {
  // Check if the model not was loaded previus
  if (models_.find(lpszPathName) != models_.end()) {
    // Return the reference to the model loaded
    return models_[lpszPathName];
  }

  // Create the a new model of the extension type
  SmartPointer<IModel> tmpModel;

  // Check extension of the file to know ...
  const std::tstring ext = GetExt(lpszPathName);
  if (ext == _T("obj")) {
    tmpModel = new ModelObj(lpszPathName);
  } else {
    PRINT_LOG(TYPE_WARNING, "The format %s is not supported by the application", ext.c_str());
	return NULL;
  }
	
  // Construct the path for the aabb of the model.
  const std::tstring aabbPath = GetAPathFromOne(lpszPathName, _T("tmp/") + GetBaseFileName(lpszPathName) + _T(".aabb"));
  // Try to load the aabb file related to this model.
  if (!tmpModel->bb.Load(aabbPath)) {
    tmpModel->bb.Init(tmpModel->groupList);
    tmpModel->bb.Save(aabbPath);
  }

  // Save the new model
  models_.insert(std::pair<std::tstring, SmartPointer<IModel>> (lpszPathName, tmpModel));

  // Return the reference to the model loaded
  return models_[lpszPathName];
}

END_TEG_NAMESPACE();
