#include <iostream>
using namespace std;

#include <print.h>
#include <point.h>

#include <mathlib.h>
#include <commandline.h>
#include <mathlibtest.h>

//template< typename T=double>
//double solver<double>::zero=0.0;

//double solver<double>::zero = (double)(1E-20);

//double solver<double>::zero(1E-20);


void mathlibtest::test01(int argc, char** argv)
{
  cout << "2D linear equation solver." << endl;

  
  point2<double> a0(3.0,2.0);
  point2<double> a1(5.0,-7.0);
  point2<double> c(10.0,3.0);

  commandline cmd(argc,argv);
  cmd.mapvar(a0.x,"a00");
  cmd.mapvar(a0.y,"a10");
  cmd.mapvar(a1.x,"a01");
  cmd.mapvar(a1.y,"a11");
  cmd.mapvar(c.x,"c0");
  cmd.mapvar(c.y,"c1");

  point2<double> x;

  solver<double>::d2linearequ(x,a0,a1,c);

  cout << SHOW(x) << endl;
}

void mathlibtest::test02(int argc, char** argv)
{
  cout << "2D linear equation solver." << endl;

  double a00(3.0);
  double a01(5.0);
  double a10(2.0);
  double a11(-7.0);
  double c0(10.0);
  double c1(3.0);
  double x;
  double y;
  
  commandline cmd(argc,argv);
  cmd.mapvar(a00,"a00");
  cmd.mapvar(a10,"a10");
  cmd.mapvar(a01,"a01");
  cmd.mapvar(a11,"a11");
  cmd.mapvar(c0,"c0");
  cmd.mapvar(c1,"c1");

  solver<double>::d2linearequ(x,y,a00,a01,a10,a11,c0,c1);

  cout << SHOW(x) << " " << SHOW(y) << endl;
}

void mathlibtest::test03()
{
  vector<uint> index;
  index.push_back(3);
  index.push_back(0);
  index.push_back(11);
  index.push_back(9);
  index.push_back(7);

  vector<uint> v2;
  uintc N(15);
  integersetdiff(v2,index,N);
  cout << SHOW(print(index)) << endl;
  cout << SHOW(print(v2)) << endl;
  cout << SHOW(N) << endl;

  

}

void mathlibtest::test04(int argc, char** argv)
{
  commandline cmd(argc,argv);
  double a0;
  double a1;
  double b0;
  double b1;
  cmd.mapvar(a0,"a0");
  cmd.mapvar(a1,"a1");
  cmd.mapvar(b0,"b0");
  cmd.mapvar(b1,"b1");

  double c0;
  double c1;
  bool res;
  res = intervalintersection::unordered(c0,c1,a0,a1,b0,b1);
  cout << SHOW(res) << endl;
  cout << "( " << c0 << ", " << c1 << " )" << endl;
}

void mathlibtest::test05()
{
  double a0;
  double a1;
  double b0;
  double b1;
  double c0;
  double c1;
  bool res;

  cout << "Testing 4 different interval intersection cases." << endl << endl;

  a0=0.1; a1=0.5;
  b0=0.3; b1=0.7;
  cout << "( " << a0 << ", " << a1 << " )  ( " << b0 << ", " << b1 << " )" << endl;
  res = intervalintersection::unordered(c0,c1,a0,a1,b0,b1);
  cout << SHOW(res) << "  ( " << c0 << ", " << c1 << " )" << endl;

  a0=0.1; a1=0.5;
  b0=0.2; b1=0.4;
  cout << "( " << a0 << ", " << a1 << " )  ( " << b0 << ", " << b1 << " )" << endl;
  res = intervalintersection::unordered(c0,c1,a0,a1,b0,b1);
  cout << SHOW(res) << "  ( " << c0 << ", " << c1 << " )" << endl;


  a0=0.1; a1=0.5;
  b0=0.0; b1=0.3;
  cout << "( " << a0 << ", " << a1 << " )  ( " << b0 << ", " << b1 << " )" << endl;
  res = intervalintersection::unordered(c0,c1,a0,a1,b0,b1);
  cout << SHOW(res) << "  ( " << c0 << ", " << c1 << " )" << endl;


  a0=0.1; a1=0.5;
  b0=0.0; b1=0.7;
  cout << "( " << a0 << ", " << a1 << " )  ( " << b0 << ", " << b1 << " )" << endl;
  res = intervalintersection::unordered(c0,c1,a0,a1,b0,b1);
  cout << SHOW(res) << "  ( " << c0 << ", " << c1 << " )" << endl;
}



void mathlibtest::test06(int argc, char** argv)
{
  commandline cmd(argc,argv);
  double a[2];
  double b[2];

  a[0] = a[1] = 0.0;
  b[0] = b[1] = 0.0;

  cmd.mapvar(a[0],"a0");
  cmd.mapvar(a[1],"a1");

  cmd.mapvar(b[0],"b0");
  cmd.mapvar(b[1],"b1");

  cout << "a = ( " << a[0] << ", " << a[1] << " )" << endl;
  cout << "b = ( " << b[0] << ", " << b[1] << " )" << endl;

  bool res;
  res = intervalintersection::unordered(a,b);
  cout << SHOW(res) << endl;
}

