#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "structures.h"
#include "prototypes.h"




RepertoireDObjets litPov (char nomFichier[])
{
    FILE *fichierALire = NULL, *fichierTemp = NULL;
    char caractereLu = 0, caractereLu2 = 0;
    int i = 0, nbCamera = 0, nbLumiere = 0, nbBackground = 0, nbPlan = 0, nbBox = 0, nbSphere = 0, nbCylindre = 0, nbCone = 0, nbTorus = 0;

    Camera *camera = NULL;
    Lumiere *lumiere = NULL;
    Background *background = NULL;
    Plan *plan = NULL;
    Box *box = NULL;
    Sphere *sphere = NULL;
    Cylindre *cylindre = NULL;
    Cone *cone = NULL;
    Torus *torus = NULL;
    RepertoireDObjets objets;

    fichierALire = fopen(nomFichier, "r");

    if (fichierALire == NULL)
    {
        printf("Nom de fichier invalide\n");
        exit(0);
    }


    fichierTemp = fopen("temp.txt", "w+");

    if (fichierTemp == NULL)
    {
        exit(0);
    }


    caractereLu = fgetc(fichierALire);

	while (caractereLu != EOF)
	{
        if (caractereLu == '/')
        {
            caractereLu2 = fgetc(fichierALire);

            if (caractereLu2 == '/')
            {
                while (caractereLu != '\n' && caractereLu != EOF)
                {
                    caractereLu = fgetc(fichierALire);
                }
            }
            else
            {
                fputc(caractereLu, fichierTemp);
                fputc(caractereLu2, fichierTemp);
            }
        }
        else
        {
            fputc(caractereLu, fichierTemp);
        }

  	    caractereLu = fgetc(fichierALire);
	}

    fclose(fichierALire);

    rewind(fichierTemp);


    nbCamera = compteNBMotCle(fichierTemp, "camera");
    nbLumiere = compteNBMotCle(fichierTemp, "light_source");
    nbBackground = compteNBMotCle(fichierTemp, "background");
    nbPlan = compteNBMotCle(fichierTemp, "plane");
    nbBox = compteNBMotCle(fichierTemp, "box");
    nbSphere = compteNBMotCle(fichierTemp, "sphere");
    nbCylindre = compteNBMotCle(fichierTemp, "cylinder");
    nbCone = compteNBMotCle(fichierTemp, "cone");
    nbTorus = compteNBMotCle(fichierTemp, "torus");

    camera = malloc(nbCamera * sizeof(Camera));
    lumiere = malloc(nbLumiere * sizeof(Lumiere));
    background = malloc(nbBackground * sizeof(Background));
    plan = malloc(nbPlan * sizeof(Plan));
    box = malloc(nbBox * sizeof(Box));
    sphere = malloc(nbSphere * sizeof(Sphere));
    cylindre = malloc(nbCylindre * sizeof(Cylindre));
    cone = malloc(nbCone * sizeof(Cone));
    torus = malloc(nbTorus * sizeof(Torus));

    if (camera == NULL || lumiere == NULL || background == NULL || plan == NULL || box == NULL || sphere == NULL || cylindre == NULL || cone == NULL || torus == NULL)
    {
        exit(0);
    }


    for (i = 0; i < nbCamera; i++)
    {
        camera[i] = litCamera(fichierTemp);
    }
    rewind(fichierTemp);

    for (i = 0; i < nbLumiere; i++)
    {
        lumiere[i] = litLumiere(fichierTemp);
    }
    rewind(fichierTemp);

    for (i = 0; i < nbBackground; i++)
    {
        background[i] = litBackground(fichierTemp);
    }
    rewind(fichierTemp);

    for (i = 0; i < nbPlan; i++)
    {
        plan[i] = litPlan(fichierTemp);
    }
    rewind(fichierTemp);

    for (i = 0; i < nbBox; i++)
    {
        box[i] = litBox(fichierTemp);
    }
    rewind(fichierTemp);

    for (i = 0; i < nbSphere; i++)
    {
        sphere[i] = litSphere(fichierTemp);
    }
    rewind(fichierTemp);

    for (i = 0; i < nbCylindre; i++)
    {
        cylindre[i] = litCylindre(fichierTemp);
    }
    rewind(fichierTemp);

    for (i = 0; i < nbCone; i++)
    {
        cone[i] = litCone(fichierTemp);
    }
    rewind(fichierTemp);

    for (i = 0; i < nbTorus; i++)
    {
        torus[i] = litTorus(fichierTemp);
    }
    rewind(fichierTemp);



    objets.nbCamera = nbCamera;
    objets.nbLumiere = nbLumiere;
    objets.nbBackground = nbBackground;
    objets.nbPlan = nbPlan;
    objets.nbBox = nbBox;
    objets.nbSphere = nbSphere;
    objets.nbCylindre = nbCylindre;
    objets.nbCone = nbCone;
    objets.nbTorus = nbTorus;

    objets.camera = camera;
    objets.lumiere = lumiere;
    objets.background = background;
    objets.plan = plan;
    objets.box = box;
    objets.sphere = sphere;
    objets.cylindre = cylindre;
    objets.cone = cone;
    objets.torus = torus;



    fclose(fichierTemp);

    remove("temp.txt");

    /*free(cameraBug);
    free(camera);
    free(lumiere);
    free(background);
    free(plan);
    free(box);
    free(sphere);
    free(cylindre);
    free(cone);
    free(torus);*/

    return objets;
}








