unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids, StdCtrls, ExtCtrls;

const ROWS        = 50000;
const COLS        = 12;

const colLp       =  0;
const colNazwisko =  1;
const colImie     =  2;
const colUlica    =  3;
const colKodp     =  4;
const colMiasto   =  5;
const colDataur   =  6;
const colPesel    =  7;
const colTel      =  8;
const colEmail    =  9;
const colWoj      = 10;
const colZarobek  = 11;

Type

MRec = record
     Lp          : String;
     Nazwisko    : String;
     Imie        : String;
     Ulica       : String;
     Kodp        : String;
     Miasto      : String;
     Dataur      : String;
     Pesel       : String;
     Tel         : String;
     Email       : String;
     Woj         : String;
     Zarobek     : String;
  end;

  TMainForm = class(TForm)
    Panel1: TPanel;
    imgKONIEC: TImage;
    imgQUICK_SORT: TImage;
    lblINFO: TLabel;
    lblCZAS: TLabel;
    sg: TStringGrid;
    procedure imgKONIECClick(Sender: TObject);
    procedure imgQUICK_SORTClick(Sender: TObject);
    procedure FormShow(Sender: TObject);

  private

  public
    procedure  Sortuj();
	 procedure  Koniec();
	 procedure  Przypisz_lp();
    procedure  Buduj_sg();
    procedure  GetRec(ARow : Integer; var Rek: MRec);
	 procedure  SetRec(ARow : Integer; Rek : MRec);
	 procedure  QuickSort(iLo : Integer; iHi : Integer);
  end;

var
  MainForm: TMainForm;

implementation
{$R *.dfm}
{------------------------------------------------------------------------------}
procedure TMainForm.Przypisz_lp();
var
   ACol : Integer;
 	ARow : Integer;
   Recs : Integer;

begin
   Recs := sg.RowCount-1;

   for ARow := 1 to Recs do
   begin
   	sg.Cells[ACol, ARow] := IntToStr(ARow);
   end;

   sg.Invalidate();
end;

procedure TMainForm.imgKONIECClick(Sender: TObject);
begin
	Koniec();
end;

procedure TMainForm.Koniec();
begin
	if Application.MessageBox('Koniec pracy', 'Uwaga', MB_ICONINFORMATION or MB_YESNO) = mrYes then
	begin
		Close();
   end;
end;

procedure TMainForm.FormShow(Sender: TObject);
begin
	lblINFO.Visible := true;
	Application.ProcessMessages();

	Buduj_sg();

	lblINFO.Visible := false;
	sg.Align := alClient;

	sg.Col := 1;
	sg.Row := 1;
	sg.SetFocus();
end;

procedure TMainForm.GetRec(ARow: Integer; var Rek: MRec);
begin
   Rek.Lp       := sg.Cells[colLp      , ARow];
   Rek.Nazwisko := sg.Cells[colNazwisko, ARow];
   Rek.Imie     := sg.Cells[colImie    , ARow];
   Rek.Ulica    := sg.Cells[colUlica   , ARow];
   Rek.Kodp     := sg.Cells[colKodp    , ARow];
   Rek.Miasto   := sg.Cells[colMiasto  , ARow];
   Rek.Dataur   := sg.Cells[colDataur  , ARow];
   Rek.Pesel    := sg.Cells[colPesel   , ARow];
   Rek.Tel      := sg.Cells[colTel     , ARow];
   Rek.Email    := sg.Cells[colEmail   , ARow];
   Rek.Woj      := sg.Cells[colWoj     , ARow];
   Rek.Zarobek  := sg.Cells[colZarobek , ARow];
end;

procedure TMainForm.SetRec(ARow : Integer; Rek : MRec);
begin
   sg.Cells[colLp      , ARow] := Rek.Lp;
   sg.Cells[colNazwisko, ARow] := Rek.Nazwisko;
   sg.Cells[colImie    , ARow] := Rek.Imie;
   sg.Cells[colUlica   , ARow] := Rek.Ulica;
   sg.Cells[colKodp    , ARow] := Rek.Kodp;
   sg.Cells[colMiasto  , ARow] := Rek.Miasto;
   sg.Cells[colDataur  , ARow] := Rek.Dataur;
   sg.Cells[colPesel   , ARow] := Rek.Pesel;
   sg.Cells[colTel     , ARow] := Rek.Tel;
   sg.Cells[colEmail   , ARow] := Rek.Email;
   sg.Cells[colWoj     , ARow] := Rek.Woj;
   sg.Cells[colZarobek , ARow] := Rek.Zarobek;
end;

procedure TMainForm.Buduj_sg();
var
	ARow : Integer;
	lp   : Integer;

