#include <iostream>
#include <ostream>
#include <iomanip>

#include "Header.hh"

#include "Triangle.hh"

Int4 main(Int4 argc, Char *argv[]) {

    vector<Double> p=*(new vector<Double>());
    p.push_back( 1.0);
    p.push_back(-1.0);
    p.push_back( 0.0);
    p.push_back( 1.0);

    UInt4  nDiv;
    Double xmin, xmax;

    std::cout << "xmin=" ; std::cin >> xmin; std::cout << xmin << endl;
    std::cout << "xmax=" ; std::cin >> xmax; std::cout << xmax << endl;
    std::cout << "nDiv=" ; std::cin >> nDiv; std::cout << nDiv << endl;

    Double delta=(xmax-xmin)/static_cast<Double>(nDiv);
    vector<Double> xv=*(new vector<Double>());
    for (UInt4 i=0; i<=nDiv; ++i) {
        xv.push_back(xmin+delta*i);
    }

    std::cout << setw(24) << setiosflags(std::ios::right) << "x";
    std::cout << setw(24) << setiosflags(std::ios::right) << "eval";
    //std::cout << setw(24) << setprecision(15) << setiosflags(std::ios::right) << setiosflags(std::ios::scientific) << func.der1st(*x, p);
    std::cout << setw(24) << setiosflags(std::ios::right) << "der1st";
    std::cout << setw(24) << setiosflags(std::ios::right) << "der2nd";
    std::cout << setw(24) << setiosflags(std::ios::right) << "gradient->";
    std::cout << endl;

    Triangle func=*(new Triangle());
    for (std::vector<Double>::const_iterator x=xv.begin(); x != xv.end(); ++x) {
        std::cout << setw(24) << setprecision(15) << setiosflags(std::ios::right) << setiosflags(std::ios::scientific) << *x;
        std::cout << setw(24) << setprecision(15) << setiosflags(std::ios::right) << setiosflags(std::ios::scientific) << func.eval(  *x, p);
        std::cout << setw(24) << setprecision(15) << setiosflags(std::ios::right) << setiosflags(std::ios::scientific) << func.der1st(*x, p);
        //std::cout << setw(24) << setprecision(15) << setiosflags(std::ios::right) << setiosflags(std::ios::scientific) << func.der1st(*x, p[0], p[1], p[2], p[3]);
        std::cout << setw(24) << setprecision(15) << setiosflags(std::ios::right) << setiosflags(std::ios::scientific) << func.der2nd(*x, p);
        vector<Double> gv=func.gradient(*x, p);
        for (std::vector<Double>::const_iterator g=gv.begin(); g != gv.end(); ++g) {
            std::cout << setw(23) << setprecision(15) << setiosflags(std::ios::right) << setiosflags(std::ios::scientific) << *g;
        }
        std::cout << endl;
    }
    std::cout << endl;
}
