program taschenrechner;
uses crt, graph, maus;

var rechenfeld : array[1..50] of real;

procedure taste(x1, y1, x2, y2: integer; text: string; farbe: word);

  var x, y   : integer;

  begin
    setcolor(0); setfillstyle(1, farbe); setlinestyle(0, 0, 3);
    settextstyle(1, 0, 7); settextjustify(1, 1);
    rectangle(x1, y1, x2, y2);
    x:=x1+round((x2-x1)/2);
    y:=y1+round((y2-y1)/2)-10;
    outtextxy(x, y, text);
    floodfill(x1+3, y1+3, 0);
  end;

procedure start;

  var gd, gm : integer;
      ja : boolean;
      tasten : word;

  begin
    {Grafikaufbau}
    gd:=9; gm:=2;
    initgraph(gd, gm, 'd:\tp\bgi');
    cleardevice;
    {1. Seite: Bedienung}
    settextstyle(3, 0, 4);
    setfillstyle(1, white);
    setcolor(white);
    bar(0, 0, 639, 479);
    setcolor(red);
    settextjustify(1, 1);
    outtextxy(320, 30, 'Taschenrechner');
    outtextxy(320, 90, 'von Stefan Ziegler');
    settextstyle(1, 0, 2);
    setcolor(0);
    settextjustify(0, 0);
    outtextxy(5, 160, 'Bedienung:');
    outtextxy(5, 190, '- Mit Maus auf Schalter drcken');
    outtextxy(5, 220, '- Taste, die auf Schalter abgebildet ist, drcken');
    outtextxy(5, 250, '- Fr Taste ''='' auch ENTER');
    outtextxy(5, 280, '- ''L'' : Display lschen, ''A'' : Aus, ''ö'' auch ''/'', ''ñ'' enspr. ''_''');
    outtextxy(5, 330, 'Speicher:');
    outtextxy(5, 360, '- ''M+'' : Taste: S (schreiben); Zahl einspeichern');
    outtextxy(5, 390, '- ''M-'' : Taste: C (Clear); Speicher lschen');
    outtextxy(5, 420, '- ''Mr'' : Taste: m/M; Zahl des Speichers in Display');
    settextjustify(1, 1);
    outtextxy(320, 460, 'Enter');
    if paramstr(1)='' then readln;
    delay(100);
    cleardevice;
    {Aufbau des Taschenrechnerbildes}
    setcolor(11); setfillstyle(1, 11);
    bar(0, 0, 639, 479);
    taste(10, 10, 635, 110, '', 15);
    taste(10, 130, 110, 210, '1', 9);
    taste(120, 130, 220, 210, '2', 9);
    taste(230, 130, 330, 210, '3', 9);
    taste(340, 130, 440, 210, '+', 2);
    taste(450, 130, 550, 210, 'M+', 3);
    taste(560, 130, 630, 300, 'A', 5);
    taste(10, 220, 110, 300, '4', 9);
    taste(120, 220, 220, 300, '5', 9);
    taste(230, 220, 330, 300, '6', 9);
    taste(340, 220, 440, 300, '-', 2);
    taste(450, 220, 550, 300, 'M-', 3);
    taste(10, 310, 110, 390, '7', 9);
    taste(120, 310, 220, 390, '8', 9);
    taste(230, 310, 330, 390, '9', 9);
    taste(340, 310, 440, 390, '*', 2);
    taste(450, 310, 550, 390, 'Mr', 3);
    taste(560, 310, 630, 470, 'L', 5);
    taste(10, 400, 110, 470, '.', 7);
    taste(120, 400, 220, 470, '0', 9);
    taste(230, 400, 330, 470, 'ñ', 7);
    taste(340, 400, 440, 470, 'ö', 2);
    taste(450, 400, 550, 470, '=', 2);
    {Maus starten}
    ja:=true;
    tasten:=2;
    init_maus(ja, tasten, ja);
    select_maus(1);
    show_maus;
    set_maus(320, 240);
  end;

procedure auftaste(xm, ym, x1, y1, x2, y2: integer; text: char; var zeichen: char);

  var stbolx, stboly : boolean;
      farbe          : word;

  begin
    stbolx:=(xm>=x1) and (xm<=x2);
    stboly:=(ym>=y1) and (ym<=y2);
    if stbolx and stboly
      then begin
             zeichen:=text;
             {farbe:=getpixel(x1+3, y1+3);
             setcolor(0); setlinestyle(0, 0, 3);
             rectangle(x1, y1, x2, y2);
             setcolor(15); setfillstyle(1, 15);
             floodfill(x1+3, y1+3, 0);
             delay(50);
             setcolor(farbe); setfillstyle(1, farbe);
             floodfill(x1+3, y1+3, 0);}
           end
      else zeichen:=chr(0);
  end;

