#include <math.h>

//Instance du code (pas important, enfin je veux dire pour le prog si, mais pas pour
//comprendre la source! :D)
HINSTANCE hInst;

//Indique un "Chargement en cours..." pour tout et pour (vraiment) rien.
//Décommentez cette ligne si ça peut vous faire triper :)
//#define INDIQUE_TRAVAIL
#define INDIQUE_PATIENTER

//#ifdef INDIQUE_TRAVAIL
	HWND hChargement;
//#endif

enum typesElement {TYPE_MAP=1,TYPE_CARTE=1,TYPE_SPRITE,TYPE_MOSAIQUE,TYPE_BITMAP8,TYPE_BITMAP16,TYPE_PALETTE,TYPE_LISTE};
#define TYPE_DOSSIER 0x4000
#define DANS_DOSSIER 0x8000
#define MASQUE_TYPE 0x3fff

#define FichierExiste(f)		((GetFileAttributes(f)==0xffffffff)?(0):(1))

//Structure d'un élément du projet
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 dossier[31];
/*	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;

#define MAXEL 1000
int nbreElements;
int gParam=0;
ELEMENT *elements;
char *cTitre="";
char chneTitre[1000];

//La variable "selection" contiendra une de ces valeurs pour indiquer l'état de l'appli.
enum Selections {SEL_AUCUNE,SEL_CARTES,SEL_MOSAIQUES,SEL_LISTES,SEL_BITMAPS,
	SEL_BITMAPS8,SEL_BITMAPS16,SEL_CARTES512,SEL_CARTES1024,SEL_BITMAP_8,SEL_BITMAP_16,
	SEL_CARTE,SEL_PALETTES,SEL_PALETTE,SEL_MOSAIQUE,SEL_LISTE,SEL_NULL
};

//Handle vers les éléments de l'arbre
HANDLE htvMosaiques, htvBitmaps, htvBitmaps8, htvBitmaps16, htvCartes, htvPalettes, htvImporter, htvListes;

//Variables Windows diverses
HFONT hFonte, hfCourier;
HDC hdcImage1, hdcImage2, hdcImage3, hdcImage4, hdcEdit, hdcSpec;
HBITMAP hbm1, hbm2, hbm4, hbmEdit, hbmSpec;
HWND hTV;
int selection=SEL_AUCUNE;

//Handle vers les boutons "dynamiques"
HWND hBoutonOk=0, hTexte01=0, hBoutonParcourir=0, hStatic01=0, hRadioTexte=0,
	hRadioRotation=0, hStatic02=0, hTexte02=0, hBoutonParcourir2=0,
	hBoutonParcourir3=0, hTexte03=0, hStatic03=0, hBoutonParcourir4=0, hTexte04=0,
	hStatic04=0, hComboPalette=0, hCheckPal=0, hComboTileset=0, hCheckTileset=0,
	hCheckMap=0, hTexte05=0, hStatic05=0, hStatic06=0, hComboTaille=0, hCheckOptimise=0,
	hComboTiles=0, hComboMap=0, hCheck16=0, hComboTileBits=0, hComboTypeMap=0, hStatic07=0,
	hBoutonReinit=0, hComboModeles=0;

int nElementSelectionne=-1;

//Vive les variables globales! :D
//(si vous me cherchez je suis déjà dehors...)
int tailleX, tailleY;						//Dimensions de l'image
int tailleVoulueX, tailleVoulueY;			//Ca se passe de commentaires...
int tileX=8, tileY=8, taille, vraieTaille;
int scrollX=0, scrollY=0;
int cFond=0, blocBase=0;
char str[1000];
int ModeTexte=0;
BOOL optimisePal=0, optimiseTil=0, b16coul=0, messages=1, bTil32Bits=0;					//bTil32Bits=1: 15 bits, (=2: 16 bits, =3: 18 bits, =4: 32 bits)
int utilMemoire=0;
int masqueInvisible=0xffff;
int editeurOuvert=0;

/*
	DEFINITIONS DE L'EDITEUR
*/
int MODE_TEXTE=0;
int nMaps=0, combleZeros=0, fondTransparent=0, hexAlphaFonds=96, gfxAlphaFonds=128, AlphaPremPlan=160;
BOOL proprePalette=1;

/*
	FIN DES DEFINITIONS DE L'EDITEUR
*/
HWND hArbre;

//Nombre max de tiles
//#define TILEMAX 4097
#define TILEMAX 8193


//Oui je sais c'est terriblement sale...
char gblcPal[MAX_PATH], gblcMap[MAX_PATH], gblcTil[MAX_PATH], gblcNomC[MAX_PATH];

int notification=1;

enum types_objets {	TYPE_TREEVIEW,TYPE_EDIT,TYPE_CHECKBOX,TYPE_RADIO,TYPE_COMBOBOX,TYPE_FONCTION,
					TYPE_ENTIER,TYPE_CHAINE,TYPE_REEL,TYPE_OBJET,TYPE_TABLEAU,TYPE_ENTIERDIRECT,
					TYPE_BOOLEEN, TYPE_SPECIAL};

char *types[]=		{
	"aucun", "carte", "(sprite)", "tileset", "bitmap 8 bits", "bitmap 16 bits", "palette", "liste"
};

char fichierConfigAOuvrir[MAX_PATH];
#define BASEMENU 16384
int nbreProcedures;

#define TAILLE_MAX_CHAINES 512
char repertoire[TAILLE_MAX_CHAINES], dossierParDefaut[10][TAILLE_MAX_CHAINES], fichierAide[TAILLE_MAX_CHAINES];

//N'accédez pas directement à ces variables avec le script! Utilisez "convert.couleurtransparente=rgb(1,2,3)" à la place...
int rougeMasque=255, vertMasque=0, bleuMasque=254, rougeZero=0, vertZero=0, bleuZero=0;
int popUpInfos=1, tempsPopUp=61, fondHexa=1, retourScript;
int nuances;
char *sectionDonnees;
int tailleSectionDonnees, utilMaxCoul=FALSE, emul_gba=FALSE;
HMENU hProcedures;

enum sdTypes {SDT_AUCUN=0,SDT_ENTIER=1,SDT_BRUT=2};

#define MAX_SD 100
#define TAILLE_MAX_NOM_SD 32
#define TAILLE_MAX_VALEUR_DEFAUT_SD 16
typedef struct	{
//	int sdNumParams=0;
	char sdNomModele[TAILLE_MAX_CHAINES];
	int sdNumParams;
	int sdTypeParam[MAX_SD];
	int sdTaillesParam[MAX_SD];
	char sdNomsParams[MAX_SD][TAILLE_MAX_NOM_SD];
	char sdTexteDefaut[MAX_SD][TAILLE_MAX_VALEUR_DEFAUT_SD];
	int sizeofSD;
} SD_PARAMS;

#define MAX_SD_MODELES 10
SD_PARAMS *sdParams;
int sdNbreModeles=1;
int gblSdModele=0;
char gblTypeSd[TAILLE_MAX_CHAINES];

#define _SD(x,y) ((SPRITE_DEF*)((char*)x.sd+(y)*((x).sizeofSD)))

typedef	struct	{
	int x,y;
	int type;
	char params[];
} SPRITE_DEF;

typedef struct		{
	int sizeofSD;
	SPRITE_DEF *sd;
	int nbSprites;
} SPRITE_LISTE;

#define SUPPORT_MAPS_32_BITS

#ifdef SUPPORT_MAPS_32_BITS
	typedef unsigned long MAP;
#else
	typedef unsigned short MAP;
#endif

#define NB_MAX_USERDATA 8

typedef struct		{
	int tailleX;
	int tailleY;
	int tileX;
	int tileY;
	int tileBaseX, tileBaseY;
	int taille;
	int blocBase;
	int gfxmask;
	int ModeTexte;
	int b16coul;
	double parallaxeX, parallaxeY;
	unsigned char *gblPal;
	unsigned long *gblMotifs;
	MAP *gblMap;
	char gblcPal[MAX_PATH], gblcMap[MAX_PATH], gblcTil[MAX_PATH], gblcNomC[MAX_PATH];
	int gblTypeMap;
	SPRITE_LISTE gblSpriteListe;
	int grilleX, grilleY;
	int bTil32Bits;
	SD_PARAMS *gblSdParam;
	char gblTypeSd[TAILLE_MAX_CHAINES];
	char gblUserData[NB_MAX_USERDATA][TAILLE_MAX_CHAINES];
	int emul_gba;
} PARAM;

SPRITE_LISTE gblSpriteListe;
char gblUserData[NB_MAX_USERDATA][TAILLE_MAX_CHAINES];

unsigned char tblCoulR[256], tblCoulV[256], tblCoulB[256];
double GammaR=1, GammaV=1, GammaB=1, AdditionR=0, AdditionV=0, AdditionB=0, AlphaR=0, AlphaV=0, AlphaB=0;
int nuancesAvant=0, troncEntier=0;

int modeConversion=0;
int gblCurSection;
BITMAP                  bmConv;
HBITMAP                 hbmConv;
HDC                     hdcConv;

int couleurGrille=RGB(64,64,64), transGrille=96;
int masqueZero=0, bitsMasqueZero=1;

#define NOMBRE_BITS 8
#define BASE_BIT 8
char (*nomsBits)[NOMBRE_BITS][TAILLE_MAX_CHAINES]=NULL;
char (*bitsActives)[NOMBRE_BITS]=NULL;
HWND hDlgBits;


#define MAX_FONDS 20

#define MAX_COND 20

unsigned short n_conditions[MAX_FONDS];
typedef struct		{
	MAP debut, fin;
	int difference;
	unsigned char exact;
} S_CONDITION;
S_CONDITION s_conditions[MAX_FONDS][MAX_COND];

