/*------------------------------------------------------------------------------
Module	R:\Programmation\Projets_LCC_2005\Calculatrice\frmDlgMain.c
Author:	Valentin KIEBASA
Project:	Inconnu
State:		Début
Creation Date :	dim   9 jan 2005 09:25:59
Description:	Gestion de la feuille de dialogue référencée DLG_MAIN
--------------------------------------------------------------------------*/
#include <windows.h>
#include <stdio.h>
#include <RKControles.h>
#include "calc_rc.h"


#include "calc.h"

#include "version.h"

typedef struct _contexte
{
	int afficherErreurs;
	int afficherHisto;
}CONTEXTE;

CONTEXTE contexte = {1, 1};

/* Tableau pour la gestion des variables */
#define MAXVARTABLESIZE 100
CALC_VAR calc_vartable[MAXVARTABLESIZE];
int calc_nbvars = 0;

int appelDlgAbout(HWND hwndParent);
int appelDlgHelp(HWND hwndParent);

void MYSTRINGS_ReplaceChar(char *chaineSrc, int carDest, int carSrc);


 /*------------------------------frmMain---------------------------------*/
extern HINSTANCE hInst;

/*Déclarations privées--------------------------------------------------*/
static LRESULT On_Notify(HWND hwndDlg, WPARAM wParam, LPARAM lParam);
static LRESULT On_Click(HWND hwndDlg, WPARAM wParam, LPARAM lParam);
static LRESULT On_RightClick(HWND hwndDlg, WPARAM wParam, LPARAM lParam);
static LRESULT On_DoubleClick(HWND hwndDlg, WPARAM wParam, LPARAM lParam);
static LRESULT On_Close(HWND hwndDlg, WPARAM wParam, LPARAM lParam);
static int On_Resize(HWND hwndDlg);

static int Calculer(HWND hwndDlg, char *formule);

static int enregClassedialog(HINSTANCE);
static BOOL LISTVIEW_InsertColumn(HWND lv,  char *titreColonne,
	int taille, int format, int emplacement);

static int InsererMessage(HWND hwndLV, CALC_MSG *msg);
static int InsererFormule(HWND hwndLV, char *formule, double resultat);

