/* Copyright (c) 1997-2010
   Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Darmstadt, Germany)
   http://www.polymake.de

   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any
   later version: http://www.gnu.org/licenses/gpl.txt.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
--------------------------------------------------------------------------------
   $Project: polymake $$Id: beneath_beyond.cc 9991 2010-12-12 23:36:28Z gawrilow $
*/

#include "polymake/client.h"
#include "polymake/polytope/beneath_beyond.h"

namespace polymake { namespace polytope {

template <typename Scalar>
void beneath_beyond(perl::Object p, bool take_VERTICES)
{
   const Matrix<Scalar> Points=p.give(take_VERTICES ? "RAYS" : "INPUT_RAYS");

   beneath_beyond_algo<Scalar> algo(Points, take_VERTICES);
   algo.compute(entire(sequence(0,Points.rows())));

   p.take("FACETS") << algo.getFacets();
   p.take("LINEAR_SPAN") << algo.getAffineHull();
   p.take("RAYS_IN_FACETS") << algo.getVertexFacetIncidence();
   p.take("DUAL_GRAPH.ADJACENCY") << algo.getDualGraph();

   if (take_VERTICES) {
      p.take("TRIANGULATION.FACETS") << algo.getTriangulation();
      p.take("ESSENTIALLY_GENERIC") << algo.getGenericPosition();
   } else {
      p.take("RAYS") << algo.getVertices();
      p.take("TRIANGULATION_INT") << algo.getTriangulation();
   }
}

template <typename Scalar>
Array< Set<int> >
placing_triangulation(const Matrix<Scalar>& Points, const Array<int>& permutation)
{
   beneath_beyond_algo<Scalar> algo(Points, false);
   if (permutation.empty()) {
      algo.compute(entire(sequence(0,Points.rows())));
   } else {
      if (permutation.size() != Points.rows())
         throw std::runtime_error("placing_triangulation: wrong permutation");
      algo.compute(entire(permutation));
   }
   return algo.getTriangulation();
}

FunctionTemplate4perl("beneath_beyond<Scalar> (Cone<Scalar>; $=1) : void");

UserFunctionTemplate4perl("# @category Subdivisions"
                          "# Compute the placing triangulation of the given point set using the beneath-beyond algorithm."
                          "# @param Matrix Points the given point set"
                          "# @param Array<Int> permutation"
                          "# @return Array<Set<Int>>",
                          "placing_triangulation(Matrix; $=[ ])");
} }

// Local Variables:
// mode:C++
// c-basic-offset:3
// indent-tabs-mode:nil
// End:
