//////////////////////////////////////////////////////////////////////////
// ComputeTriangs.hh
// produced: 25 Nov 1999 jr
/////////////////////////////////////////////////////////////////////////
#ifndef COMPUTETRIANGS_HH
#define COMPUTETRIANGS_HH

#include "Global.hh"
#include "Message.hh"
#include "SimplicialComplex.hh"
#include "PointConfiguration.hh"
#include "Chirotope.hh"
#include "Symmetry.hh"
#include "RegularityCheck.hh"
#include "Signal.hh"

namespace topcom {

  class ComputeTriangs {
  public:

    // flags:
    static constexpr int INPUT_CHIRO    = 0x0001;
    static constexpr int COMPUTE_ALL    = 0x0002;
    static constexpr int FINE_ONLY      = 0x0004;
    static constexpr int OUTPUT_TRIANGS = 0x0008;
    static constexpr int PREPROCESS     = 0x0010;
    static constexpr int FINDFLIPS      = 0x0020;
    static constexpr int UNIMODULAR     = 0x0040;
    static constexpr int FINDMIN        = 0x0080;    
  private:
    parameter_type        _no;
    parameter_type        _rank;
    PointConfiguration*   _pointsptr;
    Chirotope*            _chiroptr;
    SymmetryGroup*        _symmetriesptr;
    SymmetryGroup*        _required_symmetriesptr;
    SimplicialComplex*    _seedptr;
    symmetryptr_datapair* _seed_symmetryptrsptr;
    Volumes*              _voltableptr;
  public:
    bool                  input_chiro;
    bool                  compute_all;
    bool                  fine_only;
    bool                  output_triangs;
    bool                  preprocess;
    bool                  findflips;
    bool                  unimodular;
    bool                  findmin;    
  public:
    inline ComputeTriangs() :
      _no(-1),
      _rank(-1),
      _pointsptr(0),
      _chiroptr(0),
      _symmetriesptr(0),
      _required_symmetriesptr(0),
      _seedptr(0),
      _seed_symmetryptrsptr(0),
      _voltableptr(0),
      input_chiro(false),
      compute_all(false),
      fine_only(false),
      output_triangs(false),
      preprocess(false),
      findflips(false),
      unimodular(false),
      findmin(false) {
      if (CommandlineOptions::lp_solver_needed()) {
	
	// some solvers need initialization of global constants etc.:
	RegularityCheck::init();
      }
    }
    inline ComputeTriangs(const int flags) :
      _no(-1),
      _rank(-1),
      _pointsptr(0),
      _chiroptr(0),
      _symmetriesptr(0),
      _required_symmetriesptr(0),
      _seedptr(0),
      _seed_symmetryptrsptr(0),
      _voltableptr(0),
      input_chiro(flags & INPUT_CHIRO),
      compute_all(flags & COMPUTE_ALL),
      fine_only(flags & FINE_ONLY),
      output_triangs(flags & OUTPUT_TRIANGS),
      preprocess(flags & PREPROCESS),
      findflips(flags & FINDFLIPS),
      unimodular(flags & UNIMODULAR),
      findmin(flags & FINDMIN) {
      if (CommandlineOptions::lp_solver_needed()) {

	// some solvers need initialization of global constants etc.:
	RegularityCheck::init();
      }
    }
    
    inline ~ComputeTriangs() {
      if (CommandlineOptions::lp_solver_needed()) {
	
	// some solvers need termination of global constants etc.:
	RegularityCheck::term();
      }
      if (_pointsptr) {
	delete _pointsptr;
      }
      if (_chiroptr) {
	delete _chiroptr;
      }
      if (_symmetriesptr) {
	delete _symmetriesptr;
      }
      if (_required_symmetriesptr) {
	delete _required_symmetriesptr;
      }
      if (_seedptr) {
	delete _seedptr;
      }
      if (_seed_symmetryptrsptr) {
	delete _seed_symmetryptrsptr;
      }
      if (_voltableptr) {
	delete _voltableptr;
      }
    }

    int run();

    Message& write_header(Message&) const;
    std::istream& read_input(std::istream&);
    
    const std::pair<size_type, SimplicialComplex> findmin_by_extension(const parameter_type      no,
								       const parameter_type      rank,
								       const PointConfiguration* pointsptr,
								       const Chirotope*          chiroptr,
								       const SymmetryGroup*      symmetriesptr,
								       const SymmetryGroup*      required_symmetriesptr,
								       const bool                output_triangs,
								       const bool                only_fine_triangs);
    const size_type enumerate_by_extension(const parameter_type      no,
					   const parameter_type      rank,
					   const PointConfiguration* pointsptr,
					   const Chirotope*          chiroptr,
					   const SymmetryGroup*      symmetriesptr,
					   const SymmetryGroup*      required_symmetriesptr,
					   const bool                output_triangs,
					   const bool                only_fine_triangs);

    const size_type enumerate_by_flips(const parameter_type        no,
				       const parameter_type        rank,
				       const PointConfiguration*   pointsptr,
				       const Chirotope*            chiroptr,
				       const SymmetryGroup*        symmetriesptr,
				       const SymmetryGroup*        required_symmetriesptr,
				       const SimplicialComplex*    seedptr,
				       const symmetryptr_datapair* seed_symmetryptrs,
				       const Volumes*              voltableptr,
				       const bool                  output_triangs,
				       const bool                  fine_only);
    
  };
  
}; // namespace topcom

#endif

// eof ComputeTriangs.hh
