unit Fibo3F;
//*******************************************************
// Example program demonstrating non-recursive Fibonacci
// numbers using a prefilled lookup table.
//*******************************************************
// 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,
  StdCtrls, Menus;

type
  TFiboForm = class(TForm)
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    mnuExit: TMenuItem;
    Help1: TMenuItem;
    mnuAbout: TMenuItem;
    NEdit: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    ResultLabel: TLabel;
    CmdCompute: TButton;
    procedure NEditChange(Sender: TObject);
    procedure NumbersOnly(Sender: TObject; var Key: Char);
    procedure CmdComputeClick(Sender: TObject);
    procedure mnuExitClick(Sender: TObject);
    procedure mnuAboutClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  FiboForm: TFiboForm;

    function Fibo(n : Integer) : Double;

implementation

Const
    MAX_FIB = 1476; // The largest value we can compute.

var
    FiboValues : Array[0..MAX_FIB] of Double;

{$R *.DFM}

procedure TFiboForm.NEditChange(Sender: TObject);
begin
    CmdCompute.Enabled := (NEdit.Text <> '');
end;

procedure TFiboForm.NumbersOnly(Sender: TObject; var Key: Char);
begin
    if (Key = #8) then exit; // Backspace.
    if ((Key >= '0') and (Key <= '9')) then exit;
    Key := #0;
end;

procedure TFiboForm.CmdComputeClick(Sender: TObject);
var
    n : Integer;
begin
    n := StrToInt(NEdit.Text);
    if ((n < 0) or (n > MAX_FIB)) then
    begin
        ShowMessage(Format('N should be between 0 and %d.',
            [MAX_FIB]));
        exit;
    end;

    ResultLabel.Caption := '';
    Screen.Cursor := crHourGlass;
    Update;

    ResultLabel.Caption := Format('%.6g', [Fibo(n)]);

    Screen.Cursor := crDefault;
end;

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

procedure TFiboForm.mnuAboutClick(Sender: TObject);
const
    CRCR = #13#10#13#10;
begin
    MessageDlg(
        'This program uses a precomputed lookup table to display Fibonacci numbers. All of the table values are calculated when the program starts.' + CRCR +
        'Enter a value and click the Compute button to see the Fibonacci number.'
        , mtInformation, [mbOK], 0);
end;

// Initialize the lookup table.
procedure TFiboForm.FormCreate(Sender: TObject);
var
    i : Integer;
begin
    FiboValues[0] := 0;
    FiboValues[1] := 1;
    for i := 2 to MAX_FIB do
        FiboValues[i] :=
            FiboValues[i - 1] + FiboValues[i - 2];
end;

// Look up Fibonnaci numbers in a table.
function Fibo(n : Integer) : Double;
begin
    Fibo := FiboValues[n];
end;

end.
