#include "fdmCoProcessing.h"

#include "fdmCellGrid.h"
#include "fdmTimeInfo.h"

#include "vtkCPDataDescription.h"
#include "vtkCPInputDataDescription.h"
#include "vtkCPProcessor.h"
#include "vtkCPPythonScriptPipeline.h"

#include "vtkXMLDataElement.h"

fdmCoProcessing *fdmCoProcessing::New(fdmTimeInfo *tInfo,
    vtkXMLDataElement *element)
{
  fdmCoProcessing *coproc = new fdmCoProcessing(tInfo);
  if(coproc->Parse(element))
    {
    return coproc;
    }
  coproc->Delete();
  return 0;
}

fdmCoProcessing::fdmCoProcessing(fdmTimeInfo *tInfo)
  : fdmTimestepObject(tInfo)
{
  this->Processor = vtkCPProcessor::New();
}

fdmCoProcessing::~fdmCoProcessing()
{
  this->Processor->Finalize();
  this->Processor->Delete();
}

int fdmCoProcessing::Parse(vtkXMLDataElement *coproc)
{
  if(!this->Processor->Initialize())
    {
    return 0;
    }

  vtkXMLDataElement *source = coproc->FindNestedElementWithName("Source");
  if (!source)
    {
    return 0;
    }

  vtkCPPythonScriptPipeline *pipe = vtkCPPythonScriptPipeline::New();
  if(!pipe->Initialize(source->GetCharacterData()))
    {
    return 0;
    }
  this->Processor->AddPipeline(pipe);
  pipe->Delete();

  return 1;
}

// deadcopy from
// ParaView/CoProcessing/CoProcessor/Testing/TestDriver/vtkCPTestDriver.cxx
void fdmCoProcessing::Exec()
{
  vtkCPDataDescription *dataDescription = vtkCPDataDescription::New();
  dataDescription->SetTimeData(this->TimeInfo->GetTimeValue(),
      this->TimeInfo->GetTIter());
  dataDescription->AddInput("input");
  if(this->Processor->RequestDataDescription(dataDescription))
    {
    dataDescription->GetInputDescriptionByName("input")->SetGrid(
        this->TimeInfo->GetGrid());
    // now call the coprocessing library
    this->Processor->CoProcess(dataDescription);
    }
  dataDescription->Delete();
}
