#include <sstream>
#include <string>
#include "node.hpp"
#include "parser.hpp"
#include "Vector3D.hpp"

int main(int argc, char *argv[])
{
	string solid;
	if (argc>1) 
		solid= argv[1];
	else
		solid= "curva";	
	

	std::string lin;
	lin= "";
	std::cout << "x(t)= \n";
	while (!std::cin.eof() && std::cin.peek()!=';')
		lin+= char(std::cin.get());
	lin+= std::cin.get();
	Parser px(lin, NULL, NULL);
	Node* x= px.Tree();
	Node* xp= x->deriv();
	std::cout << "x(t):= " <<  x->print() << std::endl;
	std::cout << "xp(t):= " <<  xp->print() << std::endl;

	lin= "";
	std::cout << "y(t)= \n";
	while (!std::cin.eof() && std::cin.peek()!=';')
		lin+= char(std::cin.get());
	lin+= std::cin.get();
	Parser py(lin, NULL, NULL);
	Node* y= py.Tree();
	Node* yp= y->deriv();
	std::cout << "y(t):= " <<  y->print() << std::endl;
	std::cout << "yp(t):= " <<  yp->print() << std::endl;

	lin= "";
	std::cout << "z(t)= \n";
	while (!std::cin.eof() && std::cin.peek()!=';')
		lin+= char(std::cin.get());
	lin+= std::cin.get();
	Parser pz(lin, NULL, NULL);
	Node* z= pz.Tree();
	Node* zp= z->deriv();
	std::cout << "z(t):= " <<  z->print() << std::endl;
	std::cout << "zp(t):= " <<  zp->print() << std::endl;

	double a, b;
	std::cout << "Dar a b:\n";
	std::cin >> a >> b;
	std::cout  << "a: " <<  a << " b: " << b << std::endl;
	int N;
	std::cout << "N:\n";
	std::cin >> N;
	std::cout  << "N: " <<  N << std::endl;
	double h= (a+b)/N;
	int M;
	std::cout << "M:\n";
	std::cin >> M;
	std::cout  << "M: " <<  M << std::endl;
	double r;
	std::cout << "r:\n";
	std::cin >> r;
	std::cout  << "r: " <<  r << std::endl;

	double co[M+1];
	double si[M+1];
	double ta= 0.0;
	double tb= 2.0 * M_PI;
	double ht= (tb-ta) / M;
	for (int k=0; k<=M; ++k) {
		double th= ta + k*ht;
		co[k]= r*cos(th);
		si[k]= r*sin(th);
	}

	Vector3D G[N+1][M+1];
	Vector3D sky(0,0,1);
	for (int i=0; i<=N; ++i) {
		double t= a + i*h;
		Vector3D p(x->eval(t), y->eval(t), z->eval(t));
		Vector3D u= unit(Vector3D(xp->eval(t), yp->eval(t), zp->eval(t)));
		Vector3D v= unit(sky - (sky*u)*u);
		Vector3D w= u % v;

		std::cerr << "u: " << u << " v: " << v << " w: " << w << std::endl;
		for (int j=0; j<=M; ++j) {
			G[i][j]= p+ co[j]*v + si[j]*w;
			std::cerr << "t: " << t 
				<< " G[" << i <<"][" << j <<"]= " << G[i][j] << std::endl;
		}
	}

	delete zp;
	delete yp;
	delete xp;
	delete z;
	delete y;
	delete x;

	std::cout << 2*N*M << std::endl;
	for (int i=0; i<N; ++i)
		for (int j=0; j<M; ++j) {
			std::cout << G[i][j] << G[i+1][j+1] << G[i+1][j];
			std::cout << G[i][j] << G[i][j+1] << G[i+1][j+1];
		}

	return EXIT_SUCCESS;
}
