unit LList1F;
//*******************************************************
// Example program demonstrating linked lists.
//*******************************************************
// Copyright (C) 1998 John Wiley & Sons, Inc.
// All rights reserved. See additional copyright
// information in Readme.txt.
//*******************************************************

interface

uses
  Windows, Messages, SysUtils, Graphics, Controls, Forms, Dialogs,
  Menus, StdCtrls,
  LList1C, Classes;

type
  TLList1Form = class(TForm)
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    Help1: TMenuItem;
    mnuExit: TMenuItem;
    mnuAbout: TMenuItem;
    ItemText: TEdit;
    Label1: TLabel;
    CmdAddAfter: TButton;
    CmdRemoveAfter: TButton;
    Label2: TLabel;
    CmdClearList: TButton;
    procedure FormCreate(Sender: TObject);
    procedure mnuExitClick(Sender: TObject);
    procedure mnuAboutClick(Sender: TObject);
    procedure CmdAddAfterClick(Sender: TObject);
    procedure CmdRemoveAfterClick(Sender: TObject);
    procedure CmdClearListClick(Sender: TObject);
    procedure ItemTextChange(Sender: TObject);
    procedure ShowList;
    procedure LabelsOnClick(Sender: TObject);
    procedure SelectLabel(index : Longint);
    procedure Deselect;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  LList1Form: TLList1Form;

implementation

type
    // Note: This array starts at 0.
    TListLabelArray = array[0..100000000] of TLabel;
    PListLabelArray = ^TListLabelArray;

var
    the_list    : TLinkedList;
    list_labels : PListLabelArray;
    max_label   : Longint;
    selected    : Longint;

{$R *.DFM}

procedure TLList1Form.FormCreate(Sender: TObject);
begin
    // Make the list.
    the_list := TLinkedList.Create;

    // Put the sentinel's label in the label list.
    GetMem(list_labels,
        (the_list.Count + 1) * SizeOf(TLabel));
    list_labels^[0] := Label2;
    Label2.OnClick := LabelsOnClick; // Event handler.

    // Start with no label selected.
    selected := -1;
end;

procedure TLList1Form.mnuExitClick(Sender: TObject);
begin
     Close;
end;

procedure TLList1Form.mnuAboutClick(Sender: TObject);
const
    CRCR = #13#10#13#10;
    CR   = #13#10;
begin
    MessageDlg(


        'Program demonstruje funkcjonowanie listy jednokierunkowej z wartownikiem' + CR +
        'na początku.' + CRCR +
        'Kliknięcie w przycisk "Dodaj następnik" spowoduje utworzenie nowej komórki' + CR +
        'zawierającej podany łańcuch i wstawienie jej bezpośrednio za podświetloną' + CR +
        'komórką.' + CRCR +
        'Kliknięcie w przycisk "Usuń następnik" spowoduje usunięcie komórki' + CR +
        'znajdującej się bezpośrednio za komórką podświetloną.' + CRCR +
        'Kliknięcie w przycisk "Wyczyść listę" spowoduje usunięcie z listy' + CR +
        'wszystkich komórek oprócz wartownika.'
        ,  mtInformation, [mbOK], 0);



end;

procedure TLList1Form.CmdAddAfterClick(Sender: TObject);
var
    new_index : Longint;
begin
    the_list.AddAfter(selected, ItemText.Text);
    new_index := selected + 1;
    ShowList;
    SelectLabel(new_index); // Select the new item.
    ItemText.Text := '';
    ItemText.SetFocus;
end;

procedure TLList1Form.CmdRemoveAfterClick(Sender: TObject);
begin
    the_list.RemoveAfter(selected);
    Deselect;
    ShowList;
    ItemText.SetFocus;
end;

procedure TLList1Form.CmdClearListClick(Sender: TObject);
begin
    the_list.ClearList;
    Deselect;
    ShowList;
    ItemText.SetFocus;
end;

procedure TLList1Form.ItemTextChange(Sender: TObject);
begin
    CmdAddAfter.Enabled := 
        ((selected >= 0) and
         (ItemText.Text <> ''));
end;

procedure TLList1Form.ShowList;
var
    new_labels : PListLabelArray;
    i          : Longint;
    t, l, w, h : Integer;
begin

    // Make enough labels for the list.
    if (the_list.Count > max_label) then
    begin
        // Allocate space for the labels.
        GetMem(new_labels, (the_list.Count + 1) * SizeOf(TLabel));

        // Copy the old labels.
        for i := 0 to max_label do
            new_labels^[i] := list_labels^[i];

        // Create the new labels.
        l := Label2.Left;
        w := Label2.Width;
        h := Label2.Height;
        t := new_labels^[max_label].Top + h;
        for i := max_label + 1 to the_list.Count do
        begin
            new_labels^[i] := TLabel.Create(Self);
            with new_labels^[i] do
            begin
                Parent := Self;
                Left := l;
                Top := t;
                Width := w;
                Height := h;
                AutoSize := False;
                Alignment := taCenter;
                OnClick := LabelsOnClick; // Event handler.
            end;
            t := t + h;
        end;

        // Point to the new array.
        list_labels := new_labels;
        max_label := the_list.Count;
    end;

    // Display the list.
    for i := 1 to the_list.Count do
    begin
        list_labels^[i].Caption := the_list.Item(i);
        list_labels^[i].Visible := True;
    end;

    // Hide the other labels.
    for i := the_list.Count + 1 to max_label do
    begin
        list_labels^[i].Visible := False;
    end;

    Deselect;
    CmdRemoveAfter.Enabled := False;
end;

procedure TLList1Form.LabelsOnClick(Sender: TObject);
var
    i : Longint;
begin
    for i := 0 to max_label do
        if (list_labels^[i] = Sender) then
        begin
            SelectLabel(i);
            exit;
        end;
end;

procedure TLList1Form.SelectLabel(index : Longint);
begin
    // Unhighlight the previous selection.
    Deselect;

    // Highlight the label.
    if (index <= the_list.Count) then
    begin
        selected := index;
        list_labels^[selected].Color := Label1.Font.Color;
        list_labels^[selected].Font.Color := Label1.Color;
    end;
    CmdAddAfter.Enabled :=
        ((selected >= 0) and
         (ItemText.Text <> ''));
    CmdRemoveAfter.Enabled :=
        ((selected >= 0) and
         (selected < the_list.Count));
end;

procedure TLList1Form.Deselect;
begin
    if (selected >= 0) then
    begin
        list_labels^[selected].Color := Label1.Color;
        list_labels^[selected].Font.Color := Label1.Font.Color;
        selected := -1;
    end;
end;

end.
