/////////////////////////////////////////////////////////////////////////////
//                                                                         //
// MParList                                                                //
//                                                                         //
// This class contains a list of different parameter containers.           //
//                                                                         //
// A parameter container is an object which is derived from                //
// MParContainer.                                                          //
//                                                                         //
// Normally a parameter container is used for data exchange between two    //
// tasks at runtime.                                                       //
//                                                                         //
// You can add every parameter container (Named object) to the             //
// instance and access it from somewhere else via its Name.                //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
#include "MParList.h"

#include <TNamed.h>
#include <TClass.h>

#include "MLog.h"

ClassImp(MParList)

MParList::MParList(const char *name, const char *title)
{
    //
    //  default constructor
    //  creates an empty list
    //
    *fName  = name  ? name  : "MParList";
    *fTitle = title ? title : "List of Parameter Containers";
}

MParList::MParList(MParList &ts)
{
    //
    // copy constructor
    //

    fContainer.AddAll(&ts.fContainer);
}

void MParList::SetLogStream(MLog *log)
{
    //
    //  create the Iterator over the tasklist
    //
    TIter Next(&fContainer);

    MParContainer *cont=NULL;

    //
    // loop over all tasks for preproccesing
    //
    while ( (cont=(MParContainer*)Next()) )
        cont->SetLogStream(log);

    MParContainer::SetLogStream(log);
}

Bool_t MParList::AddToList(MParContainer *obj, MParContainer *where)
{
  // 
  //  Add an Container to the list.
  // 
  //  If 'where' is given, the object will be added after this.
  //
  
  //
  //  check if the object (you want to add) exists
  //

  if (!obj) return kTRUE;

  *fLog << "Adding " << obj->GetName() << " to " << GetName() << "... " << flush;
  //
  //  check if it is in the list yet
  //
  if (fContainer.FindObject(obj))
  {
      *fLog << "WARNING: MParList::add: Container already added" << endl;
      return kTRUE;
  }

  //
  //  check if you want to add the new parameter container somewhere 
  //  special (in that case you specify "where") 
  //  
  if (where)
  {
      if (!fContainer.FindObject(where))
      {
          *fLog << "ERROR: MParList::add: Cannot find parameter container after which the new one should be added!" << endl;
          return kFALSE;
      }
  }

  fContainer.Add(obj);
  *fLog << "Done." << endl;

  return kTRUE;
}

TObject *MParList::FindObject(const char *name) const
{
    //
    //  Find an object in the list.
    //  'name' is the name of the object you are searching for.
    //
    return (TObject*)fContainer.FindObject(name);
}

MParContainer *MParList::FindCreateObj(const char *name)
{
    //
    //  Find an object in the list.
    //  'name' is the name of the object you are searching for.
    //  If the object doesn't exist we try to create one from the
    //  dictionary. If this isn't possible NULL is returned
    //
    MParContainer *pcont = (MParContainer*)FindObject(name);

    if (pcont)
        return pcont;

    //
    // if object is not existing in the list try to create one
    //
    *fLog << "MParList::CreateObject - Warning: '" << name << "' not found... creating." << endl;

    //
    // try to get class from root environment
    //
    TClass *cls = gROOT->GetClass(name);

    if (!cls)
    {
        //
        // if class is not existing in the root environment
        //
        *fLog << "MParList::CreateObject - Warning: Class '" << name << "' not existing in dictionary." << endl;
        return NULL;
    }

    //
    // create the container and add it to the list
    //
    pcont = (MParContainer*)cls->New();
    AddToList(pcont);

    //
    //  Find an object in the list.
    //  'name' is the name of the object you are searching for.
    //
    return pcont;
}

void MParList::Print(Option_t *t)
{
  //
  //   print some information about the current status of MParList
  //
  *fLog << "ParList: " << this->GetName() << " <" << this->GetTitle() << ">" << endl;
  *fLog << endl;
  
}

