/**
 * Recogition of randomly generated digital circles
 */
bool testRecognition()
{

  typedef KhalimskySpaceND<2,int> KSpace; 
  GridCurve<KSpace> c; 
  
  unsigned int nbok = 0;
  unsigned int nb = 0;

  trace.beginBlock ( "Recognition" );
  
  for (unsigned int i = 0; i < 50; ++i)
  {
    //generate digital circle
    double cx = (rand()%100 ) / 100.0;
    double cy = (rand()%100 ) / 100.0;
    double radius = (rand()%100 )+100;
    c = ballGenerator<KSpace>( cx, cy, radius, ((i%2)==1) ); 
    trace.info() << " #ball #" << i << " c(" << cx << "," << cy << ") r=" << radius << endl; 
    
    //range
    typedef GridCurve<KSpace>::IncidentPointsRange Range; 
    Range r = c.getIncidentPointsRange();
    
    //recognition
    typedef Range::ConstIterator ConstIterator; //iterator
    StabbingCircleComputer<ConstIterator> s;
    longestSegment(s,r.begin(),r.end()); 

    //checking if the circle is separating
    bool flag = true;
    typedef CircleFrom3Points<KSpace::Point> Circle; 
    typedef functors::Point2ShapePredicate<Circle,false,true> 
      FirstInCirclePred; 
    typedef functors::Point2ShapePredicate<Circle,true,true> 
      SecondInCirclePred; 
    for (ConstIterator it = s.begin(); ((it != s.end()) && flag) ; ++it)
    {
      FirstInCirclePred p1( s.getSeparatingCircle() ); 
      SecondInCirclePred p2( s.getSeparatingCircle() ); 
      flag = ( p1(it->first)&&p2(it->second) ); 
    }
    
    //conclusion
    nbok += flag ? 1 : 0; 
    nb++;
  }

  trace.endBlock();
  
  trace.info() << "(" << nbok << "/" << nb << ") " << endl;
  return nbok == nb;
}
int main( int argc, char** argv )
{
  trace.beginBlock ( "Example for StabbingCircleComputer" );
  trace.info() << "Args:";
  for ( int i = 0; i < argc; ++i )
    trace.info() << " " << argv[ i ];
  trace.info() << endl;
  
  std::string filename = examplesPath + "samples/DCA.dat";
  ifstream instream; // input stream
  instream.open (filename.c_str(), ifstream::in);
  
  Curve c; //grid curve
  c.initFromVectorStream(instream);


  trace.beginBlock("Simple example");

  //! [StabbingCircleComputerUsage]
  Curve::IncidentPointsRange r = c.getIncidentPointsRange(); 
  Curve::IncidentPointsRange::ConstIterator itEnd (r.end()); 

  StabbingCircleComputer<Curve::IncidentPointsRange::ConstIterator> s; 
  //extension
  s.init( r.begin() );
  while ( ( s.end() != itEnd )
        &&( s.extendFront() ) ) {}
  //! [StabbingCircleComputerUsage]

  trace.info() << s << endl;  

  trace.endBlock();


  return 0;
}