#include <stdio.h>
#include <stdlib.h>
#include <iostream>

#include "cca.h"
#include "stdPorts.h"

#include "ports/Function_CCA.h"
#include "ports/Integrator_CCA.h"

#include "Driver_CCA.h"
#include "macros_CCA.h"

using namespace
  functions::ccaports;
using
  namespace
  integrators::ccaports;

Driver::Driver ()
{
  frameworkServices = 0;
}

Driver::~Driver ()
{
}

int
Driver::go ()
{
  double value;
  int count = 100;
  double lowerBound = 0.0, upperBound = 1.0;

  // Ports
  gov::cca::Port * port;
  Function *function;
  Integrator *integrator;

  port = frameworkServices->getPort ("IntegratorPort");
  if (port)
    integrator = dynamic_cast < Integrator * >(port);
  if (integrator == 0)
    {
      cerr << "Connected to something other than an Integrator_CCA port";
      return -1;
    }

  value = integrator->integrate (lowerBound, upperBound, count);

  cout << "integral = " << value << endl;

  // Release ports
  frameworkServices->releasePort ("IntegratorPort");
  return 0;

}

/**
 * The framework passes a pointer to the Services object
 * via this method, which is called by the framework as soon
 * as the component is instantiated.
 */
void
Driver::setServices (gov::cca::Services * services)
{
  if (services != 0)
    {
      frameworkServices = services;

      // Provide a Go port
      gov::cca::PortInfo * portInfo =
        frameworkServices->createPortInfo ("Go", "gov.cca.GoPort", 0);
      if (portInfo != 0)
        frameworkServices->addProvidesPort (this, portInfo);

      // Use an Integrator port
      portInfo =
        frameworkServices->createPortInfo ("IntegratorPort",
                                           "integrators.ccaimpl.Integrator",
                                           0);
      frameworkServices->registerUsesPort (portInfo);
    }
  else
    {
      // Close down if not closed already
      if (frameworkServices != 0)
        frameworkServices->removeProvidesPort ("Go");
      frameworkServices = 0;
    }
}

//#define DRIVER_ALIAS "Driver"
//CCAFFEINE_WRAPPER(create_Driver, Driver, Driver) // Needed for dynamic loading