#include <iostream>
#include <ctype.h>

#include "CommandlineOptions.hh"
#include "Symmetry.hh"
#include "PointConfiguration.hh"

int main(const int argc, const char** argv) {
  if (argc < 2) {
    std::cerr << "usage: " << argv[0] << " n" << std::endl;
    return 1;
  }
  parameter_type n = atoi(argv[1]);
  if (n <= 0) {
    std::cerr << "n > 0 required" << std::endl;
    return 1;
  }

  CommandlineOptions::init(argc, argv);

  // first compute the group D_n generated by the full cycle and a median reflection:
  symmetry_data D_data;
  Permutation p(n,n);
  Symmetry cycle(p); // the cycle (1,2,...,n)
  Symmetry reflection(p.reverse(), false); // the reflection (n, n-1, ..., 1)
  D_data.insert(cycle);
  D_data.insert(reflection);
  SymmetryGroup D(n, D_data);

  if (CommandlineOptions::debug()) {
    std::cerr << "group D(" << n << "):" << std::endl;
    std::cerr << D << std::endl;
  }

  // transform symmetries into permutation matrices:
  PointConfiguration B_D;
  B_D.append(Symmetry(n).ReducedPermutationMatrix().StackOfAllColumns());
  for (SymmetryGroup::const_iterator iter = D.begin();
       iter != D.end();
       ++iter) {
    const Symmetry s(*iter);
    B_D.append(s.ReducedPermutationMatrix().StackOfAllColumns());
  }
  B_D.homogenize();

  if (CommandlineOptions::debug()) {
    std::cerr << "matrix of size (" << B_D.rowdim() << "," << B_D.coldim() << "):" << std::endl;
    B_D.pretty_print(std::cerr);
  }

  // find a full-dimensional representation:
  B_D.transform_to_full_rank();
  
  if (CommandlineOptions::debug()) {
    std::cerr << "matrix in row eliminated form of size(" << B_D.rowdim() << "," << B_D.coldim() << ")" << std::endl;
    B_D.pretty_print(std::cerr);
  }

  std::cout << B_D << std::endl;
  //  std::cout << D << std::endl;
  return 0;
}