void mathlibtest::test07(int argc, char** argv)
{
  commandline cmd(argc,argv);
  double a[2][2];
  double b[2][2];

  // Describe a box 
  // x: [ a00, a01 ]
  // y: [ a10, a11 ]
  
  a[0][0] = 0.2;
  a[0][1] = 0.3;
  a[1][0] = 0.1;
  a[1][1] = 0.7;

  cmd.mapvar(a[0][0],"a00");
  cmd.mapvar(a[0][1],"a01");
  cmd.mapvar(a[1][0],"a10");
  cmd.mapvar(a[1][1],"a11");

  cout << "First box" << endl;
  cout << "{ ( " << a[0][0] << ", " << a[0][1] << " ), ( ";
  cout << a[1][0] << ", " << a[1][1] << " ) }" << endl;

  // Describe a box 
  // x: [ b00, b01 ]
  // y: [ b10, b11 ]
  b[0][0] = -1.0;
  b[0][1] = 0.0;
  b[1][0] = 0.1;
  b[1][1] = 0.5;

  cmd.mapvar(b[0][0],"b00");
  cmd.mapvar(b[0][1],"b01");
  cmd.mapvar(b[1][0],"b10");
  cmd.mapvar(b[1][1],"b11");

  cout << "Second box" << endl;
  cout << "{ ( " << b[0][0] << ", " << b[0][1] << " ), ( ";
  cout << b[1][0] << ", " << b[1][1] << " ) }" << endl;

  bool res;
  res = intervalintersection::unorderedD2((double*)a,(double*)b);
  cout << SHOW(res) << endl;
}


void mathlibtest::test010()
{
  double a[3];
  double x[2];
  bool res;

  a[0]=0.1; 
  a[1]=3.0; 
  a[2]=4.0;
  res = solverInconsistent<double>::d1linearequ(x[0],x[1],a[0],a[1],a[2]);
  cout << "a[]: " << print(a,a+3) << endl;
  cout << "x[]: " << print(x,x+2) << endl;
  cout << SHOW(a[0]*x[0]+a[1]*x[1]-a[2]) << endl;
  cout << SHOW(res) << endl;
  cout << endl;

  a[0]=0.1; 
  a[1]=0.0; 
  a[2]=4.0;
  res = solverInconsistent<double>::d1linearequ(x[0],x[1],a[0],a[1],a[2]);
  cout << "a[]: " << print(a,a+3) << endl;
  cout << "x[]: " << print(x,x+2) << endl;
  cout << SHOW(a[0]*x[0]+a[1]*x[1]-a[2]) << endl;
  cout << SHOW(res) << endl;
  cout << endl;

  a[0]=0.0; 
  a[1]=-1.0; 
  a[2]=5.0;
  res = solverInconsistent<double>::d1linearequ(x[0],x[1],a[0],a[1],a[2]);
  cout << "a[]: " << print(a,a+3) << endl;
  cout << "x[]: " << print(x,x+2) << endl;
  cout << SHOW(a[0]*x[0]+a[1]*x[1]-a[2]) << endl;
  cout << SHOW(res) << endl;
  cout << endl;

}


void mathlibtest::test011()
{

  double a[4] = {0.0,0.0,1.0,0.0};
  double b[4] = {2.0,1.0,0.0,-0.5};


  point3<double> w;
 
  bool res;
  res = solverInconsistent<double>::d2linearequ
  (
    w.x,w.y,w.z,
    a[0],a[1],a[2],a[3],
    b[0],b[1],b[2],b[3]
  );

  cout << SHOW(res) << endl;

  cout << SHOW( w.x*a[0]+w.y*a[1]+w.z*a[2]-a[3] ) << endl;
  cout << SHOW( w.x*b[0]+w.y*b[1]+w.z*b[2]-b[3] ) << endl;
}


void mathlibtest::test015()
{
  cout << "Circle and line intersection test in 2D." << endl;

  point2<double> p0;
  point2<double> p1;

  cout << "Enter 2 2D point for the start and end of the line." << endl;
  
  point2<double> q0;
  point2<double> q1;

  cin >> q0;
  cin >> q1;
  cout << "Enter cirle radius" << endl;
  double radius;
  cin >> radius;
  
  bool res;
  res = circleLine::intersection2D(p0,p1,radius,q0,q1);
  cout << SHOW(res) << endl;
  if (res)
  {
    cout << SHOW(p0) << endl;
    cout << SHOW(p1) << endl;
    cout << SHOW(p0.distance()) << endl;
    cout << SHOW(p1.distance()) << endl;
  }
}



