program VideoClub;

uses crt, sysutils;

type
	adher = record
		num : integer;
		nom : string;
		prenom : string;
	end;
	movie = record
		titre : string;
		categ : string;
		num : integer;
		date : string;
	end;
	ptr_adh = ^adh;
	ptr_film = ^film;
	adh = record
		val : adher;
		suiv : ptr_adh;
	end;
	film = record
		val : movie;
		suiv : ptr_film;
	end;



procedure affichAdh(x : ptr_adh);
begin
	if x <> nil then
	begin
		writeln('n°',x^.val.num,' : ',x^.val.nom,' ',x^.val.prenom);
		affichAdh(x^.suiv);
	end;
end;

function disponible(x : ptr_film):string;
begin
	if x^.val.date = 'DISPO' then
		disponible := 'DISPONIBLE'
	else
		disponible := 'Loué le '+x^.val.date+' par n°'+intToStr(x^.val.num);
end;

procedure affichFilms(x : ptr_film; disp : boolean);
begin
	if x <> nil then
	begin
		if not disp or (x^.val.date = 'DISPO') then
			writeln(disponible(x),' : ',x^.val.titre,' (',x^.val.categ,')');
		affichFilms(x^.suiv,disp);
	end;
end;

procedure nvAdh(var x : ptr_adh ; var nb_adh : integer);
var
	nv,tmp : ptr_adh;
begin
	new(nv);
	nv^.suiv := nil;
	nb_adh := nb_adh + 1;
	nv^.val.num := nb_adh;
	writeln('Nom de l''adhérent ?');
	readln(nv^.val.nom);
	writeln('Prénom de l''adhérent ?');
	readln(nv^.val.prenom);
	if x = nil then
		x := nv
	else
	begin
		tmp := x;
		while tmp^.suiv <> nil do
			tmp := tmp^.suiv;
		tmp^.suiv := nv;
	end;
	writeln('Adhérent crée');
end;

procedure supprAdhNum(var x : ptr_adh ; choix : integer);
var
	tmp : ptr_adh;
begin
	if x^.suiv = nil then
		writeln('User not found')
	else if x^.suiv^.val.num = choix then
	begin
		tmp := x^.suiv;
		if not (tmp = nil) then
			x^.suiv := tmp^.suiv
		else
			x^.suiv := nil;
		dispose(tmp);
	end
	else
		supprAdhNum(x^.suiv,choix);
end;

procedure supprAdh(var x : ptr_adh);
var
	choix : integer;
	tmp : ptr_adh;
begin
	if not (x = nil) then
		repeat
			clrscr;
			affichAdh(x);
			writeln('Rechercher n° adhérent ? (0 pour annuler)');
			readln(choix);
			if choix > 0 then
				if x^.val.num = choix then
				begin
					tmp := x;
					x := x^.suiv;
					dispose(tmp);
				end
				else
				supprAdhNum(x,choix);
		until (choix >= 0)
	else
		writeln('Pas d''adhérents!');
end;

procedure supprFilmNum(var x : ptr_film ; choix : integer);
var
	tmp : ptr_film;
begin
	if x^.suiv = nil then
		writeln('User not found')
	else if x^.suiv^.val.num = choix then
	begin
		tmp := x^.suiv;
		if not (tmp = nil) then
			x^.suiv := tmp^.suiv
		else
			x^.suiv := nil;
		dispose(tmp);
	end
	else
		supprFilmNum(x^.suiv,choix);
end;

procedure supprFilm(var x : ptr_film);
var
	choix : integer;
	tmp : ptr_film;
begin
	if not (x = nil) then
		repeat
			clrscr;
			affichFilms(x,TRUE);
			writeln('Rechercher n° film ? (0 pour annuler)');
			readln(choix);
			if choix > 0 then
				if x^.val.num = choix then
				begin
					tmp := x;
					x := x^.suiv;
					dispose(tmp);
				end
				else
				supprFilmNum(x,choix);
		until (choix >= 0)
	else
		writeln('Pas de films!');
end;
	
