#  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.
#-------------------------------------------------------------------------------

CREDIT gfan
  Gfan is a software package for computing Groebner fans and tropical varieties.
  Copyright by Anders Jensen
  http://home.imf.au.dk/jensen/software/gfan/gfan.html

# path to gfan_bases
custom $gfan_bases;

# path to gfan_secondaryfan
custom $gfan_secondaryfan;

# path to gfan_topolyhedralfan
custom $gfan_topolyhedralfan;

CONFIGURE {
    find_program($gfan_bases,           "gfan_bases");
	($gfan_secondaryfan=$gfan_bases) =~ s/gfan_bases$/gfan_secondaryfan/;
    find_program($gfan_secondaryfan,    "gfan_secondaryfan");
	($gfan_topolyhedralfan=$gfan_bases) =~ s/gfan_bases$/gfan_topolyhedralfan/;
    find_program($gfan_topolyhedralfan, "gfan_topolyhedralfan");
}

# command => Object
sub run_gfan {
  my ($cmd)=@_;
  open my $gfan_pipe, "$cmd --xml 2>/dev/null |" or die "can't run $cmd: $!\n";
  Core::Object->fromXMLstream($gfan_pipe);
}

# @category Producing a fan
# Call [[wiki:external_software#gfan]] to compute the secondary fan of a point configuration.
#
# @param Matrix M a matrix whose rows are the vectors in the configuration
# @return PolyhedralFan
user_function secondary_fan(Matrix) {
  my ($M)=@_;
  my $tempfile=new Tempfile;
  my $input=gfan_print_matrix($tempfile, eliminate_denominators_entire_affine($M));
  # WARNING: file automatically converted via XSLT to correct F_VECTOR
  return run_gfan("$gfan_secondaryfan <$input");
}

# @category Producing a fan
# Call [[wiki:external_software#gfan]] to compute the secondary fan of a point configuration.
#
# @param polytope::PointConfiguration P
# @return PolyhedralFan
user_function secondary_fan(polytope::PointConfiguration) {
  my ($pc)=@_;
  return secondary_fan($pc->POINTS);
}

sub gfan_print_matrix {
  my ($tempname, $M) = @_;

  open(my $infile, ">$tempname.txt")
    or die "can't create temporary file $tempname.txt: $!";

  print $infile "{";
  my $r=$M->rows();
  my $c=$M->cols();
  for (my $i=0; $i<$r; ++$i) {
    print $infile "," unless $i==0;
    print $infile "(";
    for (my $j=0; $j<$c; ++$j) {
      print $infile "," unless $j==0;
      print $infile $M->elem($i,$j);
    }
      print $infile ")";
  }
  print $infile "}\n";

  close $infile;
  return "$tempname.txt";
}

# @category Producing a fan
# Call [[wiki:external_software#gfan]] to compute the greobner fan of an ideal.
#
# @param ideal::Ideal I input ideal
# @return PolyhedralFan
user_function groebner_fan(ideal::Ideal) {
  my ($I)=@_;
  my $tempfile=new Tempfile;
  my $input=gfan_print_ideal($tempfile, $I);
  # WARNING: file automatically converted via XSLT to correct F_VECTOR
  return run_gfan("$gfan_bases <$input 2>/dev/null | $gfan_topolyhedralfan");
}

sub gfan_print_ideal {
  my ($tempname, $I) = @_;

  open(my $infile, ">$tempname.txt")
    or die "can't create temporary file $tempname.txt: $!";

  print $infile "Q[", (join ",", monomials($I->N_VARIABLES)), "]\n";
  print $infile "{", (join ",", @{$I->GENERATORS}), "}\n";

  close $infile;
  return "$tempname.txt"
}

# Local Variables:
# mode: perl
# cperl-indent-level:2
# End:
