#include <iostream>
using namespace std;

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


void linetest::test01()
{
  typedef point2<double> pt2;
  typedef point3<double> pt3;

  line<pt2,double> L1(pt2(1.0,1.0),pt2());

  cout << "L1: " << (stringc) L1 << endl;
  
  double len=5.0;
  cout << "Normalize to having nml with " << len << " length." << endl;

  L1.normalize(len);
  cout << "L1: " << (stringc) L1 << endl;

  cout << SHOW(L1.nml.distance()) << endl;
  cout << SHOW( L1(0.0) ) << endl;
  cout << SHOW( L1(1.0) ) << endl;

  cout << "Re normalize." << endl;
  L1.normalize();
  cout << "L1: " << (stringc) L1 << endl;

  pt2 p2(6.0,6.0);
  cout << SHOW(p2) << endl;
  cout << "Find the t value of p2." << endl;
  double t1;
  bool res;
  res = L1.tD2(t1,p2);
  cout << SHOW(res) << "  " << SHOW(t1) << endl;
  cout << SHOW(L1(t1)) << endl;

  cout << endl;
  cout << "Testing point minimized to a line." << endl;
  double delta=0.1;
  cout << SHOW(delta) << endl;
  pt2 p3(2.0,3.0);
  cout << SHOW(p3) << endl;
  cout << "Minimize to L1:" << (stringc)L1 << endl;
  L1.nearestpoint(t1,p3);
  cout << SHOW((L1(t1-delta)-p3).distance()) << endl;
  cout << SHOW((L1(t1)-p3).distance()) << endl;
  cout << SHOW((L1(t1+delta)-p3).distance()) << endl;

}


void linetest::test02()
{
  typedef point3<double> pt3;

  pt3 pts[] = 
  {
    pt3(0.0,0.0,0.0),
    pt3(1.0,-3.0,2.0),
    pt3(.24,.1,-.3),
    pt3(-2.0,-10.0,4.3)
  };

  line<pt3,double> L1(pts[0],pts[1],true);
  line<pt3,double> L2(pts[2],pts[3],true);

  double t1;
  double t2;
  bool res;
  res = L1.lineD3minimized(t1,t2,L2);
  cout << SHOW(res) << endl;

  double delta = 0.1;
  cout << SHOW(delta) << endl;
  
  cout << "Varying t1" << endl;
  cout << SHOW((L1(t1-delta)-L2(t2)).distance()) << endl;
  cout << SHOW((L1(t1)-L2(t2)).distance()) << endl;
  cout << SHOW((L1(t1+delta)-L2(t2)).distance()) << endl;
  
  cout << "Varying t2" << endl;
  cout << SHOW((L1(t1)-L2(t2-delta)).distance()) << endl;
  cout << SHOW((L1(t1)-L2(t2)).distance()) << endl;
  cout << SHOW((L1(t1)-L2(t2+delta)).distance()) << endl;

}

int linetest::unittest01()
{
  typedef point2<double> pt2;

  line<pt2,double> L1(pt2(0.0,0.0),pt2(8.0,0.0),true);
  line<pt2,double> L2(pt2(3.0,-5.0),pt2(3.0,5.0),true);

  double t0;
  double t1;

  bool res;
  res = L1.intersects(t0,t1,L2);
  if (res==false)
    return 1;

  cout << SHOW( L1(t0) ) << endl;
  cout << SHOW( L2(t1) ) << endl;

  assertreturnOS( zero<double>::test( (L1(t0)-pt2(3.0,0.0)).dot() ) );

  return 0;
}


