#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <fstream>

//#include "structure.h"
#include "Buchele-Thebault-A.h"
using namespace std;

void ecritureAF(pcube f, int index)
{
	if(f == NULL)return;
	if(index ==0)
	{
		ofstream fichier("Buchele-Thebault-output.txt", ios::out | ios::trunc);  // ouverture en écriture avec effacement du fichier ouvert
		char donnee[50]; sprintf(donnee,"Etats Fermes\nValeur heuristique %d - Cout %d\n",f->heuristique, f->cost);
		char faceUne[9]; sprintf(faceUne,"%d%d%d%d%d%d%d%d%d",f->face[0]->cases[0][0],f->face[0]->cases[0][1],f->face[0]->cases[0][2],f->face[0]->cases[1][0],f->face[0]->cases[1][1],f->face[0]->cases[1][2],f->face[0]->cases[2][0],f->face[0]->cases[2][1],f->face[0]->cases[2][2]);
		char faceDeux[9]; sprintf(faceDeux,"%d%d%d%d%d%d%d%d%d",f->face[1]->cases[0][0],f->face[1]->cases[0][1],f->face[1]->cases[0][2],f->face[1]->cases[1][0],f->face[1]->cases[1][1],f->face[1]->cases[1][2],f->face[1]->cases[2][0],f->face[1]->cases[2][1],f->face[1]->cases[2][2]);
		char faceTrois[9]; sprintf(faceTrois,"%d%d%d%d%d%d%d%d%d",f->face[2]->cases[0][0],f->face[2]->cases[0][1],f->face[2]->cases[0][2],f->face[2]->cases[1][0],f->face[2]->cases[1][1],f->face[2]->cases[1][2],f->face[2]->cases[2][0],f->face[2]->cases[2][1],f->face[2]->cases[2][2]);
		char faceQuatre[9]; sprintf(faceQuatre,"%d%d%d%d%d%d%d%d%d",f->face[3]->cases[0][0],f->face[3]->cases[0][1],f->face[3]->cases[0][2],f->face[3]->cases[1][0],f->face[3]->cases[1][1],f->face[3]->cases[1][2],f->face[3]->cases[2][0],f->face[3]->cases[2][1],f->face[3]->cases[2][2]);
		char faceCinq[9]; sprintf(faceCinq,"%d%d%d%d%d%d%d%d%d",f->face[4]->cases[0][0],f->face[4]->cases[0][1],f->face[4]->cases[0][2],f->face[4]->cases[1][0],f->face[4]->cases[1][1],f->face[4]->cases[1][2],f->face[4]->cases[2][0],f->face[4]->cases[2][1],f->face[4]->cases[2][2]);
		char faceSix[9]; sprintf(faceSix,"%d%d%d%d%d%d%d%d%d",f->face[5]->cases[0][0],f->face[5]->cases[0][1],f->face[5]->cases[0][2],f->face[5]->cases[1][0],f->face[5]->cases[1][1],f->face[5]->cases[1][2],f->face[5]->cases[2][0],f->face[5]->cases[2][1],f->face[5]->cases[2][2]);
		fichier<<donnee<<faceUne<<" - "<<faceDeux<<" - "<<faceTrois<<" - "<<faceQuatre<<" - "<< faceCinq<< " - "<<faceSix<<"\n";
		fichier.close();
	}
	if(index > 0)
	{
		ofstream fichier("Buchele-Thebault-output.txt", ios::out | ios::app); 
		char donnee[50];sprintf(donnee,"\nValeur heuristique %d - Cout %d\n",f->heuristique, f->cost);
		char faceUne[9];sprintf(faceUne,"%d%d%d%d%d%d%d%d%d",f->face[0]->cases[0][0],f->face[0]->cases[0][1],f->face[0]->cases[0][2],f->face[0]->cases[1][0],f->face[0]->cases[1][1],f->face[0]->cases[1][2],f->face[0]->cases[2][0],f->face[0]->cases[2][1],f->face[0]->cases[2][2]);
		char faceDeux[9]; sprintf(faceDeux,"%d%d%d%d%d%d%d%d%d",f->face[1]->cases[0][0],f->face[1]->cases[0][1],f->face[1]->cases[0][2],f->face[1]->cases[1][0],f->face[1]->cases[1][1],f->face[1]->cases[1][2],f->face[1]->cases[2][0],f->face[1]->cases[2][1],f->face[1]->cases[2][2]);
		char faceTrois[9]; sprintf(faceTrois,"%d%d%d%d%d%d%d%d%d",f->face[2]->cases[0][0],f->face[2]->cases[0][1],f->face[2]->cases[0][2],f->face[2]->cases[1][0],f->face[2]->cases[1][1],f->face[2]->cases[1][2],f->face[2]->cases[2][0],f->face[2]->cases[2][1],f->face[2]->cases[2][2]);
		char faceQuatre[9]; sprintf(faceQuatre,"%d%d%d%d%d%d%d%d%d",f->face[3]->cases[0][0],f->face[3]->cases[0][1],f->face[3]->cases[0][2],f->face[3]->cases[1][0],f->face[3]->cases[1][1],f->face[3]->cases[1][2],f->face[3]->cases[2][0],f->face[3]->cases[2][1],f->face[3]->cases[2][2]);
		char faceCinq[9]; sprintf(faceCinq,"%d%d%d%d%d%d%d%d%d",f->face[4]->cases[0][0],f->face[4]->cases[0][1],f->face[4]->cases[0][2],f->face[4]->cases[1][0],f->face[4]->cases[1][1],f->face[4]->cases[1][2],f->face[4]->cases[2][0],f->face[4]->cases[2][1],f->face[4]->cases[2][2]);
		char faceSix[9]; sprintf(faceSix,"%d%d%d%d%d%d%d%d%d",f->face[5]->cases[0][0],f->face[5]->cases[0][1],f->face[5]->cases[0][2],f->face[5]->cases[1][0],f->face[5]->cases[1][1],f->face[5]->cases[1][2],f->face[5]->cases[2][0],f->face[5]->cases[2][1],f->face[5]->cases[2][2]);
		fichier<<donnee<<faceUne<<" - "<<faceDeux<<" - "<<faceTrois<<" - "<<faceQuatre<<" - "<< faceCinq<< " - "<<faceSix<<"\n";
		fichier.close();
		fichier.close();
	}
	
	index++;
	
	ecritureAF(f->suivant,  index);
}

