/* Copyright (c) 1997-2004
   Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
   http://www.math.tu-berlin.de/polymake,  mailto:polymake@math.tu-berlin.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.
*/

#ident "$Project: polymake $$Id: hd_embedder.cc,v 1.4 2004/06/22 16:22:36 gawrilow Exp $"

#include <Poly.h>
#include <vector>
#include <HDEmbedder.h>

namespace polymake { namespace graph {

void hd_embedder(Poly& p,
		 const char *hd_section, const char *embedding_section, const char *label_width_section,
		 const argv_option *options)
{
   const HasseDiagram<> HD=p.give(hd_section);
   const std::vector<double> label_width=p.give(label_width_section);
   HDEmbedder HDE(HD, label_width);
   p.take(embedding_section) << std::setprecision(6) << HDE.compute(options);
}

} }

using namespace polymake;

/** @file hd_embedder
 *
 *  Create an embedding of the Hasse diagram as a layered graph.
 *
 *  The embedding algorithm tries to minimize the weighted sum of squares of edge lengths, starting
 *  from a random distribution. The weights are relative to the fatness of the layers.
 *
 *  The y-space between the layers is constant; in the @c -primal mode the whole-lattice node is placed
 *  on the top, in the @c -dual mode it is the empty node.
 *
 *  @c label_width_section should contain estimates (better upper bounds) of the label width of each
 *  node.  The computed layout guarantees that the distances between the nodes in a layer are at least equal to
 *  the widest label in this layer.
 *
 *  @c eps is the calculation accuracy.
 *
 *  option @c seed effects the initial placement of the nodes.
 *
 *  @synopsis hd_embedder <file> <hd_section> <embedding_section> <label_width_section> { -primal | -dual }
 *              [ -seed <s> -eps <x> ]
 *
 *  @reading  <hd_section> <label_width_section>
 *  @writing  <embedding_section>
 *
 *  @client   Visualization
 */

int main(int argc, const char *argv[])
{
   argv_option options[]={ { "-primal" }, { "-dual" },
			   { "-eps", true }, { "-seed", true } };
   if (!extract_options(argc,argv,2,options) || argc != 5 ||
       bool(options[graph::HDEmbedder::opt_primal]) == bool(options[graph::HDEmbedder::opt_dual]) ) {
      cerr << "usage: " << argv[0] << " <file> <hd_section> <embedding_section> <label_width_section> { -primal | -dual } [ -seed <s> ] [ -eps <x> ]" << endl;
      return 1;
   }
   try {
      Poly p(argv[1], ios::in | ios::out);
      graph::hd_embedder(p, argv[2], argv[3], argv[4], options);
   }
   catch (const std::exception& e) {
      cerr << e.what() << endl;
      return 1;
   }
   return 0;
}
