MODULE menu INTERFACE;

{*
	Este módulo proporciona la función para iniciar el programa, que a su vez
	llama a las funciones necesarias para cada opción de la aplicación.
*}

export menu = (drawMenu, menuItems, menuLabels);

CONST
	
	{Indica la última opción disponible en el menú principal.}
	LAST_ITEM	= 'f';
	
TYPE
	
	{Tipos para el texto de las opsiones del menú principal.}
	MenuItems = set of 'a'..LAST_ITEM;
	MenuLabels = array['a'..LAST_ITEM] of string(57);
	
{*
	Dibuja el menú principal de la aplicación y llama a selectMenuOption.
	Devuelve un entero que es utilizado por el programa principal para
	determinar si debe repetir de nuevo drawMenu (> 0), en cuyo caso pasará
	dicho entero de nuevo a la función mediante m, el cual puede indicar a
	la misma que debe imprimir un mensaje informativo bajo el título de la
	aplicación. options son las opciones disponibles en el menú principal.
*}
function drawMenu(var options:MenuLabels; m:integer):integer;

{*
	Pide un caracter mediante la entrada estándar, el cual se utiliza para
	determinar qué opción de las disponibles (options) desea seleccionar
	el usuario. Devuelve un entero el cual es utilizado por el programa para
	determinar si debe repetir drawMenu o permitir la finalización de la
	aplicación (realmente es la propia función drawMenu la que devuelve este
	mismo entero al programa principal).
*}
function selectMenuOption(var options:MenuLabels):integer;

END.

MODULE menu IMPLEMENTATION;

IMPORT
	
	standardoutput;
	display;
	filesystem;
	filteredinput;
	printlist;
	sort;
	
function drawMenu;
var
	
	i:char value 'a';
	
begin
	
	clearDisplay;
	
	setTitle('Menú principal');
	
	for i := 'a' to LAST_ITEM do
	begin
		
		write(i, '. ', options[i]);
		downLines(1);
		
	end;
	
	downLines(1);
	moveMargin(-4);
	write('Introduzca la letra correspondiente a la opción del menú y pulse intro: ');
	
	if m > 0 then
		
		case m of
			
			1: setError('Opción inválida.');
			2: setError('Opción inválida. Comprueba el estado del bloqueo de mayúsculas en el teclado.');
			3: setMssg('Los datos del nuevo alumno han sido guardados corréctamente.');
			4: setError('No ha sido posible guardar los datos del nuevo alumno en el fichero ./data');
			5: setMssg('Datos guardados corréctamente.');
			6: setMssg('No se ha modificado nada en la base de datos.');
			7: setMssg('La base de datos no contiene alumnos.');
			
			otherwise;
			
		end;
		
	;
	
	drawMenu := selectMenuOption(options);
	
end;

function selectMenuOption;
var
	
	items:MenuItems value ['a'..LAST_ITEM];
	dataDump:PtrToDump;
	option:char;
	optionValue:integer;
	
begin
	
	readChar(option);
	
	if option in items then
	begin
		
		case option of
			
			'a': selectMenuOption := newStudent;
			'b': selectMenuOption := editStudent;
			'c':
			begin
				
				newDump(dataDump);
				
				if dataDump = NIL then selectMenuOption := 7
				else
				begin
					
					bubbleSortAlphabetical(dataDump);
					
					printOrdered(dataDump, -1);
					
					disposeDump(dataDump);
					
					selectMenuOption := 255;
					
				end;
				
			end;
			'd':
			begin
				
				clearDisplay;
				setTitle('Elegir convocatoria');
		
				setMssg('Deja en blanco el campo y pulsa intro para volver al menú principal.');
				
				write('Convocatoria [f/j/s/d]: ');
				readChar(option);
				
				while not (option in MONTHS + ['']) do
				begin
					
					setError(
						'Solo se admiten como valores válidos la inicial de los meses Febrero, Junio, Septiembre y Diciembre.'
					);
					clearLine;
					write('Convocatoria [f/j/s/d]: ');
					readChar(option);
					
				end;
				
				case option of
					
					'f', 'j': optionValue := 0;
					's': optionValue := 1;
					'd': optionValue := 2;
					
					otherwise optionValue := -1;
					
				end;
				
				if optionValue > -1 then
				begin
					
					newDump(dataDump);
					
					if dataDump = NIL then selectMenuOption := 7
					else
					begin
						
						bubbleSortAlphabetical(dataDump);
						
						printOrdered(dataDump, optionValue);
						
						disposeDump(dataDump);
						
						selectMenuOption := 255;
						
					end;
					
				end
				else selectMenuOption := 255;
				
			end;
			'e':
			begin
				
				clearDisplay;
				setTitle('Elegir convocatoria');
		
				setMssg('Deja en blanco el campo y pulsa intro para volver al menú principal.');
				
				write('Convocatoria [f/j/s/d]: ');
				readChar(option);
				
				while not (option in MONTHS + ['']) do
				begin
					
					setError(
						'Solo se admiten como valores válidos la inicial de los meses Febrero, Junio, Septiembre y Diciembre.'
					);
					clearLine;
					write('Convocatoria [f/j/s/d]: ');
					readChar(option);
					
				end;
				
				case option of
					
					'f', 'j': optionValue := 0;
					's': optionValue := 1;
					'd': optionValue := 2;
					
					otherwise optionValue := -1;
					
				end;
				
				if optionValue > -1 then
				begin
					
					newDump(dataDump);
					
					if dataDump = NIL then selectMenuOption := 7
					else
					begin
						
						bubbleSortByMarks(dataDump, optionValue);
						
						printOrdered(dataDump, optionValue);
						
						disposeDump(dataDump);
						
						selectMenuOption := 255;
						
					end;
					
				end
				else selectMenuOption := 255;
				
			end;
			'f': selectMenuOption := 0;
			
		end;
		
	end
	else if (ord(option) > 64) and (ord(option) < 91) then selectMenuOption := 2
	else selectMenuOption := 1;
	;
	
end;

END.