void ecritureAO(pcube f, int index)
{
	if(f == NULL)return;
	if(index ==0)
	{
		ofstream fichier("Buchele-Thebault-output.txt", ios::out | ios::app);  // ouverture en écriture avec effacement du fichier ouvert
		char donnee[50]; sprintf(donnee,"\n\nEtats Ouverts\nValeur heuristique %d - Cout %d\n",f->heuristique, f->cost);
		char faceUne[9]; sprintf(faceUne,"%d%d%d%d%d%d%d%d%d",f->face[0]->cases[0][0],f->face[0]->cases[0][1],f->face[0]->cases[0][2],f->face[0]->cases[1][0],f->face[0]->cases[1][1],f->face[0]->cases[1][2],f->face[0]->cases[2][0],f->face[0]->cases[2][1],f->face[0]->cases[2][2]);
		char faceDeux[9]; sprintf(faceDeux,"%d%d%d%d%d%d%d%d%d",f->face[1]->cases[0][0],f->face[1]->cases[0][1],f->face[1]->cases[0][2],f->face[1]->cases[1][0],f->face[1]->cases[1][1],f->face[1]->cases[1][2],f->face[1]->cases[2][0],f->face[1]->cases[2][1],f->face[1]->cases[2][2]);
		char faceTrois[9]; sprintf(faceTrois,"%d%d%d%d%d%d%d%d%d",f->face[2]->cases[0][0],f->face[2]->cases[0][1],f->face[2]->cases[0][2],f->face[2]->cases[1][0],f->face[2]->cases[1][1],f->face[2]->cases[1][2],f->face[2]->cases[2][0],f->face[2]->cases[2][1],f->face[2]->cases[2][2]);
		char faceQuatre[9]; sprintf(faceQuatre,"%d%d%d%d%d%d%d%d%d",f->face[3]->cases[0][0],f->face[3]->cases[0][1],f->face[3]->cases[0][2],f->face[3]->cases[1][0],f->face[3]->cases[1][1],f->face[3]->cases[1][2],f->face[3]->cases[2][0],f->face[3]->cases[2][1],f->face[3]->cases[2][2]);
		char faceCinq[9]; sprintf(faceCinq,"%d%d%d%d%d%d%d%d%d",f->face[4]->cases[0][0],f->face[4]->cases[0][1],f->face[4]->cases[0][2],f->face[4]->cases[1][0],f->face[4]->cases[1][1],f->face[4]->cases[1][2],f->face[4]->cases[2][0],f->face[4]->cases[2][1],f->face[4]->cases[2][2]);
		char faceSix[9]; sprintf(faceSix,"%d%d%d%d%d%d%d%d%d",f->face[5]->cases[0][0],f->face[5]->cases[0][1],f->face[5]->cases[0][2],f->face[5]->cases[1][0],f->face[5]->cases[1][1],f->face[5]->cases[1][2],f->face[5]->cases[2][0],f->face[5]->cases[2][1],f->face[5]->cases[2][2]);
		fichier<<donnee<<faceUne<<" - "<<faceDeux<<" - "<<faceTrois<<" - "<<faceQuatre<<" - "<< faceCinq<< " - "<<faceSix<<"\n";
		fichier.close();
	}
	if(index > 0)
	{
		ofstream fichier("Buchele-Thebault-output.txt", ios::out | ios::app); 
		char donnee[50];sprintf(donnee,"\nValeur heuristique %d - Cout %d\n",f->heuristique, f->cost);
		char faceUne[9];sprintf(faceUne,"%d%d%d%d%d%d%d%d%d",f->face[0]->cases[0][0],f->face[0]->cases[0][1],f->face[0]->cases[0][2],f->face[0]->cases[1][0],f->face[0]->cases[1][1],f->face[0]->cases[1][2],f->face[0]->cases[2][0],f->face[0]->cases[2][1],f->face[0]->cases[2][2]);
		char faceDeux[9]; sprintf(faceDeux,"%d%d%d%d%d%d%d%d%d",f->face[1]->cases[0][0],f->face[1]->cases[0][1],f->face[1]->cases[0][2],f->face[1]->cases[1][0],f->face[1]->cases[1][1],f->face[1]->cases[1][2],f->face[1]->cases[2][0],f->face[1]->cases[2][1],f->face[1]->cases[2][2]);
		char faceTrois[9]; sprintf(faceTrois,"%d%d%d%d%d%d%d%d%d",f->face[2]->cases[0][0],f->face[2]->cases[0][1],f->face[2]->cases[0][2],f->face[2]->cases[1][0],f->face[2]->cases[1][1],f->face[2]->cases[1][2],f->face[2]->cases[2][0],f->face[2]->cases[2][1],f->face[2]->cases[2][2]);
		char faceQuatre[9]; sprintf(faceQuatre,"%d%d%d%d%d%d%d%d%d",f->face[3]->cases[0][0],f->face[3]->cases[0][1],f->face[3]->cases[0][2],f->face[3]->cases[1][0],f->face[3]->cases[1][1],f->face[3]->cases[1][2],f->face[3]->cases[2][0],f->face[3]->cases[2][1],f->face[3]->cases[2][2]);
		char faceCinq[9]; sprintf(faceCinq,"%d%d%d%d%d%d%d%d%d",f->face[4]->cases[0][0],f->face[4]->cases[0][1],f->face[4]->cases[0][2],f->face[4]->cases[1][0],f->face[4]->cases[1][1],f->face[4]->cases[1][2],f->face[4]->cases[2][0],f->face[4]->cases[2][1],f->face[4]->cases[2][2]);
		char faceSix[9]; sprintf(faceSix,"%d%d%d%d%d%d%d%d%d",f->face[5]->cases[0][0],f->face[5]->cases[0][1],f->face[5]->cases[0][2],f->face[5]->cases[1][0],f->face[5]->cases[1][1],f->face[5]->cases[1][2],f->face[5]->cases[2][0],f->face[5]->cases[2][1],f->face[5]->cases[2][2]);
		fichier<<donnee<<faceUne<<" - "<<faceDeux<<" - "<<faceTrois<<" - "<<faceQuatre<<" - "<< faceCinq<< " - "<<faceSix<<"\n";
		fichier.close();
		fichier.close();
	}
	
	index++;
	
	ecritureAO(f->suivant,  index);
}

