#include "Objet.h"



char* scan(char* chaine, char* chaine2);
void decalage(char* cmot);

Camera* par_camera(char* texte);
Source* par_source(char* texte);
Background* par_background(char* texte);
Sphere* par_sphere(char* texte);
Cube* par_cube(char* texte);
int recherche(char* word, char* texte);



int main()
{
    Camera* camera1;
    Source* source1;
    Background* background1;
    Sphere* sphere1;
    Cube* cube1;

    FILE* fichier = NULL;
    fichier = fopen("test.pov", "r");       //NOM DU FICHIER DE TEST
    char chaine[TAILLE_MAX] = "";
    char chaine2[TAILLE_MAX2] = "";
    int i = 1;
    char caract_suivant = ' ';
    chaine2[0] = ' ';

    if (fichier != NULL)
    {
        int caract = fgetc(fichier);


        while (caract != EOF)
        {
            if(isspace(caract) != 0)
            {
                chaine2[i] = ' ';
                i++;
                while(isspace(caract) != 0)
                {
                    caract = fgetc(fichier);
                }
            }
            else
            {
                if(caract == '/')
                {
                    fgets(chaine, TAILLE_MAX, fichier);
                    caract = fgetc(fichier);
                }
                else
                {
                    if(caract == '#')
                    {
                        caract_suivant = fgetc(fichier);
                        if(caract_suivant == 'i')
                        {
                                fgets(chaine, TAILLE_MAX, fichier);
                                caract = fgetc(fichier);
                        }
                        else
                        {
                            chaine2[i] = caract;
                            chaine2[i+1] = caract_suivant;
                            i=i+2;
                            caract = fgetc(fichier);
                        }
                    }
                    else
                    {
                        chaine2[i] = caract;
                        i++;
                        caract = fgetc(fichier);
                    }
                }
            }
        }


    }
    else
    {
        printf("pas de fichier trouvé!");
        return 0;
    }

    char* resultat;
    resultat = scan("camera",chaine2);
    if(resultat==NULL)
    {
        printf("Ce fichier ne contient pas les données pour le traitement de la caméra.");
        fclose(fichier);
        return 0;
    }
    else
    {
        camera1 = par_camera(resultat);
    }

    printf("les parametres de la camera sont:\n");
    printf("Position: X=%f Y=%f Z=%f \n",(*camera1).pos.x ,(*camera1).pos.y, (*camera1).pos.z);
    printf("look at : X=%f Y=%f Z=%f \n",(*camera1).look.x ,(*camera1).look.y, (*camera1).look.z);
    puts("");


    resultat = scan("light_source",chaine2);
    if(resultat==NULL)
    {
        printf("Ce fichier ne contient pas les données pour le traitement de la source.");
        fclose(fichier);
        return 0;
    }
    else
    {
        source1 = par_source(resultat);
    }

    printf("les parametres de la source sont:\n");
    printf("Position: X=%f Y=%f Z=%f \n",(*source1).pos.x ,(*source1).pos.y, (*source1).pos.z);
    printf("couleur : R=%f G=%f B=%f \n",(*source1).color.r ,(*source1).color.g, (*source1).color.b);
    puts("");



    resultat = scan("background",chaine2);
    if(resultat==NULL)
    {
        printf("Ce fichier ne contient pas les données pour traitement du background.");
        fclose(fichier);
        return 0;
    }
    else
    {
        background1 = par_background(resultat);
    }

    printf("les parametres du background sont:\n");
    printf("couleur : R=%f G=%f B=%f \n",(*background1).color.r ,(*background1).color.g, (*background1).color.b);
    puts("");

    resultat = scan("sphere",chaine2);
    if(resultat==NULL)
    {
        printf("Ce fichier ne contient pas les données pour le traitement de la sphere.");
        fclose(fichier);
        return 0;
    }
    else
    {
        sphere1 = par_sphere(resultat);
    }

    printf("les parametres de la sphere sont:\n");
    printf("Centre: X=%f Y=%f Z=%f \n",(*sphere1).centre.x ,(*sphere1).centre.y, (*sphere1).centre.z);
    printf("Rayon : %f \n",(*sphere1).rayon);
    printf("Couleur: R=%f G=%f B=%f \n",(*sphere1).couleur.r ,(*sphere1).couleur.g, (*sphere1).couleur.b );
    puts("");



    resultat = scan("box",chaine2);
    if(resultat==NULL)
    {
        printf("Ce fichier ne contient pas les données pour le traitement du cube.");
        fclose(fichier);
        return 0;
    }
    else
    {
        cube1 = par_cube(resultat);
    }

    printf("les parametres du cube sont:\n");
    printf("Premier point: X=%f Y=%f Z=%f \n",(*cube1).p1.x ,(*cube1).p1.y, (*cube1).p1.z);
    printf("Second point: X=%f Y=%f Z=%f \n",(*cube1).p2.x ,(*cube1).p2.y, (*cube1).p2.z);
    printf("Couleur: R=%f G=%f B=%f \n",(*cube1).couleur.r ,(*cube1).couleur.g, (*cube1).couleur.b );
    puts("");
    fclose(fichier);

    return 0;
}

