program tri_graphique;
	uses
		Wait, Getclick;

	const
		X0 = 5;							{coordonnees du rectangle de jeu par rapport a Drawing}
		X1 = 500;
		Y0 = 5;
		Y1 = 300;
		MAX = 10;									   {nombre maximal de rectangles}

	type
		element = Rect;
		tab_element = array[1..MAX] of element;
		chaine = string;

	var
		nb_element: integer;									{nombre de rectangles}
		r, f, jeu, tri, stop: Rect;
		p: Point;
		tab: tab_element;                                       {tableau d'elements, ici un element est un rectangle}
{--------------------------------------------------------------------------------------------}

	function est_dans (r: Rect; p: Point): boolean;
		var
			b: boolean;
	begin
		b := false;
		if (r.left <= p.h) and (p.h <= r.right) and (r.top <= p.v) and (p.v <= r.bottom) then
			b := true;
		est_dans := b;
	end;

	function est_rectangle (r: Rect): boolean;
		var
			b: boolean;
	begin
		b := false;
		if (r.left <= r.right) and (r.top <= r.bottom) then
			b := true;
		est_rectangle := b;
	end;

	procedure ajouter (r: Rect; var tab: tab_element);
	begin
		if nb_element < MAX then
			begin
				nb_element := nb_element + 1;
				tab[nb_element] := r;
			end;
	end;

{---------------------------------------tri-----------------------------------------}
	function sup (var tab: tab_element; i: integer; x: element; critere: chaine): boolean;
{renvoie vrai si tab[i] > x selon le critere}
	begin
		if critere = 'abs_gauche' then
			sup := (tab[i].left > x.left);
		if critere = 'ord_gauche' then
			sup := (tab[i].top > x.top);
	end;

	procedure trier (var tab: tab_element; n: integer; critere: chaine);
{on fait un tri par insertion des n premiers elements du tableau selon le critere donne}
{en parametre qui est abs_gauche ou ord_gauche}
		var
			i, k: integer;
			x: element;
			b: boolean;
	begin
		if n = 1 then
		else
			for k := 2 to n do
				begin
					x := tab[k];
					i := k - 1;
					b := true;
					while sup(tab, i, x, critere) and b do
						begin
							tab[i + 1] := tab[i];
							i := i - 1;
							if i = 0 then
								begin
									b := false;
									i := 1;
								end;
							if b then
								tab[i + 1] := x
							else
								tab[1] := x;
						end;
				end;
	end;
{------------------------------------dessin et initialisation-------------------------------}
	procedure nettoyer_dessin;
	begin
		SetRect(jeu, X0, Y0, X1, Y1);                  {rectangle de jeu a nettoyer}
		FillRect(jeu, white);
		FrameRect(jeu);
		SetRect(tri, X0, Y0, X0 + 20, Y0 + 20);
		FillRect(tri, gray);                                 {le carre gris sera le bouton de tri}
		SetRect(stop, X0 + 20, Y0, X0 + 40, Y0 + 20);
		FillRect(stop, black);                             {le carre noir sera le bouton de stop}
	end;

	procedure dessiner (var tab: tab_element);
		var
			i: integer;
	begin
		nettoyer_dessin;
		for i := 1 to nb_element do
			begin
				PaintRect(tab[i]);
				Wait(30);                                          {Attente d'une demi seconde}
			end;
	end;

	procedure initialiser;
	begin
		SetRect(f, 40, 40, 600, 400);              {fenetre  Drawing}
		SetDrawingRect(f);
		ShowDrawing;
		SetRect(jeu, X0, Y0, X1, Y1);               {rectangle de jeu}
		FrameRect(jeu);
		SetRect(tri, X0, Y0, X0 + 20, Y0 + 20);
		FillRect(tri, gray);                                {le carre gris sera le bouton de tri}
		SetRect(stop, X0 + 20, Y0, X0 + 40, Y0 + 20);
		FillRect(stop, black);                             {le carre noir sera le bouton de stop}
		nb_element := 0;
	end;
{---------------------------------------------------------------------------------------}
begin  {principal}
	initialiser;
	repeat
		begin
			GetRect(r);
			p.h := r.left;
			p.v := r.top;
			if est_dans(jeu, p) then
				if est_dans(tri, p) then
					begin
						trier(tab, nb_element, 'ord_gauche');
						trier(tab, nb_element, 'abs_gauche');
						dessiner(tab);
					end
				else if est_rectangle(r) then
					begin
						PaintRect(r);
						ajouter(r, tab);
					end;
		end
	until est_dans(stop, p);
end.