int AffichageMenu()
{
	printf("\n\nVeuillez selectionner un menu :\n1. Pivoter le cube\n2. Resoudre le cube\n3. Quitter\n\nVotre choix :");
	int choix = 0;
	std::cin>>choix;
	return choix;
}
void MenuManuelle(pcube c)
{
	int choix = 0;
	while(choix != 7)
	{
		   printf("\n\n Veuillez selectionner une rotation :\n1. Pivot droite de la face frontale\n2. Pivot gauche de la face frontale\n3. Pivot bas de la face frontale\n4. Pivot haut de la face frontale\n5. Pivot Gauche de la face laterale\n6. Pivot Droite de la face laterale\n7. Revenir au menu precedent\n\nVotre choix : ");
		std::cin>>choix;
		printf("\n");
		Mouvement(choix,c);
		affichageCube(c,0);
	}
}


void affichageTitre()
{
	printf("\nLionel Buchele\nYann Thebault\n\nResolution d'un rubix cube\n\n");
}

int main (int argc, char * const argv[]) {
    // insert code here...
    pcube ouvert = (pcube)malloc(sizeof(cube));
	pcube ferme = NULL;
	pcube cubeF = NULL;
	//pcube cubeO = ouvert;
	
	affichageTitre();
	Initialisation(ouvert,0);
	
	

	affichageCube(ouvert,0);
	int choix = 1;
	while(choix == 1)
	{
		choix = AffichageMenu();
		if(choix == 1)MenuManuelle(ouvert);
		if(choix ==2)Resolution(&ouvert, &ferme, ouvert);
	}
							

	/*pivotbas(ouvert->face[0], 1, NULL, 0);
	pivotbas(ouvert->face[0], 1, NULL, 0);
	/*pivotbas(ouvert->face[0], 1, NULL, 0);
	pivotDroit(ouvert->face[0], 1, NULL, 0);
	pivotDroit(ouvert->face[0], 1, NULL, 0);
	pivotDroit(ouvert->face[0], 1, NULL, 0);
	pivotGauche(ouvert->face[0], 1, NULL, 0);
	pivotGauche(ouvert->face[0], 1, NULL, 0);
	pivotGauche(ouvert->face[0], 1, NULL, 0);
	pivothaut(ouvert->face[0], 1, NULL, 0);
	pivothaut(ouvert->face[0], 1, NULL, 0);
	pivothaut(ouvert->face[0], 1, NULL, 0);
	 Resolution(&ouvert,&ferme,ouvert,&cubeO, &cubeF);*/
	 
	
	ecritureAF(ferme,0);
	ecritureAO(ouvert,0);
	Destruction(ouvert);
	Destruction(ferme);
    return 0;
}
