int mitk::PointSetDataInteractor::GetPointIndexByPosition(Point3D position, unsigned int time, float accuracy)
{
  // iterate over point set and check if it contains a point close enough to the pointer to be selected
  PointSet* points = dynamic_cast<PointSet*>(GetDataNode()->GetData());
  int index = -1;
  if (points == NULL)
  {
    return index;
  }


  if (points->GetPointSet(time) == nullptr)
    return -1;

  PointSet::PointsContainer* pointsContainer = points->GetPointSet(time)->GetPoints();

  float minDistance = m_SelectionAccuracy;
  if (accuracy != -1 )
    minDistance = accuracy;


  for (PointSet::PointsIterator it = pointsContainer->Begin(); it != pointsContainer->End(); it++)
  {
    float distance = sqrt(position.SquaredEuclideanDistanceTo(points->GetPoint(it->Index(), time)));
    if (distance < minDistance) // if several points fall within the margin, choose the one with minimal distance to position
    {
      index = it->Index();
    }
  }
  return index;
}
bool mitk::PointSetDataInteractor::MoveSet(StateMachineAction*, InteractionEvent* interactionEvent)
{
  InteractionPositionEvent* positionEvent = dynamic_cast<InteractionPositionEvent*>(interactionEvent);
  if (positionEvent != NULL)
  {
    int timeStep = positionEvent->GetSender()->GetTimeStep();
    // Vector that represents movement relative to last position
    Point3D movementVector;
    movementVector[0] = positionEvent->GetPositionInWorld()[0] - m_PointSet->GetPoint(m_SelectedPointIndex, timeStep)[0];
    movementVector[1] = positionEvent->GetPositionInWorld()[1] - m_PointSet->GetPoint(m_SelectedPointIndex, timeStep)[1];
    movementVector[2] = positionEvent->GetPositionInWorld()[2] - m_PointSet->GetPoint(m_SelectedPointIndex, timeStep)[2];

    PointSet* points = dynamic_cast<PointSet*>(GetDataNode()->GetData());
    PointSet::PointsContainer* pointsContainer = points->GetPointSet(timeStep)->GetPoints();

    // Iterate over point set and update each point
    Point3D newPoint;
    for (PointSet::PointsIterator it = pointsContainer->Begin(); it != pointsContainer->End(); it++)
    {
      newPoint[0] = m_PointSet->GetPoint(it->Index(), timeStep)[0] + movementVector[0];
      newPoint[1] = m_PointSet->GetPoint(it->Index(), timeStep)[1] + movementVector[1];
      newPoint[2] = m_PointSet->GetPoint(it->Index(), timeStep)[2] + movementVector[2];
      m_PointSet->SetPoint(it->Index(), newPoint, timeStep);
    }

    GetDataNode()->SetData(m_PointSet);
    GetDataNode()->Modified();
    mitk::RenderingManager::GetInstance()->RequestUpdateAll();
    return true;
  }
  else
  {
    return false;
  }
}
bool mitk::PointSetDataInteractor::AddPoint(StateMachineAction* stateMachineAction, InteractionEvent* interactionEvent)
{
  // Find the position, the point is to be added to: first entry with
  // empty index. If the Set is empty, then start with 0. if not empty,
  // then take the first index which is not occupied
  int lastPosition = 0;
  PointSet::PointsContainer* pointsContainer = m_PointSet->GetPointSet(0)->GetPoints();

  if (!pointsContainer->empty())
  {
    mitk::PointSet::PointsIterator it, end;
    it = pointsContainer->Begin();
    end = pointsContainer->End();
    while (it != end)
    {
      if (!pointsContainer->IndexExists(lastPosition))
        break;
      ++it;
      ++lastPosition;
    }
  }

  InteractionPositionEvent* positionEvent = dynamic_cast<InteractionPositionEvent*>(interactionEvent);
  if (positionEvent != NULL)
  {
    IsClosedContour(stateMachineAction, interactionEvent);
    // Get time step from BaseRenderer
    int timeStep = positionEvent->GetSender()->GetTimeStep();
    mitk::Point3D point = positionEvent->GetPositionInWorld();
    m_PointSet->InsertPoint(lastPosition, point, timeStep);
    m_NumberOfPoints++;
    GetDataNode()->SetData(m_PointSet);
    GetDataNode()->Modified();
    if (m_MaxNumberOfPoints != 0 && m_NumberOfPoints >= m_MaxNumberOfPoints)
    {
      InternalEvent::Pointer event = InternalEvent::New(NULL, this, "MaxNumberOfPoints");
      positionEvent->GetSender()->GetDispatcher()->QueueEvent(event.GetPointer());
    }
    mitk::RenderingManager::GetInstance()->RequestUpdateAll();
    return true;
  }
  else
  {
    return false;
  }
}
int mitk::PointSetDataInteractor::GetPointIndexByPosition(Point3D position, int time)
{

  // iterate over point set and check if it contains a point close enough to the pointer to be selected
  PointSet* points = dynamic_cast<PointSet*>(GetDataNode()->GetData());
  int index = -1;
  if (points == NULL)
  {
    return index;
  }
  PointSet::PointsContainer* pointsContainer = points->GetPointSet(time)->GetPoints();

  float minDistance = m_SelectionAccuracy;
  for (PointSet::PointsIterator it = pointsContainer->Begin(); it != pointsContainer->End(); it++)
  {
    float distance = sqrt(position.SquaredEuclideanDistanceTo(points->GetPoint(it->Index(), time)));  // TODO: support time!
    if (distance < minDistance) // if several points fall within the margin, choose the one with minimal distance to position
    { // TODO: does this make sense, which unit is it?
      index = it->Index();
    }
  }
  return index;
}