procedure nvFilm(var x : ptr_film);
var
	nv,tmp : ptr_film;
begin
	new(nv);
	nv^.suiv := nil;
	nv^.val.num := -1;
	writeln('Nom du film ?');
	readln(nv^.val.titre);
	writeln('Catégorie du film ?');
	readln(nv^.val.categ);
	nv^.val.date := 'DISPO';
	if x = nil then
		x := nv
	else
	begin
		tmp := x;
		while tmp^.suiv <> nil do
			tmp := tmp^.suiv;
		tmp^.suiv := nv;
	end;
	writeln('Film inséré');
end;

procedure disposeAll(var x : ptr_film);
var
	tmp : ptr_film;
begin
	if x <> nil then
	begin
		tmp := x^.suiv;
		dispose(x);
		disposeAll(tmp);
	end;
end;

procedure disposeAllBis(var x : ptr_adh);
var
	tmp : ptr_adh;
begin
	if x <> nil then
	begin
		tmp := x^.suiv;
		dispose(x);
		disposeAllBis(tmp);
	end;
end;

function searchFilm(x : ptr_film ; choix : integer):ptr_film;
begin
	if x = nil then
		searchFilm := x
	else if x^.val.num = choix then
		searchFilm := x
	else
		searchFilm := searchFilm(x^.suiv,choix);
end;

procedure louerFilm(var x : ptr_film ; y : ptr_adh);
var
	choix, numadh : integer;
	valide : boolean;
	tmp : ptr_film;
begin
	clrscr;
	affichAdh(y);
	writeln('');
	writeln('Quel adhérent va louer (n°) ?');
	readln(numadh);
	clrscr;
	affichFilms(x,TRUE);
	valide := x = nil;
	if valide then writeln('Il n''y a aucun film');
	while not valide do
	begin
		writeln('Quel film louer (n°) ?');
		readln(choix);
		tmp := searchFilm(x,choix);
		if tmp = nil then
			writeln('Film introuvable!')
		else if not (tmp^.val.date = 'DISPO') then
			writeln('Ce film n''est pas disponible')
		else
		begin
			tmp^.val.num := numadh;
			tmp^.val.date := '30/04/2012';
			valide := TRUE;
		end;
	end;
end;

procedure rendreFilm(var x : ptr_film);
var
	choix : integer;
	valide : boolean;
	tmp : ptr_film;
begin
	affichFilms(x,TRUE);
	valide := x = nil;
	if valide then writeln('Il n''y a aucun film!');
	while not valide do
	begin
		writeln('Quel film louer (n°) ?');
		readln(choix);
		tmp := searchFilm(x,choix);
		if tmp = nil then
			writeln('Film introuvable!')
		else if tmp^.val.date = 'DISPO' then
			writeln('Ce film n''est pas loué!')
		else
		begin
			tmp^.val.num := -1;
			tmp^.val.date := 'DISPO';
			valide := TRUE;
		end;
	end;
end;

var
	nb_adh, choix : integer;
	films : ptr_film;
	adhs : ptr_adh;
begin
	films := nil;
	adhs := nil;
	nb_adh := 0;
	repeat
		repeat
			writeln('Choisir une procédure');
			writeln('1. Ajouter adhérent');
			writeln('2. Ajouter film');
			writeln('3. Afficher adhérents');
			writeln('4. Afficher films');
			writeln('5. Supprimer adhérent');
			writeln('6. Supprimer films');
			writeln('7. Louer film');
			writeln('8. Rendre film');
			writeln('0. Quitter');
			readln(choix);
			clrscr;
		until (choix >= 0) and (choix <= 8);
		case choix of
			0 : begin
				disposeAll(films);
				disposeAllBis(adhs);
			end;
			1 : nvAdh(adhs,nb_adh);
			2 : nvFilm(films);
			3 : affichAdh(adhs);
			4 : affichFilms(films,FALSE);
			5 : supprAdh(adhs);
			6 : supprFilm(films);
			7 : louerFilm(films,adhs);
			8 : rendreFilm(films);
		end;
	until choix = 0;
end.