char* scan(char* chaine,char* chaine2)
{
    char *word = (char*) malloc( strlen(chaine) * sizeof(char)+1 );
    char * texte = (char *) malloc(sizeof(char) * (TAILLE+1));
    *texte = '\0';
    int a = 0;
    int i = 0;
    int j = 0;
    for(j=0;j<strlen(chaine);j++)
    {
        word[j] = 'a';
    }
    word[j]='\0';

    for(i=0;i<strlen(chaine2);i++)
    {
        if(a==strlen(chaine)-1)
        {
            decalage(word);
        }
        else
        {
            a++;
        }
        word[a] = chaine2[i];

        if(strcmp(chaine,word)==0)
        {
            j=0;
            while(chaine2[i] != '}')
            {
                texte[j] = chaine2[i];
                j++;
                i++;
            }
            return texte;
        }
    }

    return NULL;
}

void decalage(char* cmot )                  //decale la chaine d'une case vers la droite
{
    int i = 1;
    for(i=1;i<strlen(cmot);i++)
    {
        cmot[i-1]=cmot[i];
    }
}

Camera* par_camera(char* texte)             //parsage de la caméra
{
    int position_look=recherche("look_at",texte);
    int position_locat=recherche("location",texte);
    int nbr_virgule = 0;
    int i = 0;
    Camera* camera1 = malloc( sizeof(struct Camera) );
    char valeur[TAILLE2] = "";
    valeur[TAILLE2-1] = '\0';

    float x, y, z;

    if(position_look==0 || position_locat==0)
    {
        printf("Pas de données pour la camera");
        return;
    }
    else
    {
        while(texte[position_locat]!='>' && texte[position_locat] !='\0')
        {
            if(texte[position_locat]!=',' && texte[position_locat]!=' ' && texte[position_locat]!='<' && texte[position_locat]!='{')
            {
                switch(nbr_virgule)
                {
                    case 0 :    while(texte[position_locat] !=',' )
                                {
                                    valeur[i] = texte[position_locat];
                                    position_locat++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                x = atof(valeur);
                                i=0;
                                break;

                    case 1 :    while(texte[position_locat] !=',' && texte[position_locat] !='>')
                                {
                                    valeur[i] = texte[position_locat];
                                    position_locat++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                y = atof(valeur);
                                i=0;
                                break;

                    case 2 :    while(texte[position_locat] !=',' && texte[position_locat] !='>')
                                {
                                    valeur[i] = texte[position_locat];
                                    position_locat++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                z = atof(valeur);
                                i=0;
                                nbr_virgule=0;
                                break;
                    default : position_locat++; break;
                }
            }
            else
            {
                position_locat++;
            }
        }

        (*camera1).pos.x = x;
        (*camera1).pos.y = y;
        (*camera1).pos.z = z;

        x=y=z=0;

        while(texte[position_look]!='>' && texte[position_look] !='\0')
        {
            if(texte[position_look]!=',' && texte[position_look]!=' '  && texte[position_look]!='<' && texte[position_look]!='{')
            {
                switch(nbr_virgule)
                {
                    case 0 :    while(texte[position_look] !=',' && texte[position_look] !='>')
                                {
                                    valeur[i] = texte[position_look];
                                    position_look++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                x = atof(valeur);
                                i=0;
                                break;

                    case 1 :    while(texte[position_look] !=',' && texte[position_look] !='>')
                                {
                                    valeur[i] = texte[position_look];
                                    position_look++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                y = atof(valeur);
                                i=0;
                                break;

                    case 2 :    while(texte[position_look] !=',' && texte[position_look] !='>')
                                {
                                    valeur[i] = texte[position_look];
                                    position_look++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                z = atof(valeur);
                                i=0;
                                nbr_virgule=0;
                                break;
                    default : position_look++; break;
                }
            }
            else
            {
                position_look++;
            }
        }

        (*camera1).look.x = x;
        (*camera1).look.y = y;
        (*camera1).look.z = z;
        //printf("x=%f y=%f z=%f",x,y,z);
    }
    return camera1;
}

Source* par_source(char* texte)             //parsage de la source
{

    int position_rgb=recherche("rgb",texte);
    int nbr_virgule = 0;
    int i = 0;
    int a = 3;
    Source* source1 = malloc( sizeof(struct Source) );
    char valeur[TAILLE2] = "";
    valeur[TAILLE2-1] = '\0';

    float x, y, z;

    while(texte[a]!='>' && texte[a]!='\0')
    {
        if(texte[a]!=',' && texte[a]!=' ' && texte[a] !='<' && texte[a] !='{')
        {
            switch(nbr_virgule)
            {
                case 0 : while(texte[a] !=',' && texte[a] !='>')
                         {
                             valeur[i] = texte[a];
                             a++;
                             i++;
                         }
                         nbr_virgule++;
                         valeur[i] = '\0';
                         x = atof(valeur);
                         i=0;
                         break;
                case 1 : while(texte[a] !=',' && texte[a] !='>')
                         {
                             valeur[i] = texte[a];
                             a++;
                             i++;
                         }
                         nbr_virgule++;
                         valeur[i] = '\0';
                         y = atof(valeur);
                         i=0;
                         break;
                case 2 : while(texte[a] !=',' && texte[a] !='>')
                         {
                             valeur[i] = texte[a];
                             a++;
                             i++;
                         }
                         nbr_virgule++;
                         valeur[i] = '\0';
                         z = atof(valeur);
                         i=0;
                         break;
                default : a++; break;
            }
        }
        else
        {
            a++;
        }
    }

    (*source1).pos.x = x;
    (*source1).pos.y = y;
    (*source1).pos.z = z;


    if(position_rgb==0)
    {
        printf("Pas de données pour la source");
        return;
    }
    else
    {
        nbr_virgule=0;
        i=0;
        position_rgb=position_rgb+3;
        while(texte[position_rgb]!='>' && texte[position_rgb] !='\0')
        {
            if(texte[position_rgb]!=',' && texte[position_rgb]!=' ' && texte[position_rgb]!='<' && texte[position_rgb]!='{')
            {
                switch(nbr_virgule)
                {
                    case 0 :    while(texte[position_rgb] !=',' && texte[position_rgb] !='>')
                                {
                                    valeur[i] = texte[position_rgb];
                                    position_rgb++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                x = atof(valeur);
                                i=0;
                                break;

                    case 1 :    while(texte[position_rgb] !=',' && texte[position_rgb] !='>')
                                {
                                    valeur[i] = texte[position_rgb];
                                    position_rgb++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                y = atof(valeur);
                                i=0;
                                break;

                    case 2 :    while(texte[position_rgb] !=',' && texte[position_rgb] !='>')
                                {
                                    valeur[i] = texte[position_rgb];
                                    position_rgb++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                z = atof(valeur);
                                i=0;
                                nbr_virgule=0;
                                break;
                    default : position_rgb++; break;
                }
            }
            else
            {
                position_rgb++;
            }
        }

        (*source1).color.r = x;
        (*source1).color.g = y;
        (*source1).color.b = z;
    }

    return source1;

}

Background* par_background(char* texte)     //parsage du background
{
    int position_rgb=recherche("rgb",texte)+1;
    int nbr_virgule = 0;
    int i = 0;
    int a = 0;
    Background* background1 = malloc( sizeof(struct Background) );;
    char valeur[TAILLE2] = "";
    valeur[TAILLE2-1] = '\0';

    float x, y, z;

    if(position_rgb==0)
    {
        printf("Pas de données pour le background");
        return;
    }
    else
    {
        nbr_virgule=0;
        i=0;
        while(texte[position_rgb]!='>' && texte[position_rgb] !='\0')
        {
            if(texte[position_rgb]!=',' && texte[position_rgb]!=' ' && texte[position_rgb]!='<' && texte[position_rgb]!='{')
            {
                switch(nbr_virgule)
                {
                    case 0 :    while(texte[position_rgb] !=',' && texte[position_rgb] !='>')
                                {
                                    valeur[i] = texte[position_rgb];
                                    position_rgb++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                x = atof(valeur);
                                i=0;
                                break;

                    case 1 :    while(texte[position_rgb] !=',' && texte[position_rgb] !='>')
                                {
                                    valeur[i] = texte[position_rgb];
                                    position_rgb++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                y = atof(valeur);
                                i=0;
                                break;

                    case 2 :    while(texte[position_rgb] !=',' && texte[position_rgb] !='>')
                                {
                                    valeur[i] = texte[position_rgb];
                                    position_rgb++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                z = atof(valeur);
                                i=0;
                                nbr_virgule=0;
                                break;
                    default : position_rgb++; break;
                }
            }
            else
            {
                position_rgb++;
            }
        }

        (*background1).color.r = x;
        (*background1).color.g = y;
        (*background1).color.b = z;

    }
    return background1;
}

Sphere* par_sphere(char* texte)             //parsage de la sphere
{
    int position_point=recherche("<",texte);
    int position_rayon=recherche(">",texte);
    int position_pigment=recherche("pigment",texte)-7;
    int position_rgb=recherche("rgb",texte);
    int nbr_virgule = 0;
    int i = 0;
    Sphere* sphere1 = malloc( sizeof(struct Sphere) );
    (*sphere1).texture.r = 0;
    (*sphere1).texture.g = 0;
    (*sphere1).texture.b = 0;
    char valeur[TAILLE2] = "";
    valeur[TAILLE2-1] = '\0';

    float x, y, z;

    if(position_point==0 || position_rayon==0)
    {
        printf("pas de données pour le sphere");
        return;
    }
    else
    {
        while(texte[position_point]!='>' && texte[position_point] !='\0')
        {
            if(texte[position_point]!=',' && texte[position_point]!=' ' && texte[position_point]!='<' && texte[position_point]!='{')
            {
                switch(nbr_virgule)
                {
                    case 0 :    while(texte[position_point] !=',' && texte[position_point] !='>')
                                {
                                    valeur[i] = texte[position_point];
                                    position_point++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                x = atof(valeur);
                                i=0;
                                break;

                    case 1 :    while(texte[position_point] !=',' && texte[position_point] !='>')
                                {
                                    valeur[i] = texte[position_point];
                                    position_point++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                y = atof(valeur);
                                i=0;
                                break;

                    case 2 :    while(texte[position_point] !=',' && texte[position_point] !='>')
                                {
                                    valeur[i] = texte[position_point];
                                    position_point++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                z = atof(valeur);
                                i=0;
                                nbr_virgule=0;
                                break;
                    default : position_point++; break;
                }
            }
            else
            {
                position_point++;
            }
        }

        (*sphere1).centre.x = x;
        (*sphere1).centre.y = y;
        (*sphere1).centre.z = z;

        nbr_virgule=0;
        i=0;

        while(position_rayon != position_pigment)
        {
            if(texte[position_rayon] != ' ' && texte[position_rayon] != '\0' && texte[position_rayon]!='<' && texte[position_rayon]!='{' && texte[position_rayon]!='>' && texte[position_rayon] != ',')
            {
                valeur[i] = texte[position_rayon];
                i++;

            }
            position_rayon++;
        }
        valeur[i] = '\0';
        (*sphere1).rayon = atof(valeur);
        i=0;

    }

    if(position_rgb==0)
    {
        x=0;
        y=0;
        z=0;
    }
    else
    {
        while(texte[position_rgb]!='>' && texte[position_rgb] !='\0')
        {
            if(texte[position_rgb]>'/' && texte[position_rgb]<':' || texte[position_rgb]=='-')
            {
                switch(nbr_virgule)
                {
                    case 0 :    while(texte[position_rgb] !=',' && texte[position_rgb] !='>')
                                {
                                    valeur[i] = texte[position_rgb];
                                    position_rgb++;
                                    i++;
                                }

                                nbr_virgule++;
                                valeur[i] = '\0';
                                x = atof(valeur);
                                i=0;
                                break;

                    case 1 :    while(texte[position_rgb] !=',' && texte[position_rgb] !='>')
                                {
                                    valeur[i] = texte[position_rgb];
                                    position_rgb++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                y = atof(valeur);
                                i=0;
                                break;

                    case 2 :    while(texte[position_rgb] !=',' && texte[position_rgb] !='>')
                                {
                                    valeur[i] = texte[position_rgb];
                                    position_rgb++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                z = atof(valeur);
                                i=0;
                                nbr_virgule=0;
                                break;
                    default : position_rgb++; break;
                }
            }
            else
            {
                position_rgb++;
            }
        }
    }

    (*sphere1).couleur.r = x;
    (*sphere1).couleur.g = y;
    (*sphere1).couleur.b = z;

    return sphere1;
}

Cube* par_cube (char* texte)                //parsage d'un cube
{
    int position_first=recherche("<",texte);
    int position_last=recherche(">",texte);
    int position_rgb=recherche("rgb",texte);
    int nbr_virgule = 0;
    int i = 0;
    Cube* cube1 = malloc( sizeof(struct Cube) );;
    char valeur[TAILLE2] = "";
    valeur[TAILLE2-1] = '\0';

    float x, y, z;

    if(position_first==0 || position_last==0)
    {
        printf("Pas de données pour le cube");
        return;
    }
    else
    {
        while(texte[position_first]!='>' && texte[position_first] !='\0')
        {
            if(texte[position_first]!=',' && texte[position_first]!=' ' && texte[position_first]!='<' && texte[position_first]!='{')
            {
                switch(nbr_virgule)
                {
                    case 0 :    while(texte[position_first] !=',' && texte[position_first] !='>')
                                {
                                    valeur[i] = texte[position_first];
                                    position_first++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                x = atof(valeur);
                                i=0;
                                break;

                    case 1 :    while(texte[position_first] !=',' && texte[position_first] !='>')
                                {
                                    valeur[i] = texte[position_first];
                                    position_first++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                y = atof(valeur);
                                i=0;
                                break;

                    case 2 :    while(texte[position_first] !=',' && texte[position_first] !='>')
                                {
                                    valeur[i] = texte[position_first];
                                    position_first++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                z = atof(valeur);
                                i=0;
                                nbr_virgule=0;
                                break;
                    default : position_first++; break;
                }
            }
            else
            {
                position_first++;
            }
        }

        (*cube1).p1.x = x;
        (*cube1).p1.y = y;
        (*cube1).p1.z = z;


        int iflag=0;
        while(iflag==0)
        {
            if(texte[position_last]>'/' && texte[position_last]<':' || texte[position_last]=='-')
            {
                switch(nbr_virgule)
                {
                    case 0 :    while(texte[position_last] !=',' && texte[position_last] !='>')
                                {
                                    valeur[i] = texte[position_last];
                                    position_last++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                x = atof(valeur);
                                i=0;
                                break;

                    case 1 :    while(texte[position_last] !=',' && texte[position_last] !='>')
                                {
                                    valeur[i] = texte[position_last];
                                    position_last++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                y = atof(valeur);
                                i=0;
                                break;

                    case 2 :    while(texte[position_last] !=',' && texte[position_last] !='>')
                                {
                                    valeur[i] = texte[position_last];
                                    position_last++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                z = atof(valeur);
                                i=0;
                                nbr_virgule=0;
                                iflag=1;
                                break;
                    default : position_last++; break;
                }
            }
            else
            {
                position_last++;
            }

        }

        (*cube1).p2.x = x;
        (*cube1).p2.y = y;
        (*cube1).p2.z = z;
    }

    if(position_rgb==0)
    {
        x=0;
        y=0;
        z=0;
    }
    else
    {
        while(texte[position_rgb]!='>' && texte[position_rgb] !='\0')
        {
            if(texte[position_rgb]!=',' && texte[position_rgb]!=' ' && texte[position_rgb]!='<' && texte[position_rgb]!='{')
            {
                switch(nbr_virgule)
                {
                    case 0 :    while(texte[position_rgb] !=',' && texte[position_rgb] !='>')
                                {
                                    valeur[i] = texte[position_rgb];
                                    position_rgb++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                x = atof(valeur);
                                i=0;
                                break;

                    case 1 :    while(texte[position_rgb] !=',' && texte[position_rgb] !='>')
                                {
                                    valeur[i] = texte[position_rgb];
                                    position_rgb++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                y = atof(valeur);
                                i=0;
                                break;

                    case 2 :    while(texte[position_rgb] !=',' && texte[position_rgb] !='>')
                                {
                                    valeur[i] = texte[position_rgb];
                                    position_rgb++;
                                    i++;
                                }
                                nbr_virgule++;
                                valeur[i] = '\0';
                                z = atof(valeur);
                                i=0;
                                nbr_virgule=0;
                                break;
                    default : position_rgb++; break;
                }
            }
            else
            {
                position_rgb++;
            }
        }
    }

    (*cube1).couleur.r = x;
    (*cube1).couleur.g = y;
    (*cube1).couleur.b = z;

    return cube1;
}

int recherche(char* word, char* texte)      //recherche d'un mot dans une chaine et renvoi
{
    char *c = (char*) malloc( strlen(word) * sizeof(char)+1 );
    int a = 0;
    int i = 0;

    for(i=0;i<strlen(word);i++)
    {
        c[i] = 'a';
    }
    c[i]='\0';

    for(i=0;i<strlen(texte);i++)
    {
        if(a==strlen(word)-1)
        {
            decalage(c);
        }
        else
        {
            a++;
        }
        c[a] = texte[i];

        if(strcmp(word,c)==0)
        {
            return i;
        }
    }
    return 0;
}
