#include <iostream>

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

#include "MidpointIntegrator_CCA.h"
#include "macros_CCA.h"

namespace integrators
{
  namespace ccaimpl
  {

    // MidpointIntegrator implementation

    MidpointIntegrator::MidpointIntegrator ()
    {
      function_m = 0;
    }

    MidpointIntegrator::~MidpointIntegrator ()
    {
    }

    double MidpointIntegrator::integrate (double lowBound, double upBound,
                                          int count)
    {
      gov::cca::Port * port;

      // Get Function port
      GETPORT (port, function_m, "FunctionPort",
               functions::ccaports::Function);

      double sum = 0.0;
      double h = (upBound - lowBound) / static_cast < double >(count);

      for (int i = 0; i < count; i++)
        {
          double x = lowBound + h * (i + 0.5);
          sum = sum + function_m->evaluate (x);
        }

      // Release ports
      RELEASE (function_m, "FunctionPort");

      return sum * h;
    }

    /**
     * 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 MidpointIntegrator::setServices (gov::cca::Services * services)
    {
      if (services != 0)
        {
          frameworkServices = services;

          // Provide an Integrator port
          PROVIDE (this, "IntegratorPort", "integrators.ccaports.Integrator");

          // Use a Function port
          REGISTER ("FunctionPort", "functions.ccaports.Function", 0);
        }
      else
        {
          // Close down if not closed already
          if (frameworkServices != 0)
            UNPROVIDE ("IntegratorPort");
          frameworkServices = 0;
        }
    }

  }
}