/*
 * app_cone.cpp
 *
 *  Created on: Aug 14, 2025
 *      Author: anders
 */

#include <iostream>
#include <fstream>
#include <stdlib.h>
#include "parser.h"
#include "printer.h"
#include "gfanapplication.h"
#include "gfanlib_tableau.h"
#include "gfanlib_circuittableinteger.h"
#include "log.h"

using namespace gfan;


class ConeApplication : public GFanApplication
{
	SimpleOption optionLinealitySpace;
	SimpleOption optionIsPointed;
	SimpleOption optionDual;

public:
  bool includeInDefaultInstallation()
  {
    return true;
  }
  const char *helpText()
  {
    return "This program computes properties of a cone given on input via generators.\n"
    		"The input/output format is:\n"
    		"(ambientDimension,set of rays, set of lines)\n"
    		"(or\n"
    		"(ambientDimension,set of inequalities, set of equations)\n"
    		"if the interpretation is a cone given in H representation)\n"
    		"for example:"
    		"(3,{(1,2,3),(4,5,6)},{(1,1,1)})\n";
  }
  ConeApplication():
	  optionLinealitySpace("--linealityspace","Output the lineality space of the cone."),
	  optionIsPointed("--ispointed","Output whether the cone is pointed."),
	  optionDual("--dual","Output dual cone.")
  {
	  registerOptions();
  }

  const char *name()
  {
    return "_cone";
  }

  int main()
  {
	  typedef gfan::CircuitTableInteger typ;

	  auto a=parseSequence(cin);
	  assert(a.size()==3);
	  stringstream ss(a[0]);
	  int ambientDimension;ss>>ambientDimension;
	  stringstream ss1(a[1]);
	  stringstream ss2(a[2]);
	  auto inequalities=gfan::Matrix<typ>::readMatrix(ss1,ambientDimension).transposed();
	  auto equations=gfan::Matrix<typ>::readMatrix(ss2,ambientDimension).transposed();
	  auto C=gfan::GeneratedCone<typ>(inequalities,equations);

	  if(optionLinealitySpace.getValue())
	  {
		  std::cout<<C.getLinealitySpace().transposed().toString();
	  }
	  if(optionIsPointed.getValue())
	  {
		  std::cout<<int(C.getDimensionOfLinealitySpace()==0)<<"\n";
		  std::cerr<<C.getGenericSupportingHyperplane()<<"\n";
	  }
	  if(optionDual.getValue())
	  {
		  C.ensureStateAsMinimum(3);
		  std::cout<<"{"<<C.getAmbientDimension()<<",\n"
					  <<C.getFacetNormals().toString()<<",\n"
					  <<C.getOrthogonalComplement().toString()<<"}\n";
	  }

	  return 0;
  }
};

static ConeApplication theApplication;