procedure blink(x1, y1, x2, y2, farbe : integer);
  begin
    hide_maus;
    setcolor(0); setlinestyle(0, 0, 3);
    rectangle(x1, y1, x2, y2);
    setcolor(15); setfillstyle(1, 15);
    floodfill(x1+3, y1+3, 0);
    delay(50);
    setcolor(farbe); setfillstyle(1, farbe);
    floodfill(x1+3, y1+3, 0);
    show_maus;
  end;

procedure displayzeich(zahl : real);

  var zstr : string;
      zahl2: longint;

  begin
    hide_maus;
    setcolor(0); setfillstyle(1, 15);
    bar(12, 12, 633, 70);
    if int(zahl)=zahl
      then begin
             zahl2:=round(zahl);
             str(zahl2, zstr);
           end
      else str(zahl, zstr);
    settextjustify(2, 1);
    setcolor(1);
    settextstyle(1, 0, 5);
    outtextxy(635, 40, zstr);
    show_maus;
  end;

procedure rechausf(funktion : char; var z1, z2, display : real);
  begin
    {setcolor(0); setfillstyle(1, 15);
    bar(120, 12, 634, 105);
    settextjustify(2, 1);
    setcolor(1);
    settextstyle(1, 0, 5);
    outtextxy(630, 50, funktion);
    display:=0;
    delay(100);}
    if funktion='+' then display:=z1+z2;
    if funktion='-' then display:=z1-z2;
    if funktion='*' then display:=z1*z2;
    if funktion='/' then display:=z1/z2;
    z1:=0;
    z2:=0;
    displayzeich(display);
  end;

procedure zahl(nummer : byte; var faktor:byte; komma: boolean; var display: real);

  var minus: shortint;
      raus : boolean;

  begin
    raus:=false; 
    raus:=(faktor>=10) or (display*10+nummer>=2140000000.0); {10^9}
    if raus=true then
       begin
         sound(200);
         delay(50);
         nosound;
       end;
    if raus=false then
      begin
        if display>=0 then minus:=1 else minus:=-1;
        if komma=false then display:=display*10+nummer*minus;
        if komma=true then
          begin
            display:=display+nummer/round(exp(faktor*ln(10)))*minus;
            faktor:=faktor+1;
          end;
      end;
  end;

