///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// Copyright (C) 2006 by Intel Coproration and Carnegie Mellon University    //
// Contacts: casey.j.helfrich @ intel.com                                    //
//           bdr @ cs.cmu.edu                                                //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////


#ifndef __CODEMODULELIST_HXX
#define __CODEMODULELIST_HXX

/*

DON'T DO THIS ANY MORE!!!!

#include "Hierarchy.hxx"
#include "TestMessaging.hxx"
#include "TestAggregation.hxx"
//#include "XYMelt.hxx"
#include "Flicker.hxx"
#include "RemoteFeatureTest.hxx"
//#include "Sculpture.hxx"
#include "Life.hxx"
#include "Color.hxx"
#include "HexRotate.hxx"
#include "Ellipsis.hxx"
#include "BoundingBox.hxx"

// When you create a NEW Code Module, add a new #include here.
// NO DON'T!!!!!
*/

#include "CodeModule.hxx"

void CatomSim::loadCodeModules(string module_list) {
  
  // Tokenize the code_module list
  vector<string> moduleTokens;
  const string delimiter = ",";
  unsigned int lastpos = module_list.find_first_not_of(delimiter, 0);
  unsigned int pos = module_list.find_first_of(delimiter, lastpos);
  
  while((pos != string::npos || lastpos != string::npos) && (pos != lastpos)) {
    moduleTokens.push_back(module_list.substr(lastpos, pos-lastpos));
    lastpos = module_list.find_first_not_of(delimiter, pos);
    pos = module_list.find_first_of(delimiter, lastpos);
  }

  // moduleTokens now contains a list of all Code Modules to be loaded

  if(moduleTokens.size() < 1) {
    cerr << "Module List appears invalid..." << endl;
    exit(1);
  }

  bool first_time = false;
  bool failure = false;
  int i = 0;

  if ( CODE_MODULE_DECLARATIONS::module_id_remap == 0 ) {
    first_time = true;
    CODE_MODULE_DECLARATIONS::module_id_remap = 
      new int[ CodeModuleID::max_value + 1 ];
    int k;
    for ( k =0; k<=CodeModuleID::max_value; k++ )
      CODE_MODULE_DECLARATIONS::module_id_remap[ k ] = -1;  // force errors
  }

  vector<string>::iterator currentModule = moduleTokens.begin();
  while(currentModule != moduleTokens.end()) {
/*
   DON'T DO THIS ANY MORE !!!
    if(*currentModule == "Hierarchy")
      codeModules.push_back(new Hierarchy(C.getID(),"TestHierarchyBase"));
    else if(*currentModule == "TestMessaging")
      codeModules.push_back(new TestMessaging(C.getID()));
    else if(*currentModule == "TestAggregation")
      codeModules.push_back(new TestAggregation(C.getID()));
    else if(*currentModule == "Flicker")
      codeModules.push_back(new Flicker(C.getID()));
//    else if(*currentModule == "XYMelt")
//      codeModules.push_back(new XYMelt(C.getID()));
    else if(*currentModule == "RemoteFeatureTest")
      codeModules.push_back(new RemoteFeatureTest(C.getID()));
//    else if(*currentModule == "Sculpture")
//      codeModules.push_back(new Sculpture(C.getID()));
    else if(*currentModule == "Life")
      codeModules.push_back(new Life(C.getID()));
    else if(*currentModule == "COLOR")
      codeModules.push_back(new ColorModule(C.getID()));
    else if(*currentModule == "HexRotate")
      codeModules.push_back(new HexRotate(C.getID()));
    else if(*currentModule == "Ellipsis")
      codeModules.push_back(new Ellipsis(C.getID()));
    else if(*currentModule == "BoundingBox")
      codeModules.push_back(new BoundingBoxModule(C.getID()));

    // When you create a NEW Code Module, add another "else if" here.
    // NO DON'T
*/

    int k;
    CodeModule* cm = 
      CodeModuleListEntry::getModuleByName( *currentModule, C.getID(), &k );

    if ( cm ) {
      codeModules.push_back( cm );
      if (first_time) {
        CODE_MODULE_DECLARATIONS::module_id_remap[ k ] = i++;
        std::cout << "Loaded Code Module: " << *currentModule << std::endl;
      }
    }
    else
    {
      cerr << "Invalid Code Module: " << *currentModule << endl;
      failure = 1;
    }
    currentModule++;
  }
  
  if ( failure ) {
    cerr << "\n It appears that you have specified a CodeModule"
      << "\n that does not exist in this version of the simulator."
      << "\n Please check the README file for details on adding modules." 
      << endl;
    exit(1);
  }
}

#endif /* __CODEMODULELIST_HXX */
