const char *cVersion="GBA Graphics 02";
const char *chneVersion="#Fichier de projet GBA Graphics\n";

typedef struct		{
	HTREEITEM hti;					//L'élément dans l'arbre du projet
	char nom_base[MAX_PATH];		//Nom du fichier de base (avant conversion)
	char nom_fichier[MAX_PATH];		//Nom du fichier à utiliser
	char nom_court[31];				//Nom personnalisé de l'élément
/*	char nom_map[MAX_PATH];			//Nom de la map associé (si le cas)
	char nom_palette[MAX_PATH];		//Optionnel: s'il y a une palette associée
	char nom_tileset[MAX_PATH];		//Optionnel: s'il y a un jeu de mosaïques associé*/
	int type;						//Type de l'élément
} ELEMENT_V02;

void DemandeSauveProjet(char *str)		{
	memset(str,0,MAX_PATH);
	if (!SauveFichier(str,"\1Fichiers projet GBA Graphics *.pgg\0*.pgg\0\0"))
		str[0]=0;
	else
		AjouteExtension(str, ".pgg");
}


int ChargeProjetVersion02(const char *nom_fichier)		{
	FILE *f;
	ELEMENT_V02 elems[MAXEL];
	ELEMENT el;
	char str[100];
	int i,nEle;


	f=fopen(nom_fichier,"rb");
	if (!f)
		return 0;
	memset(str,0,sizeof(str));
	fread(str,strlen(cVersion),1,f);
	if (strcmp(str,cVersion))		{
		return 0;
	}
	fread(&nEle,sizeof(int),1,f);
	fread(elems,sizeof(ELEMENT_V02),nEle,f);

	for (i=0;i<nEle;i++)		{
		el.hti=NULL;
		strcpy(el.nom_base,elems[i].nom_base);
		strcpy(el.nom_court,elems[i].nom_court);
		strcpy(el.nom_fichier,elems[i].nom_fichier);
		el.type=elems[i].type+1;
		AjouteAuProjet(el);
	}

	fclose(f);
	return 1;
}

/*void SauveProjet(const char *nom_fichier)		{
	FILE *f;
	f=fopen(nom_fichier,"wb");
	if (!f)
		return;
	fwrite(cVersion,strlen(cVersion),1,f);
	fwrite(&nbreElements,sizeof(int),1,f);
	fwrite(elements,sizeof(ELEMENT),nbreElements,f);
	fclose(f);
}*/

char *GetBoolText(int valeur)		{
	if (valeur)
		return "vrai";
	else
		return "faux";
}

