/*
*	console.h
*
*	Programmé par Hillaire Sébastien
*
*
*	- utilité :
*		Permet d'afficher un console de saisie à l'écran
*
*	- version :
*		1.0
*
*	- update :
*		09/09/2004 : ajout de la complétion automatique avec suggestion
*		05/08/2004 : BUG corriger dans add command : on pointe directement sur la chaine de caractère
*		17/07/2004 : - Ajout de l'alpha testing pour les carte ATI.(sinon problème spécifique ATI)
*		30/06/2004 : - Correction d'un Bug
*					 - Prise en compte du clignotement du curseur
*		21/06/2004 : première version
*
*	- NOTE :
*		Implementer d'autre méthode de console_ comme couleur,taille char....
*		Prendre en compte fichier de log
*		prendre en compte les espaces intelligement!
*
*/

#ifndef CONSOLE_H
#define CONSOLE_H

#ifdef WIN32
#include "windows.h"
#endif

#include "glFont2D.h"
#include <iostream>
#include <cstdarg>
#include <stdlib.h>
#include <Vector>

#include "MemoryManager/DebugNew.h"


namespace RenderSystem{


	//Definition des touches spécials pour la console
	#define CONSOLE_SUPPR_BACK	8
	#define CONSOLE_VALIDATE	13
	#define CONSOLE_SUPPR		127
	#define CONSOLE_CLOSE		178
	#define CONSOLE_COMPLETION	9
	#define CONSOLE_INSERT		-1
	#define CONSOLE_HOME		-2
	#define CONSOLE_END			-3
	#define CONSOLE_PG_UP		-4
	#define CONSOLE_PG_DOWN		-5
	#define CONSOLE_LEFT		-6
	#define CONSOLE_RIGHT		-7
	#define CONSOLE_UP			-8
	#define CONSOLE_DOWN		-9


	class Console;							//pré-définition pour Console_Command

	#define MAX_CHAR_PER_LINE	256			//LE nombre de caratères maximum dans une ligne de commande

	/**
	* représente une ligne à afficher dans la console
	*/
	struct Console_Line
	{
		/**
		* indique si c'est l'utilisateur qui a entré la ligne(pour historique)
		*/
		bool			isUserCommand;
		/**
		* la couleur de la ligne
		*/
		float			color[4];
		/**
		* la ligne de commande(maximum 256 caractères) +30 pour la concaténation de 'unknow message'
		*/
		char			cmd[MAX_CHAR_PER_LINE+30];
	};

	/**
	* représente une commande : le nom de la commande et la fonction a appelé
	*/
	struct Console_Command
	{
		/**
		* le nom de la commande(première chaine dans la ligne
		*/
		char			*command_name;
		/**
		* le pointeur sur la fonction à éxecuter
		*
		* @param char* la ligne tapez par l'utilisateur
		* @param Console* la console qui appele la méthode
		*/
		void			(*command_func)(char*, Console*);
	};


	/**
	* Permet de gérer facilement une console avec les commandes disponibles et leur actions associées.
	*/
	class Console
	{
	private:
		/**
		* Permet d'effacer une chaine de caractère
		*
		* @param c le pointeur sur la chaine de caractère
		* @param len la longueur de la chaine de caractère
		*/
		void RAZchars(char *c, int len);

		/**
		* Permet d'afficher à l'écran les dernières commandes
		*/
		void renderLines();

		/**
		* un chaine temporaire
		*/
		char			ctmp[MAX_CHAR_PER_LINE+1];
		
		/**
		* Indique que la ligne courante a changer
		*/
		bool linehaschange;
		
		/**
		* Le dernier numéro de la liste de commande acceptable pour la complétion
		*/
		int lastCompletionNum;
		
		/**
		* Le vecteur contenant la liste des numéros des commandes possible pour la complétion courante
		*/
		std::vector<int> PossibleCompletionNum;
		
		/**
		* contient la chaine de char de la ligne courante avant la demande de complétion
		*/
		char tmpcompletion[MAX_CHAR_PER_LINE];
		
		/**
		* uen chaine temporaire de travail(utilisé dans DispMessage avec argument variable par exemple)
		*/
		static char tmpString[MAX_CHAR_PER_LINE];

