/////////////////////////////////////////////////////////////
//                                                         //
// Copyright (c) 2007-2014 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.opensource.org/licenses/osl-3.0.php          //
//                                                         //
/////////////////////////////////////////////////////////////

#include <boost/version.hpp>
#include <iostream>
#include <sstream>
#include "InsertGenerator2DPy.h"

using namespace boost::python;

    using boost::python::arg;
    void exportAGenerator2D()
    {
      // Disable autogeneration of C++ signatures (Boost 1.34.0 and higher)
      // for Epydoc which stumbles over indentation in the automatically generated strings.
      boost::python::docstring_options no_autogen(true,false);

      class_<AGenerator2D, boost::noncopyable>("AGenerator2D", "Abstract base class for 2D InsertGenerators",no_init);
    }

    void exportInsertGenerator2D()
    {
      // Disable autogeneration of C++ signatures (Boost 1.34.0 and higher)
      // for Epydoc which stumbles over indentation in the automatically generated strings.
      boost::python::docstring_options no_autogen(true,false);

      class_<InsertGenerator2D, bases<AGenerator2D> >(
        "InsertGenerator2D",
        "A particle packing algorithm for filling an L{AVolume2D} space",
        init<>()
      )
      .def(init<const InsertGenerator2D &>())
      .def(
        init<double,double,int,int,double>(
          ( arg("minRadius"), arg("maxRadius"), arg("insertFails"), arg("maxIterations"), arg("tolerance") ),
          "Initialises a particle packer in preparation for filling an\n"
          "L{AVolume2D} with particles whose radii are in the specified range.\n"
          "The packing will terminate after the specified number of \n"
          "insertion failures. The iterative solver will compute only the\n"
          "specified maximum number of iterations. Particles are permitted \n"
          "to overlap by the specified tolerance.\n" 
          "@type minRadius: double\n"
          "@kwarg minRadius: the minimum radius of particles to pack\n"
          "@type maxRadius: double\n"
          "@kwarg maxRadius: the maximum radius of particles to pack\n"
          "@type insertFails: int\n"
          "@kwarg insertFails: the number of particle insertion failures before the packer terminates\n"
          "@type maxIterations: int\n"
          "@kwarg maxIterations: the maximum number of iterations of the solver\n"
          "@type tolerance: double\n"
          "@kwarg tolerance: the overlap tolerance permitted\n"
          "@rtype: void\n"
        )
      )
      .def(
	   init<double,double,int,int,double,bool>(
	   ( arg("minRadius"), arg("maxRadius"), arg("insertFails"), arg("maxIterations"), arg("tolerance"),arg("seed") ),
          "@type seed: bool\n"
          "@kwarg seed: randomize the random number generator if True (optional)\n"
        )
      )
      .def(
        "generatePacking",
        &InsertGenerator2D::generatePacking,
        ( arg("volume"), arg("ntable"), arg("groupID")=0, arg("tag") ),
        "Generates a particle assembly to fill the specified area.\n"
        "@type volume: L{AVolume2D}\n"
        "@kwarg volume: the area to fill with particles\n"
        "@type ntable: L{MNTable2D}\n"
        "@kwarg ntable: the neighbours table that particles are inserted into\n"
        "@type groupID: int\n"
        "@kwarg groupID: the group ID assigned to particles (default: 0)\n"
        "@type tag: int\n"
        "@kwarg tag: the tag assigned to particles\n"
        "@rtype: void\n" 
      )
      .def(
	"setOldSeeding",
	&InsertGenerator2D::setOldSeeding,
	( arg("old")),
	"Sets seeding behavior to the older method.\n"
        "@type old: bool\n"
        "@kwarg old: toggle between old and new seeding methods.\n"
      )
      .def(self_ns::str(self))
      ;
    }