static int initFrmDlgMain(HWND, WPARAM, LPARAM);
static BOOL CALLBACK gererFrmDlgMain(HWND, UINT, WPARAM, LPARAM);
/*------------------------------------------------------------------------
Procedure:     appelDlgMain ID:1
Purpose:
Input:
Output:
Errors:
------------------------------------------------------------------------*/
int appelDlgMain(HWND hwndParent)
{

	/*
	* declaration des variables locales
	* =================================
	*/
	int result;
	INITCOMMONCONTROLSEX icex;


	/*
	* code executable
	* ===============
	*/
	icex.dwSize = sizeof (icex);
	icex.dwICC = 1;
	InitCommonControlsEx(&icex);

	enregClassedialog(hInst);


	result = DialogBoxParam(hInst, MAKEINTRESOURCE(DLG_MAIN), hwndParent, (DLGPROC) gererFrmDlgMain, (LPARAM)0);
	return result;
}
/*------------------------------------------------------------------------
Procedure:     initFrmDlgMaing ID:1
Purpose:
Input:
Output:
Errors:
------------------------------------------------------------------------*/
static int initFrmDlgMain(HWND hwndDlg, WPARAM wParam, LPARAM lParam)
{

	/*
	* declaration des variables locales
	* =================================
	*/
	HWND hwndLVMsg = GetDlgItem(hwndDlg, LVW_MESSAGES);
	HWND hwndLVHisto = GetDlgItem(hwndDlg, LVW_HISTO);
	int i = 0;
	/* Modification de la police du titre */
	HFONT hFont = CreateFont(

		13,	// logical height of font
		0,	// logical average character width
		0,	// angle of escapement
		0,	// base-line orientation angle
		FW_BOLD	,	// font weight
		FALSE,	// italic attribute flag
		FALSE,	// underline attribute flag
		FALSE,	// strikeout attribute flag
		DEFAULT_CHARSET,	// character set identifier
		OUT_DEFAULT_PRECIS,	// output precision
		CLIP_DEFAULT_PRECIS,	// clipping precision
		DEFAULT_QUALITY,	// output quality
		DEFAULT_PITCH,	// pitch and family
		"TAHOMA" 	// pointer to typeface name string
   );

	SendDlgItemMessage(hwndDlg, LBL_RESULTAT, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));



	SendMessage(hwndLVMsg, LVM_SETEXTENDEDLISTVIEWSTYLE,(WPARAM)0,(LPARAM)LVS_EX_FLATSB|LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
	LISTVIEW_InsertColumn(hwndLVMsg, "Etat",             50, LVCFMT_LEFT, i++);
	//LISTVIEW_InsertColumn(hwndLVMsg, "Num Message",      20, LVCFMT_LEFT, i++);
	//LISTVIEW_InsertColumn(hwndLVMsg, "Position",    30, LVCFMT_RIGHT, i++);
	LISTVIEW_InsertColumn(hwndLVMsg, "Message",      300, LVCFMT_LEFT, i++);

	SendMessage(hwndLVHisto, LVM_SETEXTENDEDLISTVIEWSTYLE,(WPARAM)0,(LPARAM)LVS_EX_FLATSB|LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
	LISTVIEW_InsertColumn(hwndLVHisto, "Formule",             220, LVCFMT_LEFT, i++);
	LISTVIEW_InsertColumn(hwndLVHisto, "Valeur",              120, LVCFMT_RIGHT, i++);

	/* Initialisation de la table des variables */
	memset(&calc_vartable, 0, sizeof(calc_vartable));

	/* Configuration de démarrage */
	contexte.afficherErreurs = 0;

	On_Resize(hwndDlg);

	return 1;
}
/*------------------------------------------------------------------------
Procedure:     gererFrmDlgMain ID:1
Purpose:
Input:
Output:
Errors:
------------------------------------------------------------------------*/
static BOOL CALLBACK gererFrmDlgMain(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{

	/*
	* declaration des variables locales
	* =================================
	*/

	/*
	* code executable
	* ===============
	*/

	switch (msg)
	{
		case WM_INITDIALOG:
			initFrmDlgMain(hwndDlg, wParam, lParam);
			return TRUE;

		case WM_SIZE:
			/* Resize automatique de la barre d'état */
			SendMessage(GetDlgItem(hwndDlg, STB_MAIN), msg, wParam, lParam);

			return On_Resize(hwndDlg);
			break;

		case WM_COMMAND:
			switch (LOWORD(wParam))
		{
			case TXT_FORMULE:
				break;
			case CMD_CALCULER:
				{
					char formule[1024];

					/* Récupération de la formule */
					SendDlgItemMessage(hwndDlg, TXT_FORMULE, WM_GETTEXT, (WPARAM)sizeof(formule), (LPARAM)formule);

					Calculer(hwndDlg, formule);

				}
				break;
			case LVW_MESSAGES:
				break;
			case LVW_HISTO:
				break;

			case ITM_OPEN:
				{
					char fichier[MAX_PATH] = "";
					OPENFILENAME openFonct;

					memset(&openFonct, 0, sizeof(OPENFILENAME));

					/*initialisation commune à tout exe*/
					openFonct.lStructSize = sizeof(OPENFILENAME);
					openFonct.hwndOwner = hwndDlg;
					openFonct.lpstrFilter = "Fichier de calculs (*.txt)\0*.txt\0\0";
					openFonct.lpstrCustomFilter = NULL;
					openFonct.nMaxCustFilter = 0;
					openFonct.nFilterIndex = 1;
					openFonct.nMaxFile = MAX_PATH;
					openFonct.lpstrFileTitle = NULL;
					openFonct.nMaxFileTitle = 0;
					openFonct.Flags = OFN_EXTENSIONDIFFERENT ;
					openFonct.lpstrDefExt = "*.txt" ;

					openFonct.lpstrFile = fichier;
					openFonct.lpstrInitialDir = NULL;
					openFonct.lpstrTitle = "Choisir le fichier de calcul...";

					//MessageBox(hwnd, "GetOpenFileName?>", nomApplication, MB_ICONEXCLAMATION);

					if(GetOpenFileName(&openFonct) == 0)
					{
						//MessageBox(hwndDlg, "Vous n'avez choisi aucun fichier!", "Phidus", MB_ICONEXCLAMATION);
						return -1;
					}
					else
					{
						FILE *fp;
						char buffer[256];


						fp = fopen(fichier, "r");
						if(fp == NULL)
							break;

						while(fgets(buffer, sizeof(buffer), fp))
						{
							MYSTRINGS_ReplaceChar(buffer, '\n', ' ');
							Calculer(hwndDlg, buffer);
						}

						fclose(fp);
					}
				}
				break;

			case ITM_SAVEAS:
				{
					char fichier[MAX_PATH] = "";

					OPENFILENAME openFonct;

					memset(&openFonct, 0, sizeof(OPENFILENAME));

					/*initialisation commune à tout exe*/
					openFonct.lStructSize = sizeof(OPENFILENAME);
					openFonct.hwndOwner = hwndDlg;
					openFonct.lpstrFilter = "Fichier de calcul (*.txt)\0*.*\0\0";
					openFonct.lpstrCustomFilter = NULL;
					openFonct.nMaxCustFilter = 0;
					openFonct.nFilterIndex = 1;
					openFonct.nMaxFile = MAX_PATH;
					openFonct.lpstrFileTitle = NULL;
					openFonct.nMaxFileTitle = 0;
					openFonct.Flags = OFN_EXTENSIONDIFFERENT ;
					openFonct.lpstrDefExt = "" ;

					openFonct.lpstrFile = fichier;
					openFonct.lpstrInitialDir = NULL;
					openFonct.lpstrTitle = "Enregistrer le fichier sous ...";

					//MessageBox(hwnd, "GetOpenFileName?>", nomApplication, MB_ICONEXCLAMATION);

					if(GetSaveFileName(&openFonct) == 0)
					{
						//MessageBox(hwndDlg, "Vous n'avez choisi aucun fichier!", "Phidus", MB_ICONEXCLAMATION);
						return -1;
					}
					else
					{
						HWND hwndLV = GetDlgItem(hwndDlg, LVW_HISTO);
						//LV_ITEM lvi;
						char buffer[128];
						FILE *fp;

						fp = fopen(fichier, "w");

						if(fp == NULL)
							break;

						for(int i = 0; i < ListView_GetItemCount(hwndLV)-1 ; i++)
						{
							ListView_GetItemText(hwndLV, i, 0, buffer, sizeof(buffer));

							fprintf(fp, "%s\n", buffer);
						}

						fclose(fp);
					}
				}
				break;

			case ITM_QUITTER:
				On_Close(hwndDlg, wParam, lParam);
				break;

			case ITM_AFF_ERREURS:
				contexte.afficherErreurs = !contexte.afficherErreurs;
				On_Resize(hwndDlg);
				//ModifyMenu(GetMenu(hwndDlg), ITM_AFF_ERREURS, MF_BYCOMMAND,
				if(contexte.afficherErreurs)
					CheckMenuItem(GetMenu(hwndDlg), ITM_AFF_ERREURS, MF_BYCOMMAND|MF_CHECKED);
				else
					CheckMenuItem(GetMenu(hwndDlg), ITM_AFF_ERREURS, MF_BYCOMMAND|MF_UNCHECKED);
				break;

			case ITM_HELP:
				appelDlgHelp(hwndDlg);
				break;

			case ITM_ABOUT:
				appelDlgAbout(hwndDlg);
				break;

			case ITM_HISTO_SUPP:
			{
				/* Déclarations */
				HWND hwndLV = GetDlgItem(hwndDlg, LVW_HISTO);
				LV_ITEM lvi;
				//char buffer[128];


				int countSel = ListView_GetSelectedCount(hwndLV);
				int curseur = 0;
				int nbSup = 0;

				if(countSel == 0)
				{
					//MessageBox(hwndDlg, "Aucune opération n'est sélectionnée pour la suppression.", "PHIDUS", MB_OK|MB_ICONEXCLAMATION);
					break;
				}

				memset(&lvi, 0, sizeof(LV_ITEM));

				lvi.mask = LVIF_PARAM|LVIF_STATE;
				lvi.stateMask = LVIF_STATE;

				while(nbSup <= countSel && curseur < ListView_GetItemCount(hwndLV))
				{
					//if(ListView_ == LVIS_SELECTED
					//printf("\nCurseur = %i, countSel = %i, nbSup = %i", curseur, countSel, nbSup);
					if(ListView_GetItemState(hwndLV, curseur, LVIS_SELECTED) == LVIS_SELECTED)
					{
						//lvi.iItem = curseur;
						/*if(ListView_GetItem(hwndLV, &lvi) != TRUE)
							break;*/

						ListView_DeleteItem(hwndLV, curseur--);

						nbSup++;
					}
					curseur++;
				}
			}
			break;

		case ITM_HISTO_RAPPEL:
			{
				HWND hwndLV = GetDlgItem(hwndDlg, LVW_HISTO);
				LV_ITEM lvi;
				char buffer[128];

				memset(&lvi, 0, sizeof(LV_ITEM));

				lvi.mask = LVIF_TEXT;
				lvi.stateMask = LVIF_TEXT;
				lvi.iItem = ListView_GetSelectionMark(GetDlgItem(hwndDlg, LVW_HISTO));

				if(ListView_GetItem(hwndLV, &lvi) != TRUE)
					break;


				ListView_GetItemText(hwndLV, lvi.iItem, 0, buffer, sizeof(buffer));

				SendDlgItemMessage(hwndDlg, TXT_FORMULE, WM_SETTEXT, (WPARAM)0, (LPARAM)buffer);
			}
			break;



		}
		break;

		case WM_NOTIFY:
		return On_Notify(hwndDlg, wParam, lParam);
		break;

		case WM_CLOSE:
			On_Close(hwndDlg, wParam, lParam);
		return TRUE;
	}
		return FALSE;
}


/*------------------------------------------------------------------------
 Procedure:
 Purpose:
 Input:
 Output:
 Errors:
------------------------------------------------------------------------*/
static int Calculer(HWND hwndDlg, char *formule)
{
	//char formule[1024];
	HWND hwndLV = GetDlgItem(hwndDlg, LVW_MESSAGES);
	double resultat;
	char buffer[256];
	CALC *calc;

	/* Pour le calcul de la formule */
	CALC_MSG *msg = NULL;

	//MessageBox(hwndDlg, formule, "COMPILATION ERROR", MB_ICONERROR|MB_OK);

	calc = CALC_Compile(formule);

	ListView_DeleteAllItems(hwndLV);

	while((msg = CALC_ReadMsgNext(calc)) != NULL)
	{
		InsererMessage(hwndLV, msg);
		SendDlgItemMessage(hwndDlg, TXT_FORMULE, EM_SETSEL, (WPARAM)msg->position-2, (LPARAM)msg->position-1);
		CALC_DestroyMsg(msg);
	}

	if(CALC_Error(calc))
	{
		//MessageBox(hwndDlg, "La formule contient une erreur de syntaxe.", "COMPILATION ERROR", MB_ICONERROR|MB_OK);
		SendDlgItemMessage(hwndDlg, LBL_RESULTAT, WM_SETTEXT, (WPARAM)0, (LPARAM)"Erreur de syntaxe");
		calc = CALC_Destroy(calc);
		return EXIT_FAILURE;
	}

	//ListView_DeleteAllItems(hwndLV);

	/* Définition de la table des variables à utiliser */
	CALC_SetVarTable(calc, calc_vartable, calc_nbvars);

	resultat = CALC_Calculate(calc);

	sprintf(buffer, "%s = %.16g", (CALC_GetAssignName(calc)!=NULL)?CALC_GetAssignName(calc):"Résultat", resultat);
	SendDlgItemMessage(hwndDlg, LBL_RESULTAT, WM_SETTEXT, (WPARAM)0, (LPARAM)buffer);

	while((msg = CALC_ReadMsgNext(calc)) != NULL)
	{
		InsererMessage(hwndLV, msg);
		CALC_DestroyMsg(msg);
	}

	if(CALC_Error(calc))
	{
		//MessageBox(hwndDlg, "La formule contient une erreur", "RUNTIME ERROR", MB_ICONERROR|MB_OK);
		SendDlgItemMessage(hwndDlg, LBL_RESULTAT, WM_SETTEXT, (WPARAM)0, (LPARAM)"Erreur d'execution");
		//calc = CALC_Detruire(calc);
		return EXIT_FAILURE;
	}

	/* Enregistrement de la valeur */
	{
		char *assign = CALC_GetAssignName(calc);
		int i;
		int trouvee = 0;

		/* Si un nom a été défini, on le recherche dans la table */
		if(assign != NULL)
		{
			for(i = 0 ; i < calc_nbvars ; i++)
			{
				/* Si on trouve la variable (elle existait donc déjà) on met à jour la valeur */
				if(strcmp(calc_vartable[i].name, assign) == 0)
				{
					calc_vartable[i].value = resultat;
					trouvee = 1;
					break;
				}
			}

			/* si on ne l'a pas trouvée, on l'ajoute */
			if(!trouvee)
			{
				/* On regarde de ne pas dépasser la limite fixe du nombre de variables */
				if(calc_nbvars < MAXVARTABLESIZE)
				{
					/* Enregistrement */
					calc_vartable[calc_nbvars].name = strdup(assign);
					calc_vartable[calc_nbvars].value = resultat;

					/* Incrémentation du nombre de variables */
					calc_nbvars++;
				}
				else
				{
					MessageBox(hwndDlg, "Dépassement de capacité! Vous avez atteint la limite du nombre"
					" de variables autorisé. Veuillez réutiliser celles que vous avez déjà utilisées.",
					"Dépassement de capacité", MB_ICONEXCLAMATION|MB_OK);
				}
			}
		}
	}



	CALC_Destroy(calc);

	InsererFormule(GetDlgItem(hwndDlg, LVW_HISTO), formule, resultat);

	return EXIT_SUCCESS;
}

/*------------------------------------------------------------------------
Procedure:     PHIDLUX_LV_InsererCompte ID:1
Purpose:
Input:
Output:
Errors:
------------------------------------------------------------------------*/
static int InsererMessage(HWND hwndLV, CALC_MSG *msg)
{
	/* Déclrations */
	int i = 0;
	LVITEM lvi;
	char chaine[512];

	/* Code */
	if(msg == NULL)
		return EXIT_FAILURE;

	/* Récupération du nombre d'items */
	i = ListView_GetItemCount(hwndLV);

	memset(&lvi, 0, sizeof(LVITEM));

	/* LVITEM commun*/
	lvi.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM|LVIF_STATE;
	lvi.state = 0;
	lvi.stateMask = 0;
	//lvi.lParam = (LPARAM)lv_lParam;

	switch(msg->tmsg)
	{
		case CALC_TMSG_UNKNOWN:
			sprintf(chaine, "%s", "INCONNU");
			break;

		case CALC_TMSG_INFO:
			sprintf(chaine, "%s", "INFO");
			break;

		case CALC_TMSG_WARNING:
			sprintf(chaine, "%s", "WARNING");
			break;

		case CALC_TMSG_ERROR:
			sprintf(chaine, "%s", "ERROR");
			break;

		case CALC_TMSG_SYNTAXERROR:
			sprintf(chaine, "%s", "SYNTAX_ERROR");
			break;

		case CALC_TMSG_RUNTIMEERROR:
			sprintf(chaine, "%s", "RUNTIME_ERROR");
			break;
	}

	// Initialize item-specific LVITEM members.
	//sprintf(chaine, "%i", msg->num);

	lvi.iItem = i;
	lvi.iImage = 0;
	lvi.iSubItem = 0;
	lvi.pszText = chaine;
	lvi.lParam = (LPARAM) NULL;

	/* insérer l'item*/
	ListView_InsertItem(hwndLV, &lvi);

	/* Numéro d'erreur */
	/*sprintf(chaine, "%i", msg->num);
	ListView_SetItemText(hwndLV, i, 1, chaine);*/

	/* Position */
	//sprintf(chaine, "%i", msg->position);
	//ListView_SetItemText(hwndLV, i, 1, chaine);

	/* Message */
	sprintf(chaine, "Position %i : %s", msg->position, msg->msg_info);
	ListView_SetItemText(hwndLV, i, 1, chaine);

	return EXIT_SUCCESS;
}

/*------------------------------------------------------------------------
Procedure:     PHIDLUX_LV_InsererCompte ID:1
Purpose:
Input:
Output:
Errors:
------------------------------------------------------------------------*/
static int InsererFormule(HWND hwndLV, char *formule, double resultat)
{
	/* Déclrations */
	int i = 0;
	LVITEM lvi;
	char chaine[512];

	/* Code */
	/* Récupération du nombre d'items */
	i = ListView_GetItemCount(hwndLV);

	memset(&lvi, 0, sizeof(LVITEM));

	/* LVITEM commun*/
	lvi.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM|LVIF_STATE;
	lvi.state = 0;
	lvi.stateMask = 0;
	//lvi.lParam = (LPARAM)lv_lParam;


	lvi.iItem = i;
	lvi.iImage = 0;
	lvi.iSubItem = 0;
	lvi.pszText = formule;
	lvi.lParam = (LPARAM) NULL;

	/* insérer l'item*/
	ListView_InsertItem(hwndLV, &lvi);

	/* Valeur */
	sprintf(chaine, "%.16g", resultat);
	ListView_SetItemText(hwndLV, i, 1, chaine);

	ListView_EnsureVisible(hwndLV, i, FALSE);

	return EXIT_SUCCESS;
}

/*------------------------------------------------------------------------
Procedure:
Purpose:
Input:
Output:
Errors:
------------------------------------------------------------------------*/
static BOOL menuContextuel(HWND hwnd, POINT *point, int QuelMenu)
{
	HMENU hMenu;
	HMENU hMenuTrackPopUp;


	/* Liste des comptes */

	hMenu = LoadMenu(hInst, MAKEINTRESOURCE(QuelMenu));
	if(!hMenu) return FALSE;

	hMenuTrackPopUp = GetSubMenu(hMenu, 0);

	//ClientToScreen(hwnd, point);
	TrackPopupMenu(hMenuTrackPopUp, 0, point->x, point->y, 0, hwnd, NULL);

	DestroyMenu(hMenu);
	DestroyMenu(hMenuTrackPopUp);


	return TRUE;

}



/*------------------------------------------------------------------------
Procedure:     On_Notify ID:1
Purpose:
Input:
Output:
Errors:
------------------------------------------------------------------------*/
static LRESULT On_Notify(HWND hwndDlg, WPARAM wParam, LPARAM lParam)
{
	/* Déclarations */
	NMHDR *nmhdr;
	nmhdr = (NMHDR*) lParam;

	switch(nmhdr->code)
	{
	case SEPN_RESIZE:
		{
			//SEPNOTIFY *sn = (SEPNOTIFY*) lParam;
			//contexte.tv_width = LOWORD(sn->limites);
			//On_Resize(hwndDlg);
		}
		break;

	case NM_CUSTOMDRAW:
		//return On_Customdraw(hwndDlg, wParam, lParam);
		break;

	case NM_RCLICK:
		return On_RightClick(hwndDlg, wParam, lParam);
		break;

	case NM_CLICK:
		return On_Click(hwndDlg, wParam, lParam);
		break;

	case NM_DBLCLK:
		return On_DoubleClick(hwndDlg, wParam, lParam);
		break;

	case TVN_SELCHANGED:
		//return On_TreeViewSelChanged(hwndDlg, wParam, lParam);
		break;
	}

	return FALSE;
}

/*------------------------------------------------------------------------
Procedure:     On_Click ID:1
Purpose:
Input:
Output:
Errors:
------------------------------------------------------------------------*/
static LRESULT On_Click(HWND hwndDlg, WPARAM wParam, LPARAM lParam)
{
	/* Déclarations */
	POINT point;

	/* Code */
	/* Récupération des coordonnées de la souris */
	GetCursorPos(&point);

	/* On regarde l'objet qui est concerné */
	switch(wParam)
	{
	case LVW_HISTO:

		break;

	default:
		return FALSE;
	}



	return FALSE;
}

/*------------------------------------------------------------------------
Procedure:     On_RightClick ID:1
Purpose:
Input:
Output:
Errors:
------------------------------------------------------------------------*/
static LRESULT On_RightClick(HWND hwndDlg, WPARAM wParam, LPARAM lParam)
{
	/* Déclarations */
	POINT point;

	/* Code */
	/* Récupération des coordonnées de la souris */
	GetCursorPos(&point);

	/* On regarde l'objet qui est concerné */
	switch(wParam)
	{
	case LVW_HISTO:
		{
			HMENU hMenu;
			HMENU hMenuTrackPopUp;


			/* Liste des comptes */

			hMenu = LoadMenu(hInst, MAKEINTRESOURCE(MNU_CTXHISTO));
			if(!hMenu) return FALSE;

			hMenuTrackPopUp = GetSubMenu(hMenu, 0);

			//ClientToScreen(hwnd, point);
			TrackPopupMenu(hMenuTrackPopUp, 0, point.x, point.y, 0, hwndDlg, NULL);

			DestroyMenu(hMenu);
			DestroyMenu(hMenuTrackPopUp);
		}
		break;


	default:
		return FALSE;
	}


	return FALSE;
}

/*------------------------------------------------------------------------
Procedure:     On_DoubleClick ID:1
Purpose:
Input:
Output:
Errors:
------------------------------------------------------------------------*/
static LRESULT On_DoubleClick(HWND hwndDlg, WPARAM wParam, LPARAM lParam)
{
	/* Déclarations */
	POINT point;

	/* Code */
	/* Récupération des coordonnées de la souris */
	GetCursorPos(&point);

	/* On regarde l'objet qui est concerné */
	switch(wParam)
	{
	case LVW_HISTO:
		{
			SendMessage(hwndDlg, WM_COMMAND, (WPARAM)MAKEWPARAM(ITM_HISTO_RAPPEL, 0), (LPARAM)0);
		}
		break;


	default:
		return FALSE;
	}


	return FALSE;
}

/*------------------------------------------------------------------------
Procedure:     On_Close ID:1
Purpose:
Input:
Output:
Errors:
------------------------------------------------------------------------*/
static LRESULT On_Close(HWND hwndDlg, WPARAM wParam, LPARAM lParam)
{
	/* Déclarations */

	/* Code */

	EndDialog(hwndDlg, 0);
	return TRUE;
}

/*------------------------------------------------------------------------
Procedure:
Purpose:
Input:
Output:
Errors:
------------------------------------------------------------------------*/
static int On_Resize(HWND hwndDlg)
{
#define TOP 0
#define BORDURE             5
#define STATUSBARHEIGHT    20
#define HAUTEURLVERREURS   100
#define HAUTEURLVHISTO    300
#define MARGEEXTERNE       10
#define MARGEINTERNE       10
#define MARGEINTERNEHAUT   20
#define MARGEINTERNEBAS    10

	/* Déclarations */
	int heightErreurs;
	int heightHisto;

	RECT rectLVErreurs;
	RECT rectLVHisto;
	RECT rectGRPErreurs;
	RECT rectGRPHisto;

	RECT rectMain;


	HWND hwndLVErreurs;
	HWND hwndLVHisto;

	/* Code */
	hwndLVErreurs = GetDlgItem(hwndDlg, LVW_MESSAGES);
	hwndLVHisto = GetDlgItem(hwndDlg, LVW_HISTO);

	GetClientRect(hwndDlg, &rectMain);
	//GetClientRect(hwndDlg, &rectLV);


	/* Redimmenssionnement du ListView d'erreurs */
	if(contexte.afficherErreurs)
	{
		ShowWindow(hwndLVErreurs, TRUE);
		heightErreurs = HAUTEURLVERREURS;
	}
	else
	{
		ShowWindow(hwndLVErreurs, FALSE);
		heightErreurs = 0;
	}

	if(contexte.afficherHisto)
	{
		ShowWindow(hwndLVHisto, TRUE);
		heightHisto = HAUTEURLVHISTO;
	}
	else
	{
		ShowWindow(hwndLVHisto, FALSE);
		heightHisto = 0;
	}

	rectGRPErreurs.top = 80;
	rectGRPErreurs.bottom = rectGRPErreurs.top + heightErreurs;
	rectGRPErreurs.left = MARGEEXTERNE;
	rectGRPErreurs.right = rectMain.right - MARGEEXTERNE;

	SetWindowPos(GetDlgItem(hwndDlg, GPB_FORMULE), NULL,
		rectGRPErreurs.left,
		rectGRPErreurs.top,
		rectGRPErreurs.right - rectGRPErreurs.left,
		rectGRPErreurs.bottom - rectGRPErreurs.top,
		SWP_NOZORDER );

	rectLVErreurs.top = rectGRPErreurs.top + MARGEINTERNEHAUT;
	rectLVErreurs.bottom = rectGRPErreurs.bottom - MARGEINTERNEBAS;
	rectLVErreurs.left = rectGRPErreurs.left + MARGEINTERNE;
	rectLVErreurs.right = rectGRPErreurs.right - MARGEINTERNE;

	SetWindowPos(hwndLVErreurs, NULL,
		rectLVErreurs.left,
		rectLVErreurs.top,
		rectLVErreurs.right - rectLVErreurs.left,
		rectLVErreurs.bottom - rectLVErreurs.top,
		SWP_NOZORDER );

	/**********************/

	rectGRPHisto.top = rectGRPErreurs.bottom + MARGEEXTERNE;
	rectGRPHisto.bottom = rectMain.bottom - STATUSBARHEIGHT - MARGEEXTERNE;
	rectGRPHisto.left = MARGEEXTERNE;
	rectGRPHisto.right = rectMain.right - MARGEEXTERNE;

	SetWindowPos(GetDlgItem(hwndDlg, GPB_HISTO), NULL,
		rectGRPHisto.left,
		rectGRPHisto.top,
		rectGRPHisto.right - rectGRPHisto.left,
		rectGRPHisto.bottom - rectGRPHisto.top,
		SWP_NOZORDER );

	rectLVHisto.top = rectGRPHisto.top + MARGEINTERNEHAUT;
	rectLVHisto.bottom = rectGRPHisto.bottom - MARGEINTERNEBAS;
	rectLVHisto.left = rectGRPHisto.left + MARGEINTERNE;
	rectLVHisto.right = rectGRPHisto.right - MARGEINTERNE;

	SetWindowPos(hwndLVHisto, NULL,
		rectLVHisto.left,
		rectLVHisto.top,
		rectLVHisto.right - rectLVHisto.left,
		rectLVHisto.bottom - rectLVHisto.top,
		SWP_NOZORDER );


	return 0;
}

/*------------------------------------------------------------------------
Procedure:     LISTVIEW_InsertColumn ID:1
Purpose:
Input:
Output:
Errors:
------------------------------------------------------------------------*/
static BOOL LISTVIEW_InsertColumn(HWND lv,  char *titreColonne,
	int taille, int format, int emplacement)
{
	/*************************************************
	*
	* Déclaration des variables
	*
	*************************************************/


	LVCOLUMN lvc;

	/*************************************************
	*
	* Code
	*
	*************************************************/


	if(lv == NULL) return TRUE;


	lvc.pszText= titreColonne;
	lvc.cx = taille;
	lvc.mask = LVCF_FMT|LVCF_WIDTH|LVCF_TEXT;
	lvc.fmt = format;
	//lvc.iSubItem = 0;

	if (ListView_InsertColumn(lv, emplacement, &lvc) == -1) return FALSE;


	return TRUE;
}

/*------------------------------------------------------------------------
Procedure:     enregClassedialog ID:1
Purpose:
Input:
Output:
Errors:
------------------------------------------------------------------------*/
static BOOL enregClassedialog(HINSTANCE hInst)
{
	/*
	* declaration des variables locales
	* =================================
	*/
	WNDCLASSEX wcx;
/*
a1 = nomClasse
a2 = nomMenu
a3 = nomIcone
*/
	/*
	* code executable
	* ===============
	*/
	memset(&wcx,0,sizeof(WNDCLASSEX));

	wcx.cbSize = sizeof(WNDCLASSEX);
	wcx.lpfnWndProc = DefDlgProc;
	wcx.cbWndExtra = DLGWINDOWEXTRA;
	wcx.hInstance = hInst;
	wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcx.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
	wcx.lpszClassName = "dialog";
	wcx.lpszMenuName = MAKEINTRESOURCE(MNU_MAIN);
	wcx.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(ICO_MAIN));
	wcx.hIconSm = NULL;


	if(RegisterClassEx(&wcx))
   		return TRUE;
	else
    	return FALSE;
}


/*------------------------------------------------------------------------
 Procedure:     replaceChar ID:1
 Purpose:       Remplace dans une chaine un caractère par un autre
 Input:         Chaine à traiter
                Caractère à remplacer
                Caractère remplacant
 Output:        aucun
 Errors:
------------------------------------------------------------------------*/
void MYSTRINGS_ReplaceChar(char *chaineSrc, int carDest, int carSrc)
{
	char *lpstr;

	/* On enregistre le pointeur sur la chaine */
	lpstr = chaineSrc;

	/* Boucle de substitution des caractères */
	while(*lpstr != '\0')
	{
		if(*lpstr == carDest) *lpstr = carSrc;

		*lpstr++;
	}

}



