#include <config.h>
#include <graph/AggNode.h>

#include <vector>
#include <stdexcept>

using std::vector;
using std::set;

AggNode::AggNode(Index const &dim, vector<Node *> nodes, 
		 vector<unsigned long> offsets)
  : DeterministicNode(dim)
{
  unsigned long length = data.length();
  /* Check argument lengths */
  if (length != nodes.size() || length != offsets.size()) {
    throw std::length_error ("Length mismatch in Aggregate Node constructor");
  }

  /* Check that offsets are valid */
  for (unsigned long i = 0; i < length; i++) {
    if (offsets[i] >= nodes[i]->data.length())
      throw std::out_of_range("Invalid offset in Aggregate Node constructor");
  }

  /* See if node is discrete-valued */
  bool isinteger = true;
  for (unsigned long i = 0; i < length; i++) {
    if (!nodes[i]->data.isDiscreteValued()) {
      isinteger = false;
      break;
    }
  }
  data.setDiscreteValued(isinteger);
  
  _value_pointers = new double const *[length];
  for (unsigned long i = 0; i < length; i++) {
    this->addParent(nodes[i]);
    _value_pointers[i] = nodes[i]->data.value() + offsets[i];
  }
}

AggNode::~AggNode()
{
  delete [] _value_pointers;
}

void AggNode::forwardSample()
{
  long length = data.length();
  double *value = new double[length];
  for (long i = 0; i < length; i++) {
    value[i] = *_value_pointers[i];
  }
  data.setValue(value, length);
  delete [] value;
}

AggNode *asAggregate(Node *node)
{
  return dynamic_cast<AggNode*>(node);
}

bool isAggregate(Node const *node)
{
  return dynamic_cast<AggNode const*>(node);
}


syntax highlighted by Code2HTML, v. 0.9.1