#include "CommandlineOptions.hh"
#include "PointConfiguration.hh"
#include "Symmetry.hh"
#include "Chirotope.hh"
#include "Incidences.hh"
#include "PlacingTriang.hh"
#include "ConfData.hh"
#include "TriangResult.hh"
#include "RegularityCheck.hh"
#include "Message.hh"

int main(const int argc, const char** argv) {

  using namespace topcom;
  
  CommandlineOptions::init(argc, argv);
  
  MessageStreams::forced() << std::endl;
  MessageStreams::forced() << "------------------------------------------------------------------\n";
  MessageStreams::forced() << " checking regularity of triangulations \n";
  MessageStreams::forced() << " TOPCOM client: " << CommandlineOptions::client() << '\n';
  MessageStreams::forced() << "------------------------------------------------------------------\n";
  MessageStreams::forced() << std::endl;

  Options options;

  // this client only makes sense with a seed:
  options.remove_options(Options::NO_SEED);
  ConfData confdata(options);
  CommentGrinder commentgrinder;
  confdata.read_input(std::cin);
  if (CommandlineOptions::check_regular()) {
    RegularityCheck::init();
  }
  if (!confdata.has_seed()) {
    MessageStreams::forced() << "no triangulation found - check done." << std::endl;
    return 0;
  }
  SimplicialComplex triang = confdata.seed();
  size_type count(0);
  size_type count_nonregs(0);
  confdata.make_inctable();
  confdata.make_voltable();
  confdata.make_volume();
  do {
    if ((count > 0) && CommandlineOptions::check_triang()) {
      MessageStreams::verbose() << "checking seed triangulation ..." << std::endl;
      if (!CheckTriang(confdata,
		       triang,
		       symmetryptr_datapair(confdata.symmetries().stabilizer_ptrs(triang)))()) {
	MessageStreams::verbose() << "read triangulation " << std::endl
				  << triang << std::endl
				  << "not valid - exiting." << std::endl;
	exit(1);
      }
      MessageStreams::verbose() << "... done." << std::endl;
    }
    ++count;
    TriangResult triangresult(confdata,
			      count,
			      0,
			      0,
			      0,
			      triang);

    // the following properties are computed anyway:
    triangresult.make_support();
    triangresult.make_supportcard();
    triangresult.make_card();

    // the following properties are computed only if demanded by command line options:
    if (CommandlineOptions::check_regular()) {
      RegularityCheck regcheck(confdata, triang);
      bool is_regular(regcheck.is_regular());
      triangresult.set_is_regular(is_regular);
      if (CommandlineOptions::output_heights()) {
	triangresult.set_heights(regcheck.heights());
      }
    }
    if (CommandlineOptions::check_full()) {
      triangresult.make_is_full();
    }
    if (CommandlineOptions::check_unimodular()) {
      triangresult.make_is_unimodular();
    }
    if (CommandlineOptions::output_gkzvecs()) {
      triangresult.make_gkzvec();
    }
    if (CommandlineOptions::check_flag()) {
      triangresult.make_is_flag();
    }
    if (CommandlineOptions::observe_required_symmetries()) {
      triangresult.make_triang_symmetries();
      triangresult.make_has_required_syms();
    }
    MessageStreams::result() << triangresult << std::endl;
    MessageStreams::verbose() << "checked " << count << " triangulations for properties so far" << std::endl;
    std::cin >> commentgrinder;
  } while (triang.read(std::cin));
  MessageStreams::verbose() << "... no more triangulations found." << std::endl;
  if (CommandlineOptions::check_regular()) {
    RegularityCheck::term();
  }
  return 0;
}


// eof checkregularity.cc