//Variables spéciales. Ces variables sont modifiables à l'aide d'un fichier texte.
int gfxmask=0xffffffff;
char *nom_format=NULL, format_appliquer[TAILLE_MAX_CHAINES], modele_appliquer[TAILLE_MAX_CHAINES];

//#define DIMENSION_MAX 2048
//#define DIMENSION_MAX 16384
unsigned int DIMENSION_MAX=1024*1024*32;					//Taille max des aperçus: 32 Mo

char chneNomVarTil[TAILLE_MAX_CHAINES], chneNomVarMap[TAILLE_MAX_CHAINES], chneNomVarPal[TAILLE_MAX_CHAINES], chneNomVarB8[TAILLE_MAX_CHAINES], chneNomVarB16[TAILLE_MAX_CHAINES];
int editTiming;
int precisionMax=512;

int bGdiPlusEnabled=1, bGdiPlusDemarre=0;

int GDIPLUS_DrawImage (const char *fichier, int *dx, int *dy);
LRESULT CALLBACK ProcOptions(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK ProcOptions2(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK ProcOptions3(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK ProcOptions4(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
void Alloc_Bits();
void Dealloc_Bits();
BOOL IsAllocated_Bits();
int NB_MAX_ELE_LISTE=1024;

char *chneNomsDefautBits[]=		{
	"Palette (MSB)",
	"Palette",
	"Palette",
	"Palette (LSB)",
	"Miroir vertical",
	"Miroir horizontal",
	"(inutile)",
	"(inutile)",
};

void OptionsParams_RedessCombo(HWND hDlg, int dlgItem);

int sauverParamsMaps=1, sauverParamsMapsAutomatiquement=0;
char fichierProjet[MAX_PATH];
int gblErrorFlag;			//Une erreur s'est produite?
int bEtatDupliqueElement=0;
int bRedimDIBOverflow=0, bImageTropGrosse=0;
int bChoisitAutoFormat=1;
int g_majListeEnCours=0;

int EffaceVersCorbeille(char *nom_fichier);
void EcritParamsStandard(int fond);
void ChoisitFormatFichierExtension(const char *nom);

#define MAX_S32 0x7fffffff
char *GetCopieChaine(char *dst, char *chne, unsigned long tailleMax);

LRESULT CALLBACK DlgAttributsElement(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
void GetNomFichierConfigMap(char *nom_fichier, char *nom_base);

//OKKKKK - supprimé presque tout (pas FenMAJ)
/*#define FenInvisible()		LockWindowUpdate(gblHDlg)
#define FenMAJ()			LockWindowUpdate(NULL); RedrawWindow(hDlg,NULL,NULL,RDW_ERASE|RDW_INVALIDATE);
#define FenVisible()		LockWindowUpdate(NULL)*/
#define FenInvisible()
#define FenVisible()
#define FenMAJ() RedrawWindow(hDlg,NULL,NULL,RDW_ERASE|RDW_INVALIDATE);

//#define FenMAJ()			(SendMessage(gblHDlg,WM_SETREDRAW,1,0), RedrawWindow(hDlg,NULL,NULL,RDW_ERASE|RDW_INVALIDATE))
/*void FenInvisible()		{
	SendMessage(gblHDlg,WM_SETREDRAW,0,0);
	int i;
	i=GetWindowLong(gblHDlg, GWL_STYLE);
	SetWindowLong(gblHDlg, GWL_STYLE, i);
}

void FenVisible()		{
	SendMessage(gblHDlg,WM_SETREDRAW,1,0);
}

void FenMAJ()		{
	SendMessage(gblHDlg,WM_SETREDRAW,1,0);
	RedrawWindow(gblHDlg,NULL,NULL,RDW_ERASE|RDW_INVALIDATE|RDW_INTERNALPAINT|RDW_UPDATENOW|RDW_ALLCHILDREN);
}
#define FenMAJ()			{SendMessage(gblHDlg,WM_SETREDRAW,1,0); RedrawWindow(gblHDlg,NULL,NULL,RDW_ERASE|RDW_INVALIDATE|RDW_INTERNALPAINT|RDW_UPDATENOW|RDW_ALLCHILDREN);}
#define FenVisible()		SendMessage(gblHDlg,WM_SETREDRAW,1,0)*/

/*#define FenInvisible()
#define FenMAJ()			RedrawWindow(hDlg,NULL,NULL,RDW_ERASE|RDW_INVALIDATE)
#define FenVisible()*/

#define NBRE_PTRS_FORMATS 6

//NOUVELLE OPTION -> arrondit la sélection aux tileX/tileY pour le multiplan
int bArronditSelection=1;

int dejaAvertiElementDossierBase=0;
int bInviteScriptContenuSauve=0;
char cInitialDir[MAX_PATH];
int bSpecimenAffiche=1;

#define UM_CHANGEMAP (WM_USER+2)

int gbatilmask=0xffffffff;