procedure rechnen;

  var ch, ch2           : char;
      tast, xm, ym      : word;
      event             : boolean;
      funkt             : char;
      komma             : boolean;
      faktor            : byte;
      display, speicher : real;
      z1, z2            : real;

  begin
    z1:=0; z2:=0;
    display:=0;
    faktor:=1;
    komma:=false;
    funkt:='s';
    speicher:=0;
    repeat
      repeat
        event:=false;
        ch:=chr(0);                {Taste oder Maus benutzt ?}
        ch2:=chr(0);
        if keypressed then
          begin
            ch:=readkey;
            if ch=chr(0) then ch2:=readkey;
          end;
        maus_status(xm, ym, tast);
        delay(80);
        if (ch>chr(0)) or (ch2>chr(0)) or (tast>0) then event:=true
      until event=true;
      if ch2>chr(0) then begin
                           sound(200);
                           delay(50);
                           nosound;
                         end;
      if tast=1 then
        begin                                    {Wo Maus benutzt}
          hide_maus;
          if ch=chr(0) then auftaste(xm, ym, 10, 130, 110, 210, '1', ch);
          if ch=chr(0) then auftaste(xm, ym, 120, 130, 220, 210, '2', ch);
          if ch=chr(0) then auftaste(xm, ym, 230, 130, 330, 210, '3', ch);
          if ch=chr(0) then auftaste(xm, ym, 340, 130, 440, 210, '+', ch);
          if ch=chr(0) then auftaste(xm, ym, 450, 130, 550, 210, 'S', ch);
          if ch=chr(0) then auftaste(xm, ym, 560, 130, 630, 300, 'a', ch);
          if ch=chr(0) then auftaste(xm, ym, 10, 220, 110, 300, '4', ch);
          if ch=chr(0) then auftaste(xm, ym, 120, 220, 220, 300, '5', ch);
          if ch=chr(0) then auftaste(xm, ym, 230, 220, 330, 300, '6', ch);
          if ch=chr(0) then auftaste(xm, ym, 340, 220, 440, 300, '-', ch);
          if ch=chr(0) then auftaste(xm, ym, 450, 220, 550, 300, 'C', ch);
          if ch=chr(0) then auftaste(xm, ym, 10, 310, 110, 390, '7', ch);
          if ch=chr(0) then auftaste(xm, ym, 120, 310, 220, 390, '8', ch);
          if ch=chr(0) then auftaste(xm, ym, 230, 310, 330, 390, '9', ch);
          if ch=chr(0) then auftaste(xm, ym, 340, 310, 440, 390, '*', ch);
          if ch=chr(0) then auftaste(xm, ym, 450, 310, 550, 390, 'M', ch);
          if ch=chr(0) then auftaste(xm, ym, 560, 310, 630, 470, 'L', ch);
          if ch=chr(0) then auftaste(xm, ym, 10, 400, 110, 470, '.', ch);
          if ch=chr(0) then auftaste(xm, ym, 120, 400, 220, 470, '0', ch);
          if ch=chr(0) then auftaste(xm, ym, 230, 400, 330, 470, '_', ch);
          if ch=chr(0) then auftaste(xm, ym, 340, 400, 440, 470, '/', ch);
          if ch=chr(0) then auftaste(xm, ym, 450, 400, 550, 470, '=', ch);
          show_maus;
        end;
      if ch=chr(13) then ch:='=';
      ch:=upcase(ch);
      case ch of                 {Welche Funktion ausfhren}
        chr(27) : ch:='A';
        '0'     : begin
                    blink(120, 400, 220, 470, 9);
                    if komma=false then display:=display*10;
                    if komma=true then
                      begin
                        faktor:=faktor+1;
                      end;
                  end;
        '1'     : begin
                    blink(10, 130, 110, 210, 9);
                    zahl(1, faktor, komma, display);
                  end;
        '2'     : begin
                     blink(120, 130, 220, 210, 9);
                     zahl(2, faktor, komma, display);
                  end;
        '3'     : begin
                    blink(230, 130, 330, 210, 9);
                    zahl(3, faktor, komma, display);
                  end;
        '4'     : begin
                    blink(10, 220, 110, 300, 9);
                    zahl(4, faktor, komma, display);
                  end;
        '5'     : begin
                    blink(120, 220, 220, 300, 9);
                    zahl(5, faktor, komma, display);
                  end;
        '6'     : begin
                    blink(230, 220, 330, 300, 9);
                    zahl(6, faktor, komma, display);
                  end;
        '7'     : begin
                    blink(10, 310, 110, 390, 9);
                    zahl(7, faktor, komma, display);
                  end;
        '8'     : begin
                    blink(120, 310, 220, 390, 9);
                    zahl(8, faktor, komma, display);
                  end;
        '9'     : begin
                    blink(230, 310, 330, 390, 9);
                    zahl(9, faktor, komma, display);
                  end;
        '='     : begin
                    blink(450, 400, 550, 470, 2);
                    z2:=display;
                    rechausf(funkt, z1, z2, display);
                    {z1:=display;
                    displayzeich(display);}
                  end;
        '+'     : begin
                    blink(340, 130, 440, 210, 2);
                    if z2<>0 then rechausf(funkt, z1, z2, display);
                    if funkt='s'
                      then z1:=display
                      else z2:=display;
                    funkt:='+';
                    z1:=display;
                    display:=0;
                    faktor:=1;
                    komma:=false;
                  end;
        '-'     : begin
                    blink(340, 220, 440, 300, 2);
                    if z2<>0 then rechausf(funkt, z1, z2, display);
                    if funkt='s'
                      then z1:=display
                      else z2:=display;
                    funkt:='-';
                    z1:=display;
                    display:=0;
                    faktor:=1;
                    komma:=false;
                  end;
        '*'     : begin
                    blink(340, 310, 440, 390, 2);
                    if z2<>0 then rechausf(funkt, z1, z2, display);
                    if funkt='s'
                      then z1:=display
                      else z2:=display;
                    funkt:='*';
                    z1:=display;
                    display:=0;
                    faktor:=1;
                    komma:=false;
                  end;
        '/'     : begin
                    blink(340, 400, 440, 470, 2);
                    if z2<>0 then rechausf(funkt, z1, z2, display);
                    if funkt='s'
                      then z1:=display
                      else z2:=display;
                    funkt:='/';
                    z1:=display;
                    display:=0;
                    faktor:=1;
                    komma:=false;
                  end;
        'A'     : begin
                    blink(560, 130, 630, 300, 5);
                  end;
        'L'     : begin
                    blink(560, 310, 630, 470, 5);
                    display:=0;
                    faktor:=1;
                    komma:=false;
                  end;
        'M'     : begin
                    blink(450, 310, 550, 390, 3);
                    display:=speicher;
                  end;
        'S'     : begin
                    blink(450, 130, 550, 210, 3);
                    speicher:=display;
                    setcolor(1); settextstyle(1, 0, 5);
                    settextjustify(0, 1);
                    outtextxy(15, 75, 'M');
                  end;
        'C'     : begin
                    blink(450, 220, 550, 300, 3);
                    speicher:=0;
                    setcolor(15); settextstyle(1, 0, 5);
                    settextjustify(0, 1);
                    outtextxy(15, 75, 'M');
                  end;
        '_'     : begin
                    blink(230, 400, 330, 470, 7);
                    display:=display*(-1);
                  end;
        '.'     : begin
                    blink(10, 400, 110, 470, 7);
                    komma:=true;
                  end;
        else begin                   {Bei anderen Tasten /Mauspos. Beep}
               sound(200);
               delay(50);
               nosound;
             end;{of else}
       end;{of case}
       displayzeich(display);
    until (ch='A');
  end;{of procedure}

procedure ende;
  begin
    delay(100);
    cleardevice;
    closegraph;
  end;

begin
  start;
  rechnen;
  ende;
end.