unit Trav2F;
//*******************************************************
// Example program demonstrating tree traversal for
// N-ary trees.
//*******************************************************
// Copyright (C) 1998 John Wiley & Sons, Inc.
// All rights reserved. See additional copyright
// information in Readme.txt.
//*******************************************************

interface

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

type
  TTrav2Form = class(TForm)
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    mnuExit: TMenuItem;
    Help1: TMenuItem;
    mnuAbout: TMenuItem;
    CmdAdd: TButton;
    CmdRemove: TButton;
    CmdPreorder: TButton;
    CmdInorder: TButton;
    CmdPostorder: TButton;
    CmdBreadthFirst: TButton;
    ResultLabel: TLabel;
    procedure mnuExitClick(Sender: TObject);
    procedure mnuAboutClick(Sender: TObject);
    procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormCreate(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure SetButtons;
    procedure SelectNode(new_selection : TTrav2Node);
    procedure CmdAddClick(Sender: TObject);
    procedure CmdRemoveClick(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure CmdPreorderClick(Sender: TObject);
    procedure CmdInorderClick(Sender: TObject);
    procedure CmdPostorderClick(Sender: TObject);
    procedure CmdBreadthFirstClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Trav2Form: TTrav2Form;

implementation

var
    root, selected  : TTrav2Node;
    x0, y0, node_id : Integer;

{$R *.DFM}

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

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

    MessageDlg(
        'Niniejszy program demonstruje przechodzenie drzewa dowolnego stopnia.' + CRCR +
        'Zbuduj drzewo, uzywając wielokrotnie przycisków "Dodaj potomka" i "Usuń poddrzewo",' + CR +
        'a następnie wybierz żądaną metodę.'
        , mtInformation, [mbOK], 0);


end;

procedure TTrav2Form.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
    // Select the node at the given point.
    SelectNode(
        root.NodeAtPoint(X, Y));
end;

// Create the root node.
procedure TTrav2Form.FormCreate(Sender: TObject);
var
    xmin : Integer;
begin
    // Create a one node tree.
    root := TTrav2Node.Create;
    root.Id := 'Root';
    node_id := 0;

    // Save the coordinates where we will start drawing.
    x0 := 3;
    y0 := CmdAdd.Top + CmdAdd.Height + 3;

    // Use bold text.
    Canvas.Font.Style := [fsBold];

    // Position the initial one node tree.
    xmin := x0;
    root.SetPosition(xmin, y0);
end;

// Draw the tree.
procedure TTrav2Form.FormPaint(Sender: TObject);
var
    rect : TRect;
begin
    // Erase the canvas.
    rect.Left := 0;
    rect.Right := Width;
    rect.Top := 0;
    rect.Bottom := Height;
    Canvas.Brush.Color := clLtGray;
    Canvas.FillRect(rect);

    // Draw the tree.
    root.DrawSubtree(Canvas, selected);
end;

// Enable the correct buttons for the selected node.
procedure TTrav2Form.SetButtons;
begin
    if (selected = nil) then
    begin
        CmdAdd.Enabled    := False;
        CmdRemove.Enabled := False;
    end else begin
        CmdAdd.Enabled    := True;
        CmdRemove.Enabled := (selected <> root);
    end;
end;

procedure TTrav2Form.SelectNode(new_selection : TTrav2Node);
begin
    // Unselect the previously selected node.
    if (selected <> nil) then
        selected.DrawNode(Canvas, nil);

    // Select the new node.
    selected := new_selection;
    // Highlight the selected node.
    if (selected <> nil) then
        selected.DrawNode(Canvas, selected);
    SetButtons;
end;

// Add a left child to the selected node.
procedure TTrav2Form.CmdAddClick(Sender: TObject);
var
    xmin : Integer;
begin
    node_id := node_id + 1;
    selected.AddChild(selected, IntToStr(node_id));

    // Reposition the nodes.
    xmin := x0;
    root.SetPosition(xmin, y0);

    // Enable the correct buttons.
    SetButtons;

    Refresh;
end;

// Remove the selected node and its descendants.
procedure TTrav2Form.CmdRemoveClick(Sender: TObject);
var
    xmin   : Integer;
    target : TTrav2Node;
begin
    // Unselect the node.
    target := selected;
    SelectNode(nil);

    // Remove the selected node from the tree.
    target.ParentNode.RemoveChild(target);

    // Reposition the remaining nodes.
    xmin := x0;
    root.SetPosition(xmin, y0);

    Refresh;
end;

// Move the ResultLabel to the bottom of the form.
procedure TTrav2Form.FormResize(Sender: TObject);
var
    new_top : Integer;
begin
    new_top := ClientHeight - ResultLabel.Height;
    if (new_top < CmdAdd.Top + CmdAdd.Height) then
        new_top := CmdAdd.Top + CmdAdd.Height;
    ResultLabel.Top := new_top;
end;

// Display the preorder traversal.
procedure TTrav2Form.CmdPreorderClick(Sender: TObject);
begin
    ResultLabel.Caption := root.PreorderTraverse;
end;

// Display the inorder traversal.
procedure TTrav2Form.CmdInorderClick(Sender: TObject);
begin
    ResultLabel.Caption := root.InorderTraverse;
end;

// Display the postorder traversal.
procedure TTrav2Form.CmdPostorderClick(Sender: TObject);
begin
    ResultLabel.Caption := root.PostorderTraverse;
end;

// Display the breadth first traversal.
procedure TTrav2Form.CmdBreadthFirstClick(Sender: TObject);
begin
    ResultLabel.Caption := root.BreadthFirstTraverse;
end;

end.
