unit Unit1;

interface

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

type
  TAction = (taNone,taPlus,taMinus,taMult,taDiv);
  TForm1 = class(TForm)
    MainMenu: TMainMenu;
    N1: TMenuItem;
    N2: TMenuItem;
    N3: TMenuItem;
    N4: TMenuItem;
    N5: TMenuItem;
    N6: TMenuItem;
    N7: TMenuItem;
    NumEdt: TEdit;
    SpeedButton1: TSpeedButton;
    SpeedButton2: TSpeedButton;
    SpeedButton3: TSpeedButton;
    SpeedButton4: TSpeedButton;
    SpeedButton5: TSpeedButton;
    SpeedButton6: TSpeedButton;
    SpeedButton7: TSpeedButton;
    SpeedButton8: TSpeedButton;
    SpeedButton9: TSpeedButton;
    SpeedButton10: TSpeedButton;
    SpeedButton11: TSpeedButton;
    SpeedButton12: TSpeedButton;
    SpeedButton13: TSpeedButton;
    SpeedButton14: TSpeedButton;
    SpeedButton15: TSpeedButton;
    SpeedButton16: TSpeedButton;
    SpeedButton17: TSpeedButton;
    SpeedButton18: TSpeedButton;
    SpeedButton19: TSpeedButton;
    SpeedButton20: TSpeedButton;
    ListBox: TListBox;
    PopupMenu1: TPopupMenu;
    N8: TMenuItem;
    N9: TMenuItem;
    N10: TMenuItem;
    procedure SpeedButton6Click(Sender: TObject);
    procedure SpeedButton11Click(Sender: TObject);
    procedure SpeedButton13Click(Sender: TObject);
    procedure SpeedButton12Click(Sender: TObject);
    procedure SpeedButton17Click(Sender: TObject);
    procedure SpeedButton18Click(Sender: TObject);
    procedure N2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure SpeedButton19Click(Sender: TObject);
    procedure SpeedButton20Click(Sender: TObject);
    procedure N3Click(Sender: TObject);
    procedure N5Click(Sender: TObject);
    procedure N6Click(Sender: TObject);
    procedure N7Click(Sender: TObject);
  private
    { Private declarations }
    Stack: array of Double;
    Act: TAction;
    FirstNum: Double;
    l:integer;
    WasError,sec: Boolean;
    function ConvertIt: Double;
    procedure RefreshStack;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.DFM}

procedure TForm1.SpeedButton6Click(Sender: TObject);
var Tmp:byte;
begin
  if sec then NumEdt.Text := '';
  sec := False;
  if NumEdt.Text = '0' then NumEdt.Text := '';
  Tmp := NumEdt.SelStart;
  NumEdt.Text := Copy(NumEdt.Text,1,NumEdt.SelStart)+
    (Sender as TSpeedButton).Caption + Copy(NumEdt.Text,NumEdt.SelStart+1,Length(NumEdt.Text));
  NumEdt.SelStart := Tmp+1;
end;

procedure TForm1.SpeedButton11Click(Sender: TObject);
begin
  if Pos(NumEdt.Text,',') = 0 then
    NumEdt.Text := NumEdt.Text + ',';
end;

procedure TForm1.SpeedButton13Click(Sender: TObject);
begin
  case (Sender as TSpeedButton).Tag of
    0: Act := taPlus;
    1: Act := taMinus;
    2: Act := taMult;
    3: Act := taDiv;
  end;
  FirstNum := ConvertIt;
  NumEdt.Selstart:=Length(NumEdt.Text);
  sec := True;
end;

function TForm1.ConvertIt: Double;
begin
  WasError := False;
  Result := 0;
  try
    Result := StrToFloat(NumEdt.Text);
  except
    on EConvertError do
    begin
      MessageBox(0,'Вы ввели неверное число','Ошибка!',MB_OK+MB_ICONERROR);
      WasError := True;
    end;
    on EOverflow do
    begin
      MessageBox(0,'Слишком большое число','Ошибка',MB_OK+MB_ICONERROR);
      WasError := True;
    end;
  end;
//  if not WasError then NumEdt.Text := '0';
end;

procedure TForm1.SpeedButton12Click(Sender: TObject);
var
  SecondNum,Rslt: Double;
begin
  if Act = taNone then Exit;
  Rslt := 0;
  SecondNum := ConvertIt;
  try
    case Act of
      taPlus: Rslt := FirstNum + SecondNum;
      taMinus: Rslt := FirstNum - SecondNum;
      taMult: Rslt := FirstNum * SecondNum;
      taDiv: Rslt := FirstNum / SecondNum;
    end;
  except
    on EZeroDivide do MessageBox(0,'Деление на ноль!','Ошибка',
      MB_OK+MB_ICONERROR);
    on EOverflow do
    begin
      MessageBox(0,'Переполнение!','Ошибка',MB_OK+MB_ICONERROR);
      Rslt := -1;
    end;
  end;
  NumEdt.Text := FloatToStr(Rslt);
  NumEdt.Selstart:=Length(NumEdt.Text);
  sec := True;
end;

procedure TForm1.SpeedButton17Click(Sender: TObject);
var
  Tmp: Byte;
begin
  Tmp := NumEdt.SelStart;
  NumEdt.Text:=Copy(NumEdt.Text, 1, NumEdt.Selstart-1)+
    Copy(NumEdt.Text, NumEdt.Selstart+1, Length(NumEdt.Text));
  NumEdt.SelStart := Tmp-1;
end;

procedure TForm1.SpeedButton18Click(Sender: TObject);
var
  Tmp: Byte;
begin
  Tmp := NumEdt.SelStart;
  NumEdt.Text:=Copy(NumEdt.Text, 1, NumEdt.Selstart)+
    Copy(NumEdt.Text, NumEdt.Selstart+2, Length(NumEdt.Text));
  NumEdt.SelStart := Tmp;
end;

procedure TForm1.N2Click(Sender: TObject);
begin
  AboutBox.ShowModal;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  sec := False;
  NumEdt.Selstart:=Length(NumEdt.Text);
  l := -1;
  FirstNum := 0;
  Act := taNone;
end;

procedure TForm1.SpeedButton19Click(Sender: TObject);
var
  Tmp:double;
begin
  Tmp := ConvertIt;
  if WasError then Exit;
  inc(l);
  Setlength(Stack, l+1);
  Stack[High(Stack)] := Tmp;
  RefreshStack;
  sec := True;
end;

procedure TForm1.RefreshStack;
var
  I: Integer;
begin
  ListBox.Items.Clear;
  for I := L downto 0 do
    ListBox.Items.Add(FloatToStr(Stack[I]));
end;

procedure TForm1.SpeedButton20Click(Sender: TObject);
begin
  if l=-1 then exit;
  NumEdt.Text := FloatToStr(Stack[High(Stack)]);
  dec(l);
  SetLength(Stack, l+1);
  RefreshStack;
  sec := True;
end;

procedure TForm1.N3Click(Sender: TObject);
begin
  if N3.Caption = 'Показать стек' then
  begin
    N3.Caption := 'Скрыть стек';
    Height := 380;
  end else
  begin
    N3.Caption := 'Показать стек';
    Height := 185;
  end;
end;

procedure TForm1.N5Click(Sender: TObject);
begin
  l := -1;
  finalize(Stack);
  NumEdt.Text := '0';
  FirstNum := 0;
  Act := taNone;
  NumEdt.Selstart:=Length(NumEdt.Text);
  ListBox.Items.Clear;
end;

procedure TForm1.N6Click(Sender: TObject);
begin
  NumEdt.Text:='0';
  NumEdt.Selstart:=Length(NumEdt.Text);
end;

procedure TForm1.N7Click(Sender: TObject);
begin
  l := -1;
  finalize(Stack);
  ListBox.Items.Clear;
end;

end.
