/*===========================================
            Plant and fireworks
              Martin Robinson
                tree object
===========================================*/

#include "fractal.hpp"

//constructor
fractal::fractal(string lsys,int x, int y)
{
    _tree.init(lsys);
    _start.init(x,y);
    _turtle.init(_start);
    _index = 0;
    _touche = 0;
}

//reinitialise la tortue
void fractal::reset()
{
    _turtle.init(_start);
    _index=0;
    while(!_stack.empty())
    {
        _stack.pop();
    }
    _touche = 0;
}

//faire avance la tortue dans son code
void fractal::next()
{
    _index++;
}

//est-ce que la tortue a fini ?
bool fractal::end()
{
    return _index>= _tree.len();
}

//sur quel caracter la tortue se trouve ?
char fractal::get()
{
    if (!end())
        return _tree[_index];
    return 0;
}

//ou est la tortue à l'écran ?
turtle fractal::position()
{
    if (!end())
        return _turtle;
    return _start;
}

//coordonné X de la tortue
int fractal::x()
{
    return _turtle.x();
}

//coordonné Y de la tortue
int fractal::y()
{
    return _turtle.y();
}

//faire grandire la plante
void fractal::grow()
{
    _tree.iterate(_touche,0);
}

//interpreter le caractere courant par la tortue
void fractal::parse()
{
    if (!end())
    {
        switch(_tree[_index])
        {
            case 'a':
                _turtle.stroke();
                break;
            case '+':
                _turtle.rotate(0.5);
                break;
            case '-':
                _turtle.rotate(-0.5);
                break;
            case '[':
                _stack.push(_turtle);
                break;
            case ']':
                _turtle.init(_stack.top());
                _stack.pop();
                break;
            case '|':
                _turtle.forward(5);
                break;
            case '_':
                _turtle.forward(-5);
                break;
        }
    }
}

//affiche l'arbre
void fractal::print()
{
    _tree.print();
}

//index courrant
int fractal::index()
{
    return _index;
}

//declare que la souris est dessus l'index
void fractal::touch()
{
    _touche = index();
}

bool fractal::isTouch()
{
    return _touche!=0;
}

char fractal::getTouch()
{
    return _tree[_touche];
}

void fractal::trimTouch()
{
    if (_touche)
        _tree.trim(_touche);
}

void fractal::unTouch()
{
    _touche = 0;
}

/*//-------------------------------test code-------------------------------

#include "sdl/SDL.h"

#include <fstream>
#include <iostream>

using namespace std;

int main(int argc, char * argv[])
{
    //chessy loading file
    if (argc != 2)
    {
        cout << "invalid argument\n";
        return 0;
    }
    ifstream test_file(argv[1]);
    string line,buff;
    do
    {
        getline(test_file,buff);
        line.append(buff);
    }while(test_file);
    cout << line << endl;

    SDL_Init(SDL_INIT_EVERYTHING);
    SDL_Surface *screen = SDL_SetVideoMode(600, 400, 8, SDL_SWSURFACE);
    SDL_Event event;

    int keypress = 0,
        mx = 0,
        my = 0;
        
    Uint32 brown = SDL_MapRGB( screen->format, 0x66, 0x33, 0x00 ),
           red = SDL_MapRGB( screen->format, 0xFF, 0x00, 0x00 ),
           green = SDL_MapRGB( screen->format, 0x00, 0xFF, 0x00 );
           
    fractal arbre(line,300,300);
    arbre.grow();
    arbre.grow();
    arbre.grow();
    arbre.print();

    while(!keypress)
    {
        SDL_Flip(screen);
        SDL_FillRect(screen,0,0);

        while(SDL_PollEvent(&event))
        {
            switch (event.type)
            {
                case SDL_QUIT:
                    keypress = 1;
                    break;
                case SDL_KEYDOWN:
                    keypress = 1;
                    break;
                case SDL_MOUSEMOTION:
                    mx = event.motion.x;
                    my = event.motion.y;
                    break;
                case SDL_MOUSEBUTTONDOWN:
                    if (arbre.getTouch() == 'o')
                        arbre.grow();
                    else if (arbre.getTouch()=='a')
                        arbre.trimTouch();
                    arbre.print();
                    break;
            }
        }
        
        arbre.reset();
        while (!arbre.end())
        {
            arbre.parse();
            Uint32 color;
            SDL_Rect tmp = {arbre.position().x(), arbre.position().y(), 0, 0};
            if (arbre.get()=='o')
            {
                tmp.h = 20;
                tmp.w = 20;
                color = green;
            }
            else if (arbre.get()=='a')
            {
                tmp.h = 7;
                tmp.w = 7;
                color = brown;
            }
            
            if (color)
            {
                if (tmp.x<mx && tmp.x+tmp.w>mx && tmp.y<my && tmp.y+tmp.h>my)
                {
                    arbre.touch();
                    color = red;
                }
                SDL_FillRect(screen,&tmp,color);
            }
            
            arbre.next();
        }
    }
    SDL_Quit();
    return 0;
}
//-----------------------------------------------------------------------------*/
