/////////////////////////////////////////////////////////////
//                                                         //
// Copyright (c) 2007-2017 by The University of Queensland //
// Centre for Geoscience Computing                         //
// http://earth.uq.edu.au/centre-geoscience-computing      //
//                                                         //
// Primary Business: Brisbane, Queensland, Australia       //
// Licensed under the Open Software License version 3.0    //
// http://www.apache.org/licenses/LICENSE-2.0              //
//                                                         //
/////////////////////////////////////////////////////////////

#include "ClippedSphereVol.h"

using std::make_pair;

ClippedSphereVol::ClippedSphereVol()
{}

/*!
  constructor taking center and radius of the Sphere as arguments

  \param center the center of the sphere
  \param radius the radius of the sphere
*/
ClippedSphereVol::ClippedSphereVol(const Vector3& center,double radius):
  SphereVol(center,radius)
{}

void ClippedSphereVol::addPlane(const Plane& p, bool fit)
{
  m_planes.push_back(make_pair(p,fit));
}

Vector3 ClippedSphereVol::getAPoint(int n) const
{
  Vector3 res;
  
  do {
    res=SphereVol::getAPoint(n);
  } while (!isIn(res));

  return res;
}

const map<double,const AGeometricObject*> ClippedSphereVol::getClosestObjects(const Vector3& pos ,int nr) const
{
  map<double,const AGeometricObject*> res=SphereVol::getClosestObjects(pos,nr);

  for(vector<pair<Plane,bool> >::const_iterator iter=m_planes.begin();
      iter!=m_planes.end();
      iter++){
    if(iter->second){
      double dist=iter->first.getDist(pos);
      res.insert(make_pair(dist,&(iter->first)));
    }
  }
  return res;  
}

bool ClippedSphereVol::isIn(const Vector3& pos) const
{
  bool res=SphereVol::isIn(pos);

  vector<pair<Plane,bool> >::const_iterator iter=m_planes.begin();
  while(res && iter!=m_planes.end()){
    bool rside=((pos-iter->first.getOrig())*iter->first.getNormal())>0.0;
    res=res && rside;
    iter++;
  }
  return res;
}

bool ClippedSphereVol::isIn(const Sphere& S)
{
  bool res=SphereVol::isIn(S);

  vector<pair<Plane,bool> >::const_iterator iter=m_planes.begin();
  while(res && iter!=m_planes.end()){
    bool rside=((S.Center()-iter->first.getOrig())*iter->first.getNormal())>S.Radius();
    res=res && rside;
    iter++;
  }

  return res;
}