	protected:

		//UTILITAIRES
		/**
		* permet de dessinner à l'écran
		*/
		glFont2D		glFont;

		//LES COMMANDES
		/**
		* le vecteur de commandes valides
		*/
		std::vector <Console_Command> cCmds;

		//CONTRÔLE DES LIGNES
		/**
		* le vecteur de ligne
		*/
		std::vector <Console_Line> cLines;
		/**
		* le nombre de caractères de la ligne courantes
		*/
		int				nbChar;
		/**
		* la ligne courante
		*/
		Console_Line	curLine;

		//ETAT DE LA CONSOLE
		/**
		* true si la console est ouverte
		*/
		bool			isActive;
		/**
		* la couleur/transparence du fond
		*/
		float			bgColor[4];
		/**
		* la couleur et la transparence des commands
		*/
		float			fgColor[4];
		/**
		* indique si le mode INSERT est actif
		*/
		bool			insert;
		/**
		* la pos du curseur de commande pour la recherche de commande précedente
		*/
		int				cmdCursorPos;
		/**
		* La position du curseur dans la ligne courante
		*/
		int				cursorPos;
		/**
		* le temps de clignotement du curseur en millisec
		*/
		int				cursorBlinkTime;
		/**
		* le temps courant de clignotement du curseur en millisec
		*/
		int				curBlinkTime;

		//TAILLE DE LA CONSOLE
		/**
		* le rapport largeur/hauteur de l'écran
		*/
		float			rapportWH;
		/**
		* la hauteur de la console en pourcentage de l'écran
		*/
		float			cheight;

		//TAILLE CARACTERES
		/**
		* le nombre de caratères par ligne
		*/
		float			charSize;
		/**
		* le nombre de caratères par ligne
		*/
		int				charPerLine;


		/**
		* Execute la commande de l'utilisateur si elle existe
		*
		* cl le pointeur sur la ligne de commande
		*/
		void execCmd(Console_Line *cl);

	public:

		/**
		* Constructeur
		*
		* @param rapport Le rapport largeur/hauteur de l'écran
		* @param consoleRapport Le % pris par l'écran quand la console est ouverte
		* @param nbCharCharPerLine le nombre de caractère par ligne
		* @param idTexFont l'identifiant OpenGL de la texture de Font valide
		*/
		Console(float rapport,float consoleRapport,int nbCharCharPerLine, unsigned int idTexFont);

		/**
		* Destructeur
		*/
		virtual ~Console();

		/**
		* Permet de récupérer une touche enfoncée
		*
		* @param key Le code ASCII de la touche ou un code CONSOLE_
		*/
		void keyTyped(int key);

		/**
		* Permet d'ajouter une commande à la console
		*
		* @param name Le nom de la commande
		* @param command_func Le pointeur sur la fonction a appeler
		*/
		void addCommand(char *name, void (*command_func)(char*, Console*));

		/**
		* Permet d'afficher à l'écran la console
		*/
		void render();

		/**
		* Permet d'updater la console en fonction du temps pour le clignotememnt du curseur par exemple.
		*
		* @param time : le temps écoulé depuis la dernière frame en millisecondes.
		*/
		void update(unsigned int time);

		/**
		* Indique si la console est ouverte
		*
		* @return true si la console est ouverte
		*/
		bool isOpen();

		/**
		* Ouvre la console
		*/
		void Open();

		/**
		* Affiche une message dans la console
		*
		* r la composante rouge de la couleur du message
		* g la composante verte de la couleur du message
		* b la composante bleue de la couleur du message
		* msg la message texte a afficher
		*/
		void DispMsg(float r,float g,float b,float a,char* msg);

		/**
		* Affiche une message dans la console
		*
		* r la composante rouge de la couleur du message
		* g la composante verte de la couleur du message
		* b la composante bleue de la couleur du message
		* @param chaine la coordonnée chaine, la chaine des caractère afficher avec les atribut%
		*pour les valeur supplémentaire
		* @param ... les attribut suplémentaire
		*/
		void DispMsg(float r,float g,float b,float a, const char *chaine, ...);
	};

};// namespace renderer

#include "MemoryManager/DebugNewOff.h"

#endif