program GUI;

uses crt, gLib2D, sdl_addon, sdl, sdl_ttf, sysutils;

// -------------- Pointer stuff

type
	ptr_text = ^_ptr_text;
	_ptr_text = record
		text : string;
		next : ptr_text;
	end;
		
procedure disposeAllTxt(txt : ptr_text);
var
	tmp : ptr_text;
begin
	if txt <> nil then
	begin
		tmp := txt^.next;
		dispose(txt);
		disposeAllTxt(tmp);
	end;
end;

// -------------- Background

procedure blitBG(bgImg : gImage);
begin
	gBeginRects(bgImg);
		gSetAlpha(255);
		gSetCoordMode(g_up_left);
		gSetCoord(0,0);
		gAdd;
	gEnd;	
end;

// -------------- Input

procedure blitInput(inputImg : gImage ; line_status : integer ; bottom : boolean);
begin
	gBeginRects(inputImg);
		if (line_status = -1) then gSetAlpha(100) else gSetAlpha(255);
		gSetCoordMode(g_up_left);
		if bottom then gSetCoord(75,499) else gSetCoord(75,450);
		gSetColor(white);
		gAdd;
	gEnd;
end;

procedure showInput(input : ptr_text ; font : PTTF_font ; var line_status : integer ; bottom : boolean);
var
	buffer : gImage;
begin
	buffer := gTextLoad(input^.text,font);
	blitInput(buffer,line_status,bottom);
	gTexFree(buffer);
	if (buffer^.w > 420) and (input^.next = nil) then
		line_status := 1;
	if not bottom and (input^.next <> nil) then showInput(input^.next,font,line_status,true);
end;

// -------------- Chatlog

procedure blitChatlog(chatlogImg : gImage ; y : integer);
begin
	gBeginRects(chatlogImg);
	        gSetAlpha(255);
	        gSetCoordMode(g_up_right);
	        gSetCoord(510,y);
	        gSetColor(white);
	        gAdd;
	gEnd;
end;

procedure showChatlog(chatlog : ptr_text ; font : PTTF_font ; y : integer);
var
	buffer : gImage;
begin
	if (chatlog <> nil) and (y > 0) then
	begin
		buffer := gTextLoad(chatlog^.text,font);
		blitChatlog(buffer,y);
		gTexFree(buffer);
		showChatlog(chatlog^.next,font,y-49);
	end;
end;

// -------------- Other blitting

procedure wholeBlit(bg : gImage ; input, chatlog : ptr_text ; font : PTTF_font ; var line_status : integer);
begin
        blitBG(bg);
	showChatlog(chatlog,font,334);
        showInput(input,font,line_status,false);
        gFlip;
end;

// -------------- Keyboard/Updates

//function update(var input : string) : integer;
// Fonction de gestion des événements
//var

procedure sdl_key(var input : ptr_text; key : integer; var line_status : integer);
var
	backup, tmp : ptr_text;
begin
	backup := input;
	while input^.next <> nil do
		input := input^.next;
	
        case key of
                SDLK_backspace :
		        if (length(input^.text) = 1) then
		        begin
		        	if (input = backup) then
			        begin
			                input^.text := '< Tapez votre message >';
			                line_status := -1;
			        end
			        else
			        begin
			        	dispose(input);
			        	input := backup;
					while input^.next <> nil do
						input := input^.next;
			        end
			end
		        else if line_status = 0 then
		                input^.text := copy(input^.text,1,length(input^.text)-1);
        else if line_status = -1 then
        begin
                line_status := 0;
                input^.text := chr(key);
        end
        else if line_status = 1 then
        begin
        	new(tmp);
        	tmp^.text := chr(key); // TO DO : Accompagnement du mot attaché avec le saut de ligne
        	tmp^.next := nil;
        	input^.next := tmp;
        	line_status := 0;
        end
        else
                input^.text := input^.text+chr(key);
        end;
        input := backup;
end;

// -------------- Main procedures

procedure main();
// Procédure principale du GUI
var
	chatlog : ptr_text; // Messages envoyés/reçus
	input : ptr_text; // Message potentiel à envoyer
	tmp : ptr_text;
	event : integer; // Détermine un événement
	// 0 = Etat initial, 1 = Envoi du message utilisateur, 2 = Retour du bot, 3 = Quitter
	line_status : integer; // Détermine si l'input est vide (-1), une ligne est pleine (1) ou autre (0)
	font : PTTF_font; // Police
	bg : gImage;
	
begin
	gClear(black);
	new(input);
	new(chatlog);
	new(tmp);
	
        font := TTF_OpenFont('font.ttf', 30); // Police
        line_status := -1; // Champ texte vide
        event := 0; // Etat initial
        
        bg := gTexLoad('background.jpg'); // Initialisation background
        
        chatlog^.text := 'Salutations, jeune ami(e) !'; // Initialisation chatlog
        tmp^.text := 'EISTI-Bot dit :';
        tmp^.next := nil;
        chatlog^.next := tmp;

        input^.text := '< Tapez votre message >'; // Initialisation champ texte
        input^.next := nil;
        
        wholeBlit(bg,input,chatlog,font,line_status);
        
        while true do
        begin
                while sdl_update = 1 do
                begin
                        if (sdl_get_keypressed > 0) then
                        begin
                                sdl_key(input,sdl_get_keypressed,line_status);
                                wholeBlit(bg,input,chatlog,font,line_status);
			end;
                        if sdl_do_quit then
                                exit;
                end;
        end;
        
        gTexFree(bg);
       	disposeAllTxt(input);
       	disposeAllTxt(chatlog);
end;

begin
	main();
end.