begin
	sg.DefaultRowHeight := 19;

   sg.ColCount := COLS;
   ARow := 0;

	// SZEROKOŚĆ KOLUMN
   sg.ColWidths[ 0] :=  40;     // Lp
   sg.ColWidths[ 1] :=  90;     // Nazwisko
   sg.ColWidths[ 2] :=  60;     // Imie
   sg.ColWidths[ 3] := 150;     // Ulica i nr
   sg.ColWidths[ 4] :=  60;     // Kod p
   sg.ColWidths[ 5] :=  90;     // Miejscowosc
   sg.ColWidths[ 6] :=  60;     // Data ur
   sg.ColWidths[ 7] :=  80;     // Pesel
   sg.ColWidths[ 8] :=  60;     // Telefon
   sg.ColWidths[ 9] := 100;     // E-mail
   sg.ColWidths[10] := 100;     // Województwo
   sg.ColWidths[11] :=  70;     // Zarobek

   // NAGŁÓWKI KOLUMN
   sg.Cells[ 0, ARow] := 'Lp';
   sg.Cells[ 1, ARow] := 'Nazwisko';
   sg.Cells[ 2, ARow] := 'Imię';
   sg.Cells[ 3, ARow] := 'Ulica';
   sg.Cells[ 4, ARow] := 'Kod.p';
   sg.Cells[ 5, ARow] := 'Miejsc';
   sg.Cells[ 6, ARow] := 'Data ur';
   sg.Cells[ 7, ARow] := 'Pesel';
   sg.Cells[ 8, ARow] := 'Telefon';
   sg.Cells[ 9, ARow] := 'E-mail';
   sg.Cells[10, ARow] := 'Woj';
   sg.Cells[11, ARow] := 'Zarobek';
   Inc(ARow);

   for lp := ROWS downto 1 do
   begin
	   sg.Cells[ 0, ARow] := IntToStr(lp);
	   sg.Cells[ 1, ARow] := IntToStr(lp);
	   sg.Cells[ 2, ARow] := IntToStr(lp);
	   sg.Cells[ 3, ARow] := IntToStr(lp);
	   sg.Cells[ 4, ARow] := IntToStr(lp);
	   sg.Cells[ 5, ARow] := IntToStr(lp);
   	sg.Cells[ 6, ARow] := IntToStr(lp);
	   sg.Cells[ 7, ARow] := IntToStr(lp);
	   sg.Cells[ 8, ARow] := IntToStr(lp);
	   sg.Cells[ 9, ARow] := IntToStr(lp);
	   sg.Cells[10, ARow] := IntToStr(lp);
	   sg.Cells[11, ARow] := IntToStr(lp);
      Inc(ARow);
      sg.RowCount := sg.RowCount + 1;
   end;

	sg.RowCount := ARow;
   // nie chcę pustego ARowa na końcu
   // sg.RowCount := sg.RowCount + 1;

   sg.FixedCols := 1;
   sg.FixedRows := 1;


   // włączenie opcji
	sg.Options := [goFixedVertLine,
                  goFixedHorzLine,
                  goVertLine,
                  goHorzLine,
                  goRangeSelect,
                  goRowSizing,
                  goColSizing,
                  goRowMoving,
                  goEditing,
                  goAlwaysShowEditor,
                  goColMoving];
end;

procedure TMainForm.imgQUICK_SORTClick(Sender: TObject);
var
	t1, t2, t3 : TTime;
   kom        : String;

begin
	lblINFO.Visible := true;
	lblINFO.Invalidate();

   t1 := Time();

   Sortuj();

   t2 := Time();
	lblINFO.Visible := false;
   t3 := t2 - t1;

   kom := TimeToStr(t3);
   kom := 'Czas trwania sortowania metodą QuickSort: ' + kom;
	lblCZAS.Caption := kom;
	lblCZAS.Visible := true;
end;

procedure TMainForm.Sortuj();
var
   Recs : Integer;

begin
	Recs := ROWS;

	if Recs > 1 then
   begin
      sg.Visible := false;

   	QuickSort(1, Recs);

		Przypisz_lp();
      sg.Visible := true;
   end;
end;

procedure TMainForm.QuickSort(iLo : Integer; iHi : Integer);
var
   nazwisko : Integer; // to pole bedzie porównywane w procesie sortowania

   Lo       : Integer;
   Hi       : Integer;
   srodek   : Integer;

   tmpRec   : MRec;
   LoRec    : MRec;
   HiRec    : MRec;

begin
   Lo := iLo;
   Hi := iHi;

	srodek   := (Lo + Hi) div 2;
   nazwisko := StrToInt(sg.Cells[colNazwisko, srodek]);

   repeat
   	while (StrToInt(sg.Cells[colNazwisko, Lo]) < nazwisko) do Inc(Lo);
      while (StrToInt(sg.Cells[colNazwisko, Hi]) > nazwisko) do Dec(Hi);

      if (Lo <= Hi) then
   	begin
      	GetRec(Lo, tmpRec);
      	GetRec(Lo, LoRec);
      	GetRec(Hi, HiRec);

         SetRec(Lo, HiRec);
         SetRec(Hi, tmpRec);

         Inc(Lo);
         Dec(Hi);
      end;
   until( Lo > Hi);
	
   if (Hi > iLo) then QuickSort(iLo, Hi);
   if (Lo < iHi) then QuickSort(Lo, iHi);
end;

end.