void SauveProjet(const char *nom_fichier)		{
	FILE *f;
	char str[2048], tampon[MAX_PATH], nomparam[1024], defautparam[1024];
	int i, j;

	if (!nom_fichier[0])		{
		DemandeSauveProjet(str);
		if (!(*str))
			return;
	}
	else
		strcpy(str, nom_fichier);

	f=fopen(str,"w");
	if (!f)
		return;
	fputs(chneVersion,f);

	fputs("\n#Infos utiles sur la dernière session\n"
		" .section infos\n",f);

	GetCurrentDirectory(MAX_PATH,tampon);
	sprintf(str,"  Répertoire = \"%s\"\n  Script = \"%s\"\n  AidePerso = \"%s\"\n",tampon,fichierConfigAOuvrir,fichierAide);
	fputs(str,f);

	sprintf(str,"\n  convert.couleurMasque = RGB(%i,%i,%i)\n  convert.luminosite   GAMMA=RGB(%.3f,%.3f,%.3f)  ADD=RGB(%.1f,%.1f,%.1f)  ALPHA=RGB(%.1f,%.1f,%.1f)\n  convert.mode = %i\n\n",rougeMasque,vertMasque,bleuMasque,1.0/GammaR,1.0/GammaV,1.0/GammaB,AdditionR,AdditionV,AdditionB,AlphaR,AlphaV,AlphaB,modeConversion);
	fputs(str,f);

	//Options -> général
	if (!sauverParamsMaps)
		fprintf(f, "  system.sauverParamsMaps = %s\n", GetBoolText(sauverParamsMaps));
//	if (!sauverParamsMapsAutomatiquement)
		fprintf(f, "  system.sauverParamsMapsAuto = %s\n", GetBoolText(sauverParamsMapsAutomatiquement));
	if (NB_MAX_ELE_LISTE != 1024)
		fprintf(f, "  system.objetsMax = %i\n", NB_MAX_ELE_LISTE);
	if (editTiming != 10)
		fprintf(f, "  editeur.Timing = %i\n", editTiming);
	if (DIMENSION_MAX != 1024*1024*32)		{
		Memory_IntToString(str, DIMENSION_MAX);
		fprintf(f, "  system.MemoireMax = %s\n", str);
	}
	if (!bChoisitAutoFormat)
		fprintf(f, "  system.selectionFormatAuto = %s\n", GetBoolText(bChoisitAutoFormat));

	//Options -> conversion -> avancé
	if (nuances!=31)
		fprintf(f, "  convert.nuances = %i\n", nuances+1);
	if (nuancesAvant)
		fprintf(f, "  convert.nuancesAvant = %s\n", GetBoolText(nuancesAvant));
	if (troncEntier)
		fprintf(f, "  convert.tronquer = %s\n", GetBoolText(troncEntier));
	if (utilMaxCoul)
		fprintf(f, "  convert.utilMaxCoul = %s\n", GetBoolText(utilMaxCoul));
	if (precisionMax!=512)
		fprintf(f, "  convert.precisionMax = %i\n", precisionMax);

	for (i=0;i<10;i++)		{
		if (dossierParDefaut[i][0])		{
			sprintf(str,"  DossierDéf[%i] = \"%s\"\n",i+1,dossierParDefaut[i]);
			fputs(str,f);
		}
	}

	if (nom_format)
		fprintf(f,"  Format = \"%s\"\n\n",nom_format);

	for (j=0;j<sdNbreModeles;j++)			{
		fprintf(f, "  DefModele \"%s\"		{\n", sdParams[j].sdNomModele);
		for (i=0;i<sdParams[j].sdNumParams;i++)				{
			CreeChaineScript(defautparam, sdParams[j].sdTexteDefaut[i], '\"', sizeof(defautparam));
			CreeChaineScript(nomparam, sdParams[j].sdNomsParams[i], '\"', sizeof(nomparam));
			fprintf(f, "  	%i, %i, %s, %s\n", sdParams[j].sdTypeParam[i], sdParams[j].sdTaillesParam[i], nomparam, defautparam);
		}
		fputs("  }\n\n", f);
	}

	fprintf(f, "  Modele = \"%s\"\n", sdParams[gblSdModele].sdNomModele);

	fputs("  Fin\n",f);

	fputs("\n#Eléments de l'arbre du projet\n"
		" .section fichiers\n",f);

	for (i=0;i<nbreElements;i++)	{
		if (elements[i].type&TYPE_DOSSIER)		{
			sprintf(str," #--------------\n"
						"  Elément: %s\n"
						"  Type: dossier\n"
						,elements[i].nom_court);
		}
		else	{
			sprintf(str," #--------------\n"
						"  Elément: %s\n"
						"  Type: %s\n"
						"  Fichier: %s\n"
						"  Base: %s\n"
						,elements[i].nom_court,types[(elements[i].type&MASQUE_TYPE)],elements[i].nom_fichier,elements[i].nom_base);
		}
		fputs(str,f);
		if (elements[i].type&DANS_DOSSIER)		{
			sprintf(str,"  Dossier: %s\n",elements[i].dossier);
			fputs(str,f);
		}

//		elements[i].hti=InsereObjDansArbre(hTV,(HTREEITEM)htvCartes,elements[i].nom_court,3);
	}

	fputs(" Fin\n",f);

	fputs("\n#Section où vous pouvez entrer n'importe quelle commande de script. Cela vous permet de régler les différentes variables.\n"
		" .section données\n",f);
	if (sectionDonnees)
		fwrite(sectionDonnees,1,tailleSectionDonnees,f);
	else
		fputs("  Fin\n\n\n\n",f);

//	fwrite(&nbreElements,sizeof(int),1,f);
//	fwrite(elements,sizeof(ELEMENT),nbreElements,f);
	fclose(f);
//	sprintf(str,"notepad %s",nom_fichier);
//	WinExec(str,1);
}

void ChneMinusculeEx(char *str)		{
	while(*str)		{
		if (*str>='A' && *str<='Z')
			(*str)+=32;
		str++;
	}
	if (*(str-1)=='\n')
		*(str-1)=0;
}

void ChneMinuscule(char *str)		{
	while(*str)		{
		if (*str>='A' && *str<='Z')
			(*str)+=32;
		str++;
	}
}

void EnleveRetour(char *str)		{
	while(*str)
		str++;
	if (*(str-1)=='\n')
		*(str-1)=0;
}

#define SauteEspaces(ptr)		{ while(*ptr==' ' || *ptr=='	')  ptr++; }

FILE *ChercheSection(const char *nom_fichier, char *section)			{
	char str[2048], *ptr;
	FILE *f;

	f=fopen(nom_fichier,"r");

	while(!feof(f))		{
		fgets(str,sizeof(str),f);
		ChneMinusculeEx(str);
		ptr=str;
		SauteEspaces(ptr);
		if (*ptr!='.')
			continue;
		if (strncmp(ptr,".section",8))
			continue;
		ptr+=9;
		if (!strcmp(ptr,section))
			return f;
	}
	fclose(f);
	return NULL;
}

