#include <iostream>

using namespace std;

#include "fstringMR.hpp"

template <class T>
class fstack
{
    protected:
    fstack * _back;
    T * _data;
    public:
        fstack(fstack * back, T * data)
        {
            _back = back;
            _data = data;
        }
        T * data()
        {
            return _data;
        }
        fstack * back()
        {
            return _back;
        }
};

void show(funcString * txt)
{
    int i =0;
    while((*txt)(i))
        cout << (*txt)(i++);
    cout << endl;
}

int main()
{
//     cout << "yeah functional stack !!!\n";
//
//     funcString * un = new fstr("un");
//     fstack <funcString> * sun = new fstack <funcString> (0,un);
//
//     sun = new fstack <funcString> (sun, new fstr("deux"));
//
//     show(sun->data());
//     show(sun->back()->data());
//
//     delete sun->back()->data();
//     delete sun->back();
//     delete sun->data();
//     delete sun;
//
//     cout << "garbage collector for functional string\n";
//
    funcString * str;
    gcfstr * gc;
//
//     str = new fstr("un");
//     gc = new gcfstr(str);
//     str = new fstr("deux");
//     gc = new gcfstr(gc,str);
//     str = new fstr("trois");
//     gc = new gcfstr(gc,str);
//     str = new fstr("quatre");
//     gc = gc->add(str);
//     show(str);
//     show(gc->data());
//
//     delete gc;

    gc = new gcfstr();
    str = new fstr("hello ");
    gc = gc->add(str);
    str = new fins(str,"world!",6,0);
    gc = gc->add(str);
    str = new fupper(str);
    gc = gc->add(str);
    str = new fsubstr(str,0,6);
    gc = gc->add(str);
    funcString * tmp = new fstr("god damn bastard");
    str = new fins2(str, tmp,6,0);
    gc = gc->add(tmp)->add(str);
    str = new fstart(str,' ');
    gc = gc->add(str);

    show(str);

    delete gc;

    return 0;
}
