#include <func.h>
#include <funcstate.h>
#include <functest.h>
#include <point.h>
#include <print.h>
#include <prob_func.h>

typedef point2<double> pt2;

void functest::test01()
{
  cout << "Creating a class within a function is legal" << endl;
  cout << "This may be used to eliminate the global name." << endl;
  cout << "Testing with points" << endl;

  pt2 p0(1.0,2.0);
  pt2 p1(3.5,6.0);

  class fred
  {
  public:

    pt2 p0;
    pt2 p1;

    pt2 operator()(double t)
      { return p0 + (p1-p0)*t; }
  };

  fred f;
  f.p0 = pt2(1.0,2.0);
  f.p1 = pt2(3.5,6.0);

  cout << SHOW( f(1.0) ) << endl;

}

void functest::test02()
{
  funcA1V2(finterp,v0+(v1-v0)*x,x,pt2,double) f(pt2(1.0,2.0),pt2(3.5,6.0));

  cout << SHOW( f(1.0) ) << endl;
  pt2 y;
  f(y,1.0);
  cout << SHOW(y) << endl;
}


funcTA1(cubic2,1.0+x*(1.0+x*(1.0+x)),x);
void functest::test03()
{
  cout << "Test templated function with one argument." << endl;
  cubic2<double,double> f;
  cout << SHOW( f(5.0) ) << endl;
  double y;
  cubic2<double,double>()(y,1.0);
  cout << SHOW(y) << endl;
}

funcTA2(tri1,(1.0-u-v)*2.0+u*3.0+v*5.0,u,v);
void functest::test04()
{
  cout << "Test templated function with two arguments." << endl;

  tri1<double,double> f;
  cout << SHOW( f(0.2,0.3) ) << endl;
}

void functest::test05()
{
  funcA1(hat,x*x+1.0,x,double,double);
  hat f;
  cout << SHOW(f(0.5)) << endl;
}

void functest::test06()
{
  funcA2(cat,u*u+v*v+u*v,u,v,double,double);
  cout << SHOW( cat()(.2,.3) ) << endl;
}

void functest::test07()
{
  class f1 : public funcstate< double >
  {
  public:

    f1() : funcstate<double>(2,true) {}

    doublec operator()()
    {
      double v0 = (xi[0]*xi[0]+xi[1]-11.0);
      double v1 = (xi[1]*xi[1]+xi[0]-7.0);
      xi[2] = v0*v0 + v1*v1;
      return xi[2];
    }
  };

  f1 f;
  f.xi[0]=1.0;
  f.xi[1]=0.0;
  f();
  double y=f.xi[2];
  cout << SHOW(y) << endl;
}

void functest::test08()
{
  prob_f002 f;

  funchistory<double> fh(f);

  f.xi[0]=1.0;
  f.xi[1]=0.0;
  f();
  cout << printvecfunc(f.xi,f.dim+1) << endl;
  fh.push();
  f.xi[1]=1.0;
  f();
  cout << printvecfunc(f.xi,f.dim+1) << endl;
  fh.push();
  f.xi[0]=3.0;
  f.xi[1]=3.0;
  f();

  //cout << SHOW(f.dim) << endl;

  cout << printvecfunc(f.xi,f.dim+1) << endl;

  cout << "Restoring the previous value" << endl;
  fh.pop();
  cout << printvecfunc(f.xi,f.dim+1) << endl;

/*
  double* t = new double[2];
  t[0]=.2;
  t[1]=.3;
  fh.fs.set_position(t);
*/

}


