unit Fibo1F;
//*******************************************************
// Example program demonstrating recursive Fibonacci
// numbers.
//*******************************************************
// 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;
    Label3: TLabel;
    Label4: TLabel;
    GLabel: TLabel;
    HLabel: TLabel;
    Label5: TLabel;
    TimeLabel: TLabel;
    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 : Double) : Double;

implementation

var
    base_cases, other_cases : Longint;

{$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
    start_time, stop_time : TDateTime;
    n                     : Double;
    h, m, s, ms           : Word;
begin
    ResultLabel.Caption := '';
    GLabel.Caption := '';
    HLabel.Caption := '';
    TimeLabel.Caption := '';
    Screen.Cursor := crHourGlass;
    Update;

    base_cases := 0;
    other_cases := 0;
    n := StrToFloat(NEdit.Text);
    start_time := Time;
    n := Fibo(n);
    stop_time := Time;

    ResultLabel.Caption := Format('%.6g', [n]);
    GLabel.Caption := IntToStr(base_cases);
    HLabel.Caption := IntToStr(other_cases);

    DecodeTime(stop_time - start_time, h, m, s, ms);
    TimeLabel.Caption := Format('%.2f',
        [ms / 1000.0 + s + 60 * (m + h * 60)]);

    Screen.Cursor := crDefault;
end;

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

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

    MessageDlg(
        'Niniejszy program oblicza wartość wskazanego wyrazu ciągu Fibonacciego,' + CR +
        'korzystając z definicji rekurencyjnej:' + CR +
        '    Fib(0) = 0' + CR +
        '    Fib(1) = 1' + CR +
        '    Fib(N) = Fib(N-1) + Fib(N-2)  dla N > 1' + CRCR +
        'Wprowadź numer obliczanego wyrazu i kliknij w przycisk "Oblicz".' + CRCR +
        'G(N) jest liczbą wywołań nie powodujących rekurencji.' + CRCR +
        'H(N) jest liczbą wywołań generujących dalsze wywołania rekurencyjne.'
        , mtInformation, [mbOK], 0);



end;

// Compute Fibonnaci numbers recursively.
function Fibo(n : Double) : Double;
begin
    if (n <= 1) then
    begin
        Fibo := n;
        base_cases := base_cases + 1;
    end else begin
        Fibo := Fibo(n - 1) + Fibo(n - 2);
        other_cases := other_cases + 1;
    end;
end;

end.
