///////////////////////////////////////////////////////////////////////
//                                                                   //
// MTaskList                                                          //
//                                                                   //
// Collection of tasks which should be processed in the eventloop    //
//                                                                   //
///////////////////////////////////////////////////////////////////////

#include "MTaskList.h"

#include <iostream.h>

#include "MParList.h"
#include "MInputStreamID.h"

ClassImp(MTaskList)

MTaskList::MTaskList()
{
  // 
  //  default constructor: create empty task list
  //
}

MTaskList::MTaskList(MTaskList &ts)
{
  //
  //   CopyConstructor 
  //   creates a new TaskList and put the contents of an existing
  //   TaskList in the new TaskList. 
  //
  fTasks.AddAll(&ts.fTasks);
}

Bool_t MTaskList::AddToList(MTask *task, const char *tType, MTask *where)
{
  // schedule task for execution, whether as first task, or after
  // 'where'. 'tType' is the event type which should be processed
  if (!task)
    return kTRUE;
  
  // FIXME: We agreed to put the task into list in an ordered way.
  
  if (fTasks.FindObject(task))
    {
      printf("WARNING: MTaskList::schedule: Task already existing\n");
      return kTRUE;
    }
  
  if (where)
    {
      if (!fTasks.FindObject(where))
        {
	  printf("ERROR: MTaskList::schedule: Cannot find task after which the new task should be scheduled!\n");
	  return kFALSE;
        }
    }
  
  cout << "Adding " << task->GetName() << " to " << GetName() << " for " << tType << "... " << flush;
  
  task->SetEventType(tType);
  fTasks.Add(task);
  
  cout << "Done." << endl;
  
  return kTRUE;
}


Bool_t MTaskList::PreProcess( MParList *pList )
{ 
  //
  // do pre processing (before eventloop) of all tasks in the task-list
  //
  
  fID = (MInputStreamID*)pList->FindObject("MInputStreamID");
  if (!fID)
    {
      cout << "MTaskList::PreProcess - WARNING: MInputStreamID not found... creating." << endl;
      fID = new MInputStreamID;
      pList->AddToList(fID);
    }
  
  cout << "Preprocessing... " << flush;
  
  //
  //  create the Iterator over the tasklist
  //
  TIter next(&fTasks);
  
  MTask *task=NULL;
  
  //
  // loop over all tasks for preproccesing
  //
  while ( (task=(MTask*)next()) )
    {
      cout << task->GetName() << "... " << flush;
      
      if (!task->PreProcess( pList ))
	return kFALSE;
    }
  
  cout << endl;
  
  return kTRUE;
}

Bool_t MTaskList::Process()
{
  //
  // do the event execution of all tasks in the task-list
  //
  
  //
  //  create the Iterator for the TaskList
  //
  TIter next(&fTasks);
  MTask *task=NULL;
  
  //
  // loop over all tasks for processing 
  //
  while ( (task=(MTask*)next()) )
    {
      // cout << "MTaskList::Process() " << task->GetEventType() 
      //   << "  " << fID->GetEvtType() << endl ; 

      if (!strcmp(fID->GetEvtType(), task->GetEventType()) ||
          !strcmp(task->GetEventType(), "All"))
	{
          switch (task->Process())
	    {
	    case kTRUE:
              //
              // everything was OK: go on
              //
              continue;
	      
	    case kFALSE:
              //
              // an error occured: stop eventloop
              //
              return kFALSE;
	      
	    case kCONTINUE:
              //
              // something occured: skip the rest of the tasks for this event
              //
              break;
	    }
	}
    }
  return kTRUE;
}

Bool_t MTaskList::PostProcess()
{
  //
  // do post processing (before eventloop) of all tasks in the task-list
  //
  
  cout << "Postprocessing... " << flush;
  
  //
  //  create the Iterator for the TaskList
  //
  TIter next(&fTasks);
  
  MTask *task=NULL;
  
  //
  //  loop over all tasks for postprocessing
  //  
  while ( (task=(MTask*)next()) )
    {
      cout << task->GetName() << "... " << flush;
      
      if (!task->PostProcess())
	return kFALSE;
    }
  
  cout << endl;
  
  return kTRUE;
}


void MTaskList::Print(Option_t *t)
{
  cout << "TaskList: " << this->GetName() << " <" <<  this->GetTitle() << ">" 
       << endl;
  
  fTasks.Print();
  
  cout << endl;
}




