unit Fibo4F;
//*******************************************************
// Example program demonstrating non-recursive Fibonacci
// numbers using a bottom-up calculation.
//*******************************************************
// 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);
  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.

{$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 musi zawierać się między 0 a %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(
        'Niniejszy program oblicza liczbę Fibonacciego za pomocą sumowania iteracyjnego.' +CRCR+
        'Wprowadź indeks liczby i kliknij w przycisk "Oblicz".'
        , mtInformation, [mbOK], 0);

end;

// Calculate Fibonnaci numbers from the bottom up.
function Fibo(n : Integer) : Double;
var
    fib_i, fib_i_minus_1, fib_i_minus_2 : Double;
    i                                   : Integer;
begin
    if (n <= 1) then
        Fibo := n
    else begin
        fib_i := 0;         // Prevent compiler warning.
        fib_i_minus_2 := 0; // Initially fib(0)
        fib_i_minus_1 := 1; // Initially fib(1)
        for i := 2 to n do
        begin
            fib_i := fib_i_minus_1 + fib_i_minus_2;
            fib_i_minus_2 := fib_i_minus_1;
            fib_i_minus_1 := fib_i;
        end;
        Fibo := fib_i;
    end;
end;

end.
