#include "logique.h"

/***************************
* Partie Tirage des cartes *
****************************/
void tirageInitial(struct CardData cartesJoueur[])
{
    int tirageOK=0,i,j;
    for (i=0 ; i<NOMBRE_CARTES ; i++)
    {
        do
        {
            cartesJoueur[i].ID = nombreAleatoire();
            tirageOK=1;
            for (j=0 ; j<NOMBRE_CARTES ; j++)  // Contre-mesure pour éviter les doublons
            {
                if (cartesJoueur[i].ID == cartesJoueur[j].ID && i != j)
                    tirageOK=0;
            }
        }while (!tirageOK);
        tirageOK=0;
    }
    definirCartes(cartesJoueur); // Calcul des propriétés des cartes
}

void tirageFinal(struct CardData cartesJoueur[], int cartesJetees[])
{
    int tirageOK=0,i,j;
    for (i=0 ; i<NOMBRE_CARTES ; i++)
    {
        if (cartesJoueur[i].statut != 2)
        {
            do
            {
                cartesJoueur[i].ID = nombreAleatoire();
                tirageOK=1;
                for (j=0 ; j<NOMBRE_CARTES ; j++)  // Contre-mesure pour éviter les doublons
                {
                    if ((cartesJoueur[i].ID == cartesJoueur[j].ID || cartesJoueur[i].ID == cartesJetees[j]) && i != j)
                        tirageOK=0;
                }
            }while (!tirageOK);
        }
        tirageOK=0;
        cartesJoueur[i].statut = NORMAL; // Réinitialisation du statut de la carte
    }
    definirCartes(cartesJoueur); // Calcul des propriétés des cartes
}

void definirCartes(struct CardData cartesJoueur[])
{
    int i;
    dictionary *dict; //structure du dictionnaire pour le parseur ini
    dict = iniparser_load("/rd/options.ini"); //ouverture du fichier ini

    if (dict != 0) // Si le dictionnaire est ouvert
    {
        for(i=0 ; i<NOMBRE_CARTES ; i++)
        {
            cartesJoueur[i].numero = cartesJoueur[i].ID % 13; // numéro de la carte
            /** Ce modulo donne un nombre compis entre 0 et 12
                Mais l'identifiant du ROI est 13 celui de l'AS 14
                Donc, ici 0 correspond au roi et 1 à l'AS           **/
            if (cartesJoueur[i].numero == 0)
                cartesJoueur[i].numero = ROI;

            if (cartesJoueur[i].numero == 1)
                cartesJoueur[i].numero = AS;

            // Si jamais le numero d'une carte n'est pas correct, on arrête le programme
            if (cartesJoueur[i].numero < 2 || cartesJoueur[i].numero > AS)
                quit("Tirage des cartes incorrect (ID)");

            cartesJoueur[i].couleur = cartesJoueur[i].ID / 13; //La division par 13 donne des numéros de 0 à 4 (voir header pour le correspondance)
            if (cartesJoueur[i].ID % 13 == 0)       // Si le modulo est égal à 0, on a affaire à un multiple de 13 qui donne un résultat trop grand
                cartesJoueur[i].couleur --;         // donc on décrémente

            // Nom du fichier
            if (cartesJoueur[i].couleur == TREFLE)
                sprintf(cartesJoueur[i].chemin,"/rd/img/%s/trefle_%ld.png",iniparser_getstr(dict,"skin:cartes"),cartesJoueur[i].numero);
            else if (cartesJoueur[i].couleur == PIQUE)
                sprintf(cartesJoueur[i].chemin,"/rd/img/%s/pique_%ld.png",iniparser_getstr(dict,"skin:cartes"),cartesJoueur[i].numero);
            else if (cartesJoueur[i].couleur == CARREAU)
                sprintf(cartesJoueur[i].chemin,"/rd/img/%s/carreau_%ld.png",iniparser_getstr(dict,"skin:cartes"),cartesJoueur[i].numero);
            else if (cartesJoueur[i].couleur == COEUR)
                sprintf(cartesJoueur[i].chemin,"/rd/img/%s/coeur_%ld.png",iniparser_getstr(dict,"skin:cartes"),cartesJoueur[i].numero);
            else // Si se signe n'es pas correct
                quit("Tirage des cartes incorrect (couleur)");
        }
        iniparser_freedict(dict); // Fermeture du dictionnaire
    }
    else{
        quit("Ouverture du fichier ini impossible");
}
}

int nombreAleatoire()
{
    int x=0;
    const int MIN=1,MAX=NOMBRE_ID;
    x = (rand() % (MAX - MIN + 1)) + MIN;
    return x;
}



/*****************************
 * Partie Defition des Gains *
 *****************************/

/**********************************************************************************
 * Cette fonction analyse la donne finale et détermine le gain (si gain il y a)
 * Elle renvoie un int qui correspond au coefficient multiplicateur du pari
 * Des constantes sont définies dans constantes.h pour le retour :
 * PERDU           0
 * PAIRE_TETES     1
 * DEUX_PAIRES     2
 * BRELAN          3
 * COULEUR         4
 * SUITE           6
 * FULL            9
 * CARRE           25
 * SUITE_COULEUR   50
 * SUITE_ROYALE    250
 **********************************************************************************/
int gain(struct CardData cartesJoueur[])
{
    int i, nombre[NOMBRE_CARTES]={0}, nombresTrie[NOMBRE_CARTES]={0}, couleur[NOMBRE_CARTES]={0}, occurences[13]={0}, gain=0;

    // copie les nombres des cartes dans un tableau
    for(i=0 ; i<NOMBRE_CARTES ; i++)
    {
        nombre[i] = cartesJoueur[i].numero;
        couleur[i] = cartesJoueur[i].couleur;
    }

    // range les nombres par ordre croissant dans un autre tableau
    ordonnerTableauCroissant(nombre, nombresTrie);

    // CYCLE DE VERIFICATION
    gain = Flush(nombresTrie, couleur);
    if (!gain)
        gain = nomreOccurences(nombre, occurences);
    if (gain < COULEUR && !tableauTermesEgaux(couleur))
        gain = COULEUR;
    return gain;
}

//Classe le tableau (ordre croissant)
void ordonnerTableauCroissant(int tableau[], int tableauTrie[])
{
    int i,j,valeur,temp[NOMBRE_CARTES]={0};
    for(i=0 ; i<NOMBRE_CARTES ; i++)
    {
        temp[i]=tableau[i];
    }

    //classement par ordre décorissant
    for (i=0 ; i<NOMBRE_CARTES ; i++)
    {
        for (j=0 ; j<NOMBRE_CARTES ; j++)
        {
            if (temp[j]>tableauTrie[NOMBRE_CARTES-1-i]) // Les tableaux commentcent à 0
            {
                tableauTrie[NOMBRE_CARTES-1-i]=temp[j];
                valeur=j;
            }
        }
        temp[valeur] = 0;
    }
}

// Vérifie si tous les termes du tableau sont égaux (renvoie 0 si oui)
int tableauTermesEgaux(int tableau[])
{
    int i, retour=0;
    for(i=0 ; i<NOMBRE_CARTES ; i++)
    {
        if (tableau[i] != tableau[0])
            retour++;
    }
    return retour;
}

// Dit s'il s'agit d'un flush : 0:non, 6:normal, 50:couleur, 250:royal
int Flush(int tableau[], int couleur[])
{
    int isFlush=0,i;

    // Test de la suite
    if (tableau[0] == (tableau[1]-1) && tableau[1] == (tableau[2]-1) && tableau[2] == (tableau[3]-1) && tableau[3] == (tableau[4]-1))
        isFlush=SUITE;

    // Test de la suite de couleur
    if (tableauTermesEgaux(couleur) == 0 && isFlush == SUITE)
        isFlush=SUITE_COULEUR;

    // Test de la suite royale (on vérifie le premier et la dernier tèrme du tableau et aussi si c'est une suite de couleur
    if (tableau[4] == AS && tableau[0] == 10 && isFlush == SUITE_COULEUR)
        isFlush=SUITE_ROYALE;

    return isFlush;
}

int nomreOccurences(int nombre[],int occurences[])
{
    int i,retour=0,nBrelan=0,nPaire=0;
    // référence le nombre d'ocurences de chaque numero
    for(i=0 ; i<5 ; i++)
        occurences[(nombre[i]-2)]++; // Le tableau commence à 0 et las cartes à 2

    for(i=0 ; i<13 ; i++)
    {
        if (occurences[i] == 4) //Test du carré
            retour = CARRE;
        if (occurences[i] == 3) //Incrementation du Brelan
            nBrelan++;
        if (occurences[i] == 2) //Incrementation de la paire
            nPaire++;
    }

    if (nBrelan == 1 && nPaire == 0)    // Test du brelan
        retour = BRELAN;
    if (nBrelan == 1 && nPaire == 1)    // Test du FULL
        retour = FULL;
    if (nPaire == 2)                    // Test de la double paire
        retour = DEUX_PAIRES;
    if (nPaire == 1 && nBrelan == 0)  // Test de la paire de têtes
    {
        if(occurences[VALLET-2] == 2 || occurences[DAME-2] == 2 || occurences[ROI-2] == 2 || occurences[AS-2] == 2)
            retour = PAIRE_TETES;
    }
    return retour;
}