void ChargeAncienProjet(const char *nom_fichier)		{
	char str[1000];
	nbreElements = 0;
	strcpy(str,nom_fichier);
	strcat(str,".bak");
	CopyFile(nom_fichier,str,FALSE);
	if (!ChargeProjetVersion02(nom_fichier))
		MessageBox(NULL,"Aucun des filtres intégrés n'a pu charger le fichier de sauvegarde.\nGBA Graphics va à présent démarrer avec un nouveau projet.","Erreur",MB_ICONERROR);
}

void ChargeProjet(const char *nom_fichier)		{
	FILE *f;
	char str[2048], *ptr;
	ELEMENT el;
	int i;
	fpos_t pos;

	sectionDonnees=NULL;

	f=fopen(nom_fichier,"r");
	if (!f)
		return;

	str[0]=0;
	fgets(str,sizeof(str),f);
	fclose(f);

	if (str[0]==0)
		return;

	if (strcmp(str,chneVersion))		{
		MessageBox(NULL,"Le fichier de sauvegarde est d'une version plus ancienne (ou plus nouvelle)\nGBA Graphics va tenter d'effectuer une mise à jour de celui-ci après avoir préalablement réalisé une copie sous Projet.pgg.bak, ok?","Attention",MB_ICONEXCLAMATION);
		ChargeAncienProjet(nom_fichier);
		return;
	}

	f=ChercheSection(nom_fichier,"fichiers");
	nbreElements = 0;

	while(!feof(f))		{
		fgets(str,sizeof(str),f);							//Lit la chaîne
		ptr=str;
		SauteEspaces(ptr);
		EnleveRetour(str);

		if (!strncmp(ptr,"Elément: ",9))		{			//Définition d'élément
			ptr+=9;											//Pointe sur le nom court
			strcpy(el.nom_court,ptr);						//Copie le nom court dans l'élément
			fgets(str,sizeof(str),f);						//Prochaine ligne
			EnleveRetour(str);
			ptr=str;
			SauteEspaces(ptr);
			el.type=0;
/*			strcpy(el.nom_fichier,"");
			strcpy(el.nom_base,"");
			strcpy(el.dossier,"");*/
compare:
			if (!strncmp(ptr,"Type: ",6))		{			//Définition du type
				ptr+=6;
				if (!strncmp(ptr,"dossier",7))		{
					el.type|=TYPE_DOSSIER;
					goto prochLigne;
				}
				for (i=0;i<sizeof(types)/sizeof(types[0]);i++)			{
					if (!strcmp(ptr,types[i]))				//Compare le type et la chaîne
						goto cestbon;						//Type trouvé
				}
				continue;									//Type non-trouvé
cestbon:
				el.type|=i;									//Stocke le type
prochLigne:
				fgets(str,sizeof(str),f);					//Prochaine ligne
				EnleveRetour(str);
				ptr=str;
				SauteEspaces(ptr);
				goto compare;
			}
			if (!strncmp(ptr,"Fichier: ",9))		{		//Définition du fichier
				ptr+=9;
				strcpy(el.nom_fichier,ptr);					//Copie le nom de fichier
				fgets(str,sizeof(str),f);					//Prochaine ligne
				EnleveRetour(str);
				ptr=str;
				SauteEspaces(ptr);
				goto compare;
			}
			if (!strncmp(ptr,"Base: ",6))		{			//Définition du fichier de base
				ptr+=6;
				strcpy(el.nom_base,ptr);					//Copie le nom du fichier de base
				fgets(str,sizeof(str),f);					//Prochaine ligne
				EnleveRetour(str);
				ptr=str;
				SauteEspaces(ptr);
				goto compare;
			}
			if (!strncmp(ptr,"Dossier: ",9))		{		//Définition du fichier de base
				ptr+=9;
				strcpy(el.dossier,ptr);						//Copie le nom du fichier de base
				fgets(str,sizeof(str),f);					//Prochaine ligne
				EnleveRetour(str);
				ptr=str;
				SauteEspaces(ptr);
				el.type|=DANS_DOSSIER;
				goto compare;
			}
			el.hti=NULL;
			AjouteAuProjetRapide(el);
		}
		else	{
			ChneMinuscule(str);
			if (!strncmp(ptr,"fin",3))
				break;
			else if (!strncmp(ptr,".section",8))
				break;
		}
	}
	fclose(f);

	f=ChercheSection(nom_fichier,"infos");
	ExecScript(f,NULL);

	f=ChercheSection(nom_fichier,"données");
	if (!f)
		return;
	//La section données doit être gardée dans le fichier (i.e. réécrite lors de la sauvegarde). On la sauve donc à présent. Notez que ce n'est pas le cas de la section infos, qui contient du code généré par GBA Graphics uniquement!
	sectionDonnees=(char*)malloc(1000000);
	fgetpos(f,&pos);
	tailleSectionDonnees=fread(sectionDonnees,1,1000000,f);
	fsetpos(f,&pos);
	ExecScript(f,NULL);
}



