/*=============================================================================
Exemple SDL
===============================================================================
Preprocesseur
=============================================================================*/
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_gfxPrimitives.h"
#include "SDL/SDL_rotozoom.h"


#include "fractal.hpp"
#include "shadow.hpp"

#include <fstream>
#include <iostream>

#define gw 600
#define gh 400

using namespace std;

/*=============================================================================
procedure
=============================================================================*/

void put_pixel32( SDL_Surface *surface, int x, int y, Uint32 pixel ) 
{ 
    //Convert the pixels to 32 bit 
    Uint32 *pixels = (Uint32 *)surface->pixels; 
    //Set the pixel 
    pixels[ ( y * surface->w ) + x ] = pixel; 
}

Uint32 get_pixel32( SDL_Surface *surface, int x, int y ) 
{ 
    //Convert the pixels to 32 bit 
    Uint32 *pixels = (Uint32 *)surface->pixels; 
    //Get the requested pixel 
    return pixels[ ( y * surface->w ) + x ]; 
} 

SDL_Surface * load_image(const char * filename)
{
    SDL_Surface* Surf_Temp = NULL;
    SDL_Surface* Surf_Return = NULL;
 
    Surf_Temp = IMG_Load(filename);
    
    if(Surf_Temp == NULL) {
        cout << "error loading : " << filename << endl;
        return NULL;
    }
 
    Surf_Return = SDL_DisplayFormatAlpha(Surf_Temp);
    SDL_FreeSurface(Surf_Temp);
 
    return Surf_Return;
}

/*=============================================================================
programme principal
=============================================================================*/

int main(int argc, char * argv[])
{
    //================================================larbre
	string line = "{o:a[+ao]-ao;}ao";
	
	//=================================================init
	//voici l'ombre
    shadoverlay shadow;
    shadow.init(gw,gh);
    //shadow.setSunV(sin(1),cos(1));
    //ombre

    SDL_Init(SDL_INIT_EVERYTHING);
    SDL_Surface *screen = SDL_SetVideoMode(gw, gh, 32, SDL_SWSURFACE);
    SDL_Event event;
    IMG_Init(IMG_INIT_PNG);

    SDL_Surface * nightBG = load_image("./art/PP_Night_Sky.png"),
                * dayBG = load_image("./art/PP_Day_Sky.png");

    int keypress = 0,
        mx = 0,
        my = 0;
        
    Uint32 brown = SDL_MapRGBA( screen->format, 0x66, 0x33, 0x00, 0xFF ),
           red = SDL_MapRGB( screen->format, 0xFF, 0x00, 0x00 ),
           black = SDL_MapRGBA( screen->format, 0x00, 0x00, 0x00, 0xFF ),
           blue = SDL_MapRGBA( screen->format, 0x00, 0x00, 0xFF, 0xFF ),
           green = SDL_MapRGB( screen->format, 0x00, 0xFF, 0x00 ),
           yellow = SDL_MapRGB( screen->format, 0xFF, 0xFF, 0x00 ),
           orange = SDL_MapRGB( screen->format, 0xFF, 0x80, 0x00 );
           
    //prepousser l'arbre
    fractal arbre(line,300,300);
    arbre.grow();
    arbre.grow();
    arbre.grow();
    arbre.print();

    //==================================================main loop
    while(!keypress)
    {
        SDL_Flip(screen);
        
        //--------------------------------------------arriere plan
        //SDL_FillRect(screen,0,0);
        //ombre
        shadow.reset();
        while (!shadow.end())
        {
            if (shadow.here())
                //put_pixel32(screen,shadow.x(), shadow.y(),black);
                put_pixel32(screen,shadow.x(), shadow.y(),get_pixel32(nightBG,shadow.x(), shadow.y()));
            else
                //put_pixel32(screen,shadow.x(), shadow.y(),blue);
                put_pixel32(screen,shadow.x(), shadow.y(),get_pixel32(dayBG,shadow.x(), shadow.y()));
            shadow.next();
        }
        shadow.clear();
        //ombre

        //-------------------------------------------controle utilisateur
        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;
            }
        }
        

        
        //------------------------------------------dessiner l'arbre
        arbre.reset();
        while (!arbre.end())
        {
            arbre.parse();
            Uint32 color = 0;
            SDL_Rect tmp = {arbre.position().x(), arbre.position().y()-1, 0, 0};
            if (arbre.get()=='o')   //feuille
            {
                tmp.x -= 20;
                tmp.y -= 20;
                tmp.h = 40;
                tmp.w = 40;
                //les feuilles dépendent de l'ombre
                //ici j'utilise le canvas d'ombre du frame d'avant
                //ce qui me permet de mettre à jours l'ombre dans la meme passe
                //de tortue
                if (shadow.getOld(tmp.x,tmp.y) && shadow.getOld(tmp.x+tmp.w, tmp.y))
                    color = green;
                else if(shadow.getOld(tmp.x,tmp.y) || shadow.getOld(tmp.x+tmp.w, tmp.y))
                    color = orange;
                else
                    color = yellow;
                
            }
            else if (arbre.get()=='a')  //branche
            {
                tmp.x -= 4;
                tmp.y -= 4;
                tmp.h = 8;
                tmp.w = 8;
                color = brown;
                
            }
            
            //ombre
                shadow.polarPlot(arbre.position().x(),
                                 arbre.position().y(),
                                 arbre.position().rad(),
                                 arbre.position().len()+1);
            //ombre
            
            //detection de souris sur zone
            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();
        }
        //fin d'arbre
    }
    //fin de loop
    IMG_Quit();
    SDL_Quit();
    return 0;
}