Camera litCamera (FILE *fichier)
{
    char caractereLu = 0;
    Camera camera;
    initCam(&camera);


    if (chercheMotCle(fichier, "camera"))
    {
        if (chercheMotCle(fichier, "location"))
        {
            do
            {
                caractereLu = fgetc(fichier);

                if (caractereLu == '<')
                {
                    fscanf(fichier, "%lf , %lf , %lf", &camera.location.x, &camera.location.y, &camera.location.z);
                }

            } while(caractereLu != '>' && caractereLu != EOF);
        }

        if (chercheMotCle(fichier, "look_at"))
        {
            do
            {
                caractereLu = fgetc(fichier);

                if (caractereLu == '<')
                {
                   fscanf(fichier, "%lf , %lf , %lf", &camera.lookAt.x, &camera.lookAt.y, &camera.lookAt.z);
                }

            } while(caractereLu != '>' && caractereLu != EOF);
        }
    }


    return camera;
}


Lumiere litLumiere (FILE *fichier)
{
    char caractereLu = 0;
    double r = 0, g = 0, b = 0;
    Lumiere lumiere;
    initLumiere(&lumiere);


    if (chercheMotCle(fichier, "light_source"))
    {
        do
        {
            caractereLu = fgetc(fichier);

            if (caractereLu == '<')
            {
                fscanf(fichier, "%lf , %lf , %lf", &lumiere.location.x, &lumiere.location.y, &lumiere.location.z);
            }

        } while(caractereLu != '>' && caractereLu != EOF);


        if (chercheMotCle(fichier, "rgb") == 1)
        {
            do
            {
                caractereLu = fgetc(fichier);

                if (caractereLu == '<')
                {
                   fscanf(fichier, "%lf , %lf , %lf", &r, &g, &b);
                }

            } while(caractereLu != '>' && caractereLu != EOF);
        }
    }

    lumiere.couleur.r = (int)(r*255);
    lumiere.couleur.g = (int)(g*255);
    lumiere.couleur.b = (int)(b*255);


    return lumiere;
}


Background litBackground (FILE *fichier)
{
    char caractereLu = 0;
    double r = 0, g = 0, b = 0;
    Background background;
    initBackground(&background);


    if (chercheMotCle(fichier, "background"))
    {
        if (chercheMotCle(fichier, "rgb") == 1)
        {
            do
            {
                caractereLu = fgetc(fichier);

                if (caractereLu == '<')
                {
                   fscanf(fichier, "%lf , %lf , %lf", &r, &g, &b);
                }

            } while(caractereLu != '>' && caractereLu != EOF);
        }
    }

    background.couleur.r = (int)(r*255);
    background.couleur.g = (int)(g*255);
    background.couleur.b = (int)(b*255);


    return background;
}




