unit fcalc;

interface

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

type
  TForm1 = class(TForm)
    Number_7: TButton;
    ReadOut: TLabel;
    Number_8: TButton;
    Number_9: TButton;
    Number_4: TButton;
    Number_5: TButton;
    Number_6: TButton;
    Number_1: TButton;
    Number_2: TButton;
    Number_3: TButton;
    Number_0: TButton;
    Decimal: TButton;
    Cancel: TButton;
    CancelEntry: TButton;
    Operator_1: TButton;
    Operator_3: TButton;
    Operator_2: TButton;
    Operator_0: TButton;
    Operator_4: TButton;
    Percent: TButton;
    procedure FormCreate(Sender: TObject);
    procedure NumberClick(Sender: TObject);
    procedure DecimalClick(Sender: TObject);
    procedure CancelClick(Sender: TObject);
    procedure CancelEntryClick(Sender: TObject);
    procedure PercentClick(Sender: TObject);
    procedure OperatorClick(Sender: TObject);
  private
    { Private declarations }
    Op1:Variant; //Previously input operand.
    Op2:Variant;
    DecimalFlag:Boolean; //Decimal point present yet?
    NumOps:Integer;      //Number of operands.
    LastInput:String;    //Indicate type of last keypress event.
    OpFlag:Char;        //Indicate pending operation.
    TempReadout:Variant;

  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  DecimalFlag := False;
  NumOps := 0;
  LastInput := 'NONE';
  OpFlag := ' ';
  ReadOut.Caption := '0'+DecimalSeparator;
  Decimal.Caption := DecimalSeparator;
end;

procedure TForm1.NumberClick(Sender: TObject);
begin
  if LastInput <> 'NUMS' Then
  begin
    ReadOut.Caption := DecimalSeparator;
    DecimalFlag := False;
  end; //if

  if DecimalFlag Then
    ReadOut.Caption := ReadOut.Caption + TButton(Sender).Caption
  else
    ReadOut.Caption := Copy(ReadOut.Caption, 1,
                            Pos(DecimalSeparator, ReadOut.Caption) - 1) +
                            TButton(Sender).Caption + DecimalSeparator;
  if LastInput = 'NEG' then
    ReadOut.Caption := '-' + ReadOut.Caption;

  LastInput := 'NUMS';
end;

procedure TForm1.DecimalClick(Sender: TObject);
begin
  if LastInput = 'NEG' then
    ReadOut.Caption := '-0'
  else
    if LastInput <> 'NUMS' then
      ReadOut.Caption := DecimalSeparator;
  DecimalFlag := True;
  LastInput := 'NUMS';
end;

procedure TForm1.CancelClick(Sender: TObject);
begin
  ReadOut.Caption := '0'+DecimalSeparator;
  Op1 := 0;
  Op2 := 0;
  FormCreate (Application);
end;

procedure TForm1.CancelEntryClick(Sender: TObject);
begin
  ReadOut.Caption := '0'+DecimalSeparator;
  DecimalFlag := False;
  LastInput := 'CE';
end;

procedure TForm1.PercentClick(Sender: TObject);
begin
  TempReadOut := ReadOut.Caption;
  TempReadOut := TempReadOut / 100;
  ReadOut.Caption := TempReadOut;
  LastInput := 'Ops';
  OpFlag := '%';
  NumOps := NumOps + 1; //or Inc(NumOps)
  DecimalFlag := True;
end;

procedure TForm1.OperatorClick(Sender: TObject);
begin
  TempReadout := ReadOut.Caption;

  if LastInput = 'NUMS' then
    NumOps := NumOps + 1;

  case NumOps Of
  0: begin
       if (TButton(Sender).Caption = '-') and (LastInput <> 'NEG') then
       begin
         ReadOut.Caption := '-' + ReadOut.Caption;
         LastInput := 'NEG';
       end;
     end;
  1: begin
       Op1 := ReadOut.Caption;
       if (TButton(Sender).Caption = '-') and (LastInput <> 'NUMS')
           and (OpFlag <> '=') then
       begin
         ReadOut.Caption := '-';
         LastInput := 'NEG';
       end;
     end;
  2: begin
       Op2 := TempReadout;
       case OpFlag of
       '+': Op1 := Double(Op1) + Double(Op2);
       '-': Op1 := Double(Op1) - Double(Op2);
       'x': Op1 := Double(Op1) * Double(Op2);
       '/': if Op2 = 0 then
              Application.MessageBox ('Cannot divide by zero',
                                      'Calculator', 48)
            else
              Op1 := Double(Op1) / Double(Op2);
       '=': Op1 := Double(Op2);
       '%': Op1 := Double(Op1) * Double(Op2);
       end; //End case
     end; //2:
   end; //End case

   ReadOut.Caption := Op1;
   NumOps := 1;

   if LastInput <> 'NEG' then
   begin
     LastInput := 'OPS';
     OpFlag := Char(TButton(Sender).Tag);  //ascii values of op captions
   end;
end;

end.
