/* Copyright (c) 1997-2018
   Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
   http://www.polymake.org

   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.
--------------------------------------------------------------------------------
*/

#include "polymake/client.h"
#include "polymake/Set.h"
#include "polymake/IncidenceMatrix.h"
#include "polymake/graph/Lattice.h"
#include "polymake/Graph.h"
#include "polymake/graph/maximal_chains.h"

namespace polymake { namespace graph {

template <typename Decoration, typename SeqType>
IncidenceMatrix<> maximal_chains_of_lattice(perl::Object face_lattice_obj, perl::OptionSet options)
{
  Lattice<Decoration, SeqType> lattice(face_lattice_obj);
  bool ignore_bottom_node = options["ignore_bottom_node"];
  bool ignore_top_node = options["ignore_top_node"];
  const Array<Set<int> > max_chains = maximal_chains( lattice, ignore_bottom_node, ignore_top_node);
  return IncidenceMatrix<>(max_chains);
}

template <typename Decoration, typename SeqType>
perl::Object lattice_of_chains(perl::Object lattice_obj)
{
  Lattice<Decoration, SeqType> lattice(lattice_obj);
  Array<Set<int> > max_chains = maximal_chains(lattice,false, false);
  perl::Object chains_complex("topaz::SimplicialComplex");
  chains_complex.take("FACETS") << max_chains;
  perl::Object chain_hasse = chains_complex.give("HASSE_DIAGRAM");
  return chain_hasse;
}

UserFunctionTemplate4perl("# @category Combinatorics"
                          "# For a given lattice, this computes the lattice of chains from bottom to top node."
                          "# The result always includes an artificial top node."
                          "# @param Lattice<Decoration> lattice"
                          "# @return Lattice<BasicDecoration> Faces are sets of nodes of elements in the original"
                          "# lattice forming a chain, ranks are lenghts of chains"
                          "# @example [application polytope] The following prints all faces with their ranks of the lattice of"
                          "# chains of the face lattice of the 0-simplex (a single point):"
                          "# > print lattice_of_chains(simplex(0)->HASSE_DIAGRAM)->DECORATION;"
                          "# | ({-1} 3)"
                          "# | ({0 1} 2)"
                          "# | ({0} 1)"
                          "# | ({1} 1)"
                          "# | ({} 0)",
                          "lattice_of_chains<Decoration, SeqType>(Lattice<Decoration, SeqType>)");

UserFunctionTemplate4perl("# @category Combinatorics"
                          "# Computes the set of maximal chains of a Lattice object."
                          "# @param Lattice F"
                          "# @option Bool ignore_bottom_node If true, the bottom node is not included in the chains. False by default"
                          "# @option Bool ignore_top_node If true, the top node is not included in the chains. False by default"
                          "# @return IncidenceMatrix Each row is a maximal chain, "
                          "# indices refer to nodes of the Lattice"
                          "# @example [application polytope] [prefer cdd] The following prints all maximal chains of the face lattice of the"
                          "# 1-simplex (an edge):"
                          "# > print maximal_chains_of_lattice(simplex(1)->HASSE_DIAGRAM);"
                          "# | {0 1 3}"
                          "# | {0 2 3}",
                          "maximal_chains_of_lattice<Decoration, SeqType>(Lattice<Decoration, SeqType>, {ignore_bottom_node=>0, ignore_top_node=>0})");
} }