Plan litPlan (FILE *fichier)
{
    char caractereLu = 0;
    int boucleFinie = 0;
    double r = 0, g = 0, b = 0;
    Plan plan;
    initPlan(&plan);


    if (chercheMotCle(fichier, "plane"))
    {
        do
        {
            caractereLu = fgetc(fichier);

            if (caractereLu == '<')
            {
                fscanf(fichier, "%lf , %lf , %lf", &plan.vecteurNormal.x, &plan.vecteurNormal.y, &plan.vecteurNormal.z);
            }
            else if (caractereLu == 'x')
            {
                plan.vecteurNormal.x = 1.0;
                plan.vecteurNormal.y = 0.0;
                plan.vecteurNormal.z = 0.0;
                boucleFinie = 1;
            }
            else if (caractereLu == 'y')
            {
                plan.vecteurNormal.x = 0.0;
                plan.vecteurNormal.y = 1.0;
                plan.vecteurNormal.z = 0.0;
                boucleFinie = 1;
            }
            else if (caractereLu == 'z')
            {
                plan.vecteurNormal.x = 0.0;
                plan.vecteurNormal.y = 0.0;
                plan.vecteurNormal.z = 1.0;
                boucleFinie = 1;
            }

        } while(caractereLu != '>' && !boucleFinie && caractereLu != EOF);

        fscanf(fichier, " %lf", &plan.hauteur);
        fscanf(fichier, " , %lf", &plan.hauteur);


        if (chercheMotCle(fichier, "rgb") == 1)
        {
            do
            {
                caractereLu = fgetc(fichier);

                if (caractereLu == '<')
                {
                   fscanf(fichier, "%lf , %lf , %lf", &r, &g, &b);
                }

            } while(caractereLu != '>' && caractereLu != EOF);
        }
    }

    plan.couleur.r = (int)(r*255);
    plan.couleur.g = (int)(g*255);
    plan.couleur.b = (int)(b*255);


    return plan;
}


Box litBox (FILE *fichier)
{
    char caractereLu = 0;
    double r = 0, g = 0, b = 0;
    Box box;
    initBox(&box);


    if (chercheMotCle(fichier, "box"))
    {
        do
        {
            caractereLu = fgetc(fichier);

            if (caractereLu == '<')
            {
                fscanf(fichier, "%lf , %lf , %lf", &box.point1.x, &box.point1.y, &box.point1.z);
            }

        } while(caractereLu != '>' && caractereLu != EOF);

        do
        {
            caractereLu = fgetc(fichier);

            if (caractereLu == '<')
            {
                fscanf(fichier, "%lf , %lf , %lf", &box.point2.x, &box.point2.y, &box.point2.z);
            }

        } while(caractereLu != '>' && caractereLu != EOF);


        if (chercheMotCle(fichier, "rgb") == 1)
        {
            do
            {
                caractereLu = fgetc(fichier);

                if (caractereLu == '<')
                {
                   fscanf(fichier, "%lf , %lf , %lf", &r, &g, &b);
                }

            } while(caractereLu != '>' && caractereLu != EOF);
        }
    }

    box.couleur.r = (int)(r*255);
    box.couleur.g = (int)(g*255);
    box.couleur.b = (int)(b*255);


    return box;
}


Sphere litSphere (FILE *fichier)
{
    char caractereLu = 0;
    double r = 0, g = 0, b = 0;
    Sphere sphere;
    initSphere(&sphere);


    if (chercheMotCle(fichier, "sphere"))
    {
        do
        {
            caractereLu = fgetc(fichier);

            if (caractereLu == '<')
            {
                fscanf(fichier, "%lf , %lf , %lf", &sphere.centre.x, &sphere.centre.y, &sphere.centre.z);
            }

        } while(caractereLu != '>' && caractereLu != EOF);


        fscanf(fichier, " %lf", &sphere.rayon);
        fscanf(fichier, " , %lf", &sphere.rayon);


        if (chercheMotCle(fichier, "rgb") == 1)
        {
            do
            {
                caractereLu = fgetc(fichier);

                if (caractereLu == '<')
                {
                   fscanf(fichier, "%lf , %lf , %lf", &r, &g, &b);
                }

            } while(caractereLu != '>' && caractereLu != EOF);
        }
    }

    sphere.couleur.r = (int)(r*255);
    sphere.couleur.g = (int)(g*255);
    sphere.couleur.b = (int)(b*255);


    return sphere;
}



Cylindre litCylindre (FILE *fichier)
{
    char caractereLu = 0;
    double r = 0, g = 0, b = 0;
    Cylindre cylindre;
    initCylindre(&cylindre);


    if (chercheMotCle(fichier, "cylinder"))
    {
        do
        {
            caractereLu = fgetc(fichier);

            if (caractereLu == '<')
            {
                fscanf(fichier, "%lf , %lf , %lf", &cylindre.centre1.x, &cylindre.centre1.y, &cylindre.centre1.z);
            }

        } while(caractereLu != '>' && caractereLu != EOF);


        do
        {
            caractereLu = fgetc(fichier);

            if (caractereLu == '<')
            {
                fscanf(fichier, "%lf , %lf , %lf", &cylindre.centre2.x, &cylindre.centre2.y, &cylindre.centre2.z);
            }

        } while(caractereLu != '>' && caractereLu != EOF);


        fscanf(fichier, " %lf", &cylindre.rayon);
        fscanf(fichier, " , %lf", &cylindre.rayon);


        if (chercheMotCle(fichier, "rgb") == 1)
        {
            do
            {
                caractereLu = fgetc(fichier);

                if (caractereLu == '<')
                {
                   fscanf(fichier, "%lf , %lf , %lf", &r, &g, &b);
                }

            } while(caractereLu != '>' && caractereLu != EOF);
        }
    }

    cylindre.couleur.r = (int)(r*255);
    cylindre.couleur.g = (int)(g*255);
    cylindre.couleur.b = (int)(b*255);


    return cylindre;
}



Cone litCone (FILE *fichier)
{
    char caractereLu = 0;
    double r = 0, g = 0, b = 0;
    Cone cone;
    initCone(&cone);


    if (chercheMotCle(fichier, "cone"))
    {
        do
        {
            caractereLu = fgetc(fichier);

            if (caractereLu == '<')
            {
                fscanf(fichier, "%lf , %lf , %lf", &cone.centre1.x, &cone.centre1.y, &cone.centre1.z);
            }

        } while(caractereLu != '>' && caractereLu != EOF);


        fscanf(fichier, " %lf", &cone.rayon1);
        fscanf(fichier, " , %lf", &cone.rayon1);


        do
        {
            caractereLu = fgetc(fichier);

            if (caractereLu == '<')
            {
                fscanf(fichier, "%lf , %lf , %lf", &cone.centre2.x, &cone.centre2.y, &cone.centre2.z);
            }

        } while(caractereLu != '>' && caractereLu != EOF);

        fscanf(fichier, " %lf", &cone.rayon2);
        fscanf(fichier, " , %lf", &cone.rayon2);


        if (chercheMotCle(fichier, "rgb") == 1)
        {
            do
            {
                caractereLu = fgetc(fichier);

                if (caractereLu == '<')
                {
                   fscanf(fichier, "%lf , %lf , %lf", &r, &g, &b);
                }

            } while(caractereLu != '>' && caractereLu != EOF);
        }
    }

    cone.couleur.r = (int)(r*255);
    cone.couleur.g = (int)(g*255);
    cone.couleur.b = (int)(b*255);


    return cone;
}



Torus litTorus (FILE *fichier)
{
    char caractereLu = 0;
    double r = 0, g = 0, b = 0;
    Torus torus;
    initTorus(&torus);


    if (chercheMotCle(fichier, "torus"))
    {
        do
        {
            caractereLu = fgetc(fichier);

        } while(caractereLu != '{' && caractereLu != EOF);


        fscanf(fichier, " %lf", &torus.rayon1);


        fscanf(fichier, " %lf", &torus.rayon2);
        fscanf(fichier, " , %lf", &torus.rayon2);


        if (chercheMotCle(fichier, "rgb") == 1)
        {
            do
            {
                caractereLu = fgetc(fichier);

                if (caractereLu == '<')
                {
                   fscanf(fichier, "%lf , %lf , %lf", &r, &g, &b);
                }

            } while(caractereLu != '>' && caractereLu != EOF);
        }
    }

    torus.couleur.r = (int)(r*255);
    torus.couleur.g = (int)(g*255);
    torus.couleur.b = (int)(b*255);


    return torus;
}





int chercheMotCle (FILE *fichier, char motCle[])
{
    char caractereLu = 0;
    int findMotCle = 0;
    int i = 0, longueurMotCle, estSorti = 0;

    longueurMotCle = strlen(motCle);

    do
    {
        caractereLu = fgetc(fichier);

        if (caractereLu == motCle[i])
        {
            i++;
        }
        else
        {
            i = 0;

	    if (caractereLu == '}')
	    {
		estSorti = 1;
	    }
        }


        if (i == longueurMotCle)
        {
            findMotCle = 1;
            i = 0;
        }

    } while(caractereLu != EOF && !findMotCle);


    if (findMotCle)
    {
	if (estSorti)
	{
	    return 2;
	}
	else
	{
	    return 1;
	}
    }
    else
    {
	return 0;
    }
}


int compteNBMotCle (FILE *fichier, char motCle[])
{
    int compteur = 0;

    while (chercheMotCle(fichier, motCle))
    {
        compteur++;
    }

    rewind(fichier);

    return compteur;
}








