unit uAMenu;

      {=================================================================}
      {                                                                 }
      {  SW pro terminaly SofCon                V2.51  17.03.2003 Bu    }
      {                                                                 }
      {  Knihovna pro praci s MENU-obrazovkami pro terminaly SofCon     }
      {                                                                 }
      {  (C) 1996-1997, SofCon s.r.o., Stresovicka 49, Praha 6          }
      {                 Vypracoval: V.Kastner, P.Weber                  }
      {=================================================================}


{$ifdef USE_SETS_INC} { Pokud chces tak nastav v Compiler Options/Conditional defines }
   {$I Sets.inc}
{$endif}


interface
uses
  Objects,
  uTermChr;

const
  cVerNo = $0251; { BCD format }
  cVer   = '02.51,17.03.2003';

const
  cStackSize       = 30;  {hloubka stacku}


  cPrimEditWidth   = 15;  {Touto konstantou se nastavuje pri Initu PrimEditWidth.
                           Pokud neni EditSemiLogReal, tak se u vypisu Real
                           pouzije tento pocet znaku u exponencielniho tvaru
                           vypisu}
  cEditValWidth    = 10;  {Touto konstantou se nastavuje pri Initu
                           EditValWidth.}
  cEditValDecimals = 5;   {Touto konstantou se nastavuje pri Initu
                           EditValDecimals.}


type
  tNum        = (nByte,nWord,nInteger,nLongInt,nReal);
  pAMenu      = ^tAMenu;
  pMMenu      = ^tMMenu;

  tIndCtrlTab = (         {pozor ulozeni musi byt na cele Wordy}
    iBeg,i00,iUp,iDn,iCr,iYes,iNo,iLe,iRi,
    iCall1, iCall2, iCall3, iCall4, iCall5, iCall6, iCall7, iCall8, iCall9, iCall10,
    iCall11,iCall12,iCall13,iCall14,iCall15,iCall16,iCall17,iCall18,iCall19,iCall20,
    iCall21,iCall22,iCall23,iCall24,iCall25,iCall26,iCall27,iCall28,iCall29,iCall30,
    iCall31,iCall32,iCall33,iCall34,iCall35,iCall36,iCall37,iCall38,iCall39,iCall40,
    iRet,
    iJmp1,  iJmp2,  iJmp3,  iJmp4,  iJmp5,  iJmp6,  iJmp7,  iJmp8,  iJmp9,  iJmp10,
    iJmp11, iJmp12, iJmp13, iJmp14, iJmp15, iJmp16, iJmp17, iJmp18, iJmp19, iJmp20,
    iJmp21, iJmp22, iJmp23, iJmp24, iJmp25, iJmp26, iJmp27, iJmp28, iJmp29, iJmp30,
    iJmp31, iJmp32, iJmp33, iJmp34, iJmp35, iJmp36, iJmp37, iJmp38, iJmp39, iJmp40,
    iEnd);
  tSetIndCtrlTab = set of tIndCtrlTab;
  tTransTab   = array[Char] of tIndCtrlTab;
  tCtrlTab    = array[tIndCtrlTab] of Word;

  tMMenu      = procedure(P: pAMenu);
  pMenu       = ^tMenu;
  tMenu       = array[0..16000]of tMMenu;


  pString     = ^String;
  tSetChar    = set of Char;

  tStackArray =  array[0..cStackSize-1] of Word;

  pStackMenu = ^tStackMenu;
  tStackMenu = object(tObject)
    StackArray   : tStackArray; {Stack pro ukladani navratovych cisel pro pohyb v menu}
    StackPointer : Byte;        {SP do Stacku [0..StackSize}
    constructor Init;
    procedure   PushMenu(A: Word);          virtual; {vlozi do stacku slovo A}
    procedure   CondPushMenu(A: Word);      virtual; {vlozi do stacku slovo A, pokud tam uz neni}
    function    PopMenu: Word;              virtual; {vytahne ze stacku slovo A}
    function    CondPopMenu(A: Word): Word; virtual; {pokud je slovo A ve stacku, tak ho vytahne}
    function    TopMenu: Word;              virtual; {ukaze posledni polozku ve stacku}
  end;

  tAMenu = object(tObject)
    {pointery na meody vyvolavane pomoci metody RUN}
{ protected }
    UserFirst     : tMMenu;  {1. uzivatelska procedura}
    DisplayMenu   : tMMenu;  {zobrazeni textu na vDisplay}
    UserSecond    : tMMenu;  {2. uzivatelska procedura, nebo Edit}
    NextMenu      : tMMenu;  {urceni nasledneho menu}
    UserThird     : tMMenu;  {3. uzivatelska procedura}

{ public }
    {promene MENU}
    MenuDispStr   : pString; {ukazatel na string pro vypis textu na vDisplay}
    MenuHelpStr   : pString; {ukazatel na string pro help}
    MenuArray     : pMenu;   {ukazatel na pole Pointeru s inicializacnimi procedurami menu}
    StackMenu     : tStackMenu; {ukazatel na objekt se StackMenuenu}

    ChangeMenu    : Boolean; {true= zmena aktualniho menu}

    ActMenu       : Word;    {aktualni cislo menu - index do pAMetodProc^}
    OldMenu       : Word;    {cislo predchoziho menu - index do pAMetodProc^}
    PreMenu       : Word;    {cislo predchoziho menu - index do pAMetodProc^}
    EndMenu       : Word;    {posledni cislo menu - posledni index do pAMetodProc^}

    TransTab      : tTransTab; {prekladova tabulka z ukoncovaciho ActCharu na RidTab}
    TransUpCase   : Boolean; {true = pred konversi tabulkou TransTab jsou pismena prevedena na velka}
    CtrlTab       : tCtrlTab; {Tabulka kde jsou cisla pro ridici promennou, pro pokracovani do dalsiho menu.}
    ClrScreen     : Boolean; {kdyz true, tak se v metode Display pred vypisem smaze obrazovka}

    ActChar       : Char;    {prijaty ActChar z klavesnice}
    TerminateChar : tSetChar;{mnozina ukoncovacich znaku}
    VerifyChar    : tSetChar;{mnozina znaku pro potvrzeni spravneho ukonceni editace, implicitne [zCr]}

    {promene EDITACE}
    EditWBeginX   : Byte;    {pocatek editacniho okna X}
    EditWBeginY   : Byte;    {pocatek editacniho okna Y}
    EditWWidth    : Byte;    {sire editacniho okna}
    EditWHeight   : Byte;    {vyska editacniho okna}
    EditVal       : Pointer; {ukazatel na promennou pro editaci ve Edit}

    EditEnter     : Boolean; {true => editace promenne az po Enter}
    EditSemiLogReal: Boolean; {False => real cisla se vypisi s exponentem na PrimEditWith znaku}
    EditValWidth  : Byte;    {celkovy pocet znaku vypisu ciselnych formatu}
    EditValDecimals: Byte; {Pocet znaku za desetinou carkou ve vypisu realovych formatu}
    EditLowLimit  : real;    {editovane cislo musi byt >= nez dolni mez}
    EditHiLimit   : real;    {editovane cislo musi byt <= nez horni mez, editovany string musi byt kratsi nebo stejne dlouhy
                              jako horni mez}
    EditMultipl   : real;    {EditMultiplativni konstanta pro editaci cisla. Pred editaci se cislo vynasobi EditMultipl a po
                              editaci vydeli EditMultipl}
    EditNumElementsSet:Byte; {Mohutnost editovane mnoziny<1;16>}
    EditReject0   : Boolean; {True = pri podhozeni cisla 0 k editaci ji to nevypise a zacina se od prazdneho stringu.}
    EditOk        : Boolean; {Provede-li se uspesna ediace, nastavi se na true}
    EditWaitTime  : Longint; {pocet waitu v cekani u modu edWait [ms]}
    EditNum       : tNum;    {typ cisla}

    EditBinCursor : byte;    {pocatecni poloha kursoru editacich binarnich typu 1=prvni znak zleva}{!We 30.5.2001}
    {promene PRERUSENI}
    MenuInt       : set of 0..7; {mnozina priznaku preruseni normalni
                                  posloupnosti menu. 1 odpovida menu EndMenu,
                                  7 odpovida menu EndMenu-7. 0 ma nejvyssi
                                  prioritu, 7 ma prioritu nejnizsi}
    MenuIntEnable : Boolean;    {pri FlIntEnable=False jsou MenuInterrupty
                                 zakazany, neakceptuji se. Pri obsluze preruseni
                                 se automaticky nastavuje na False a pri navratu
                                 z obsluhy na true.}
    MenuIntCnt    : Byte;       {Pocita pocet vnorenych call v obsluze
                                 MenuInterruptu. Pri ret se citac
                                 dekrementuje a pri poslednim navratu se
                                 povoluje FlIntEnable}
    MenuIntChar   : Char;       {pro ulozeni ActCharu v MenuInterruptu Ulozeni
                                 a obnoveni ActCharu se v obsluze preruceni
                                 provadi automaticky}

    {implicitni nastaveni promenych}
    PrimEditWBeginX : Byte;    {pocatek editacniho okna X}
    PrimEditWBeginY : Byte;    {pocatek editacniho okna Y}
    PrimEditWWidth  : Byte;    {sire editacniho okna}
    PrimEditWHeight : Byte;    {vyska editacniho okna}
    PrimEditEnter   : Boolean; {podle teto konstantni hodnoty se nastavuje v kazdem kole InitParam promenna EditEnter}
    PrimEditWidth   : Byte;    {Pokud je EditSemiLogReal, tak se u vypisu Real
                               pouzije tento pocet znaku u exponencielniho
                               tvaru}
    PrimClrScreen   : Boolean; {podle teto promenne se standardne v kazde otocce
                               plni FlClrScr vypisu}

    {!cr....}
    Term            : pTermChr;    { ukazatel na objekt terminalu }
    {!cr.... !!pozor, mel by zde byt spravne type pATerm, nutno opravit }

    constructor Init(Menu: pMenu; EndIndex: Word;
                     var DisplayString, HelpString: String);
                {Menu je ukazatel na pole Pointeru na procedury
                typu tMMenu, EndInex je index posledni
                procedury v poli Menu^, DisplayString je ukazatel
                na string pro zobrazeni na vDisplay, HelpString
                je ukazatel na string pro zobrazeni helpu.}
    procedure   Run;                  virtual;
                {Podle ActMenu vybere nastavovaci proceduru
                 pro menu a spusti ji. Ta provede modifikaci
                 promennych objektu. Po navratu probehne
                 volani vsech metod podle skokove tabulky
                 pMetod}
    procedure   InitParam;            virtual;
                {Ve skokove tabulce nastavuje implicitni
                 procedury pro probehnuti RUN a implicitni
                 nastaveni modifikacnich promennych objektu}
    procedure   mNextMenu;
                {Metoda pro modifikaci ridici promenne podle
                 prijateho ActCharu}
    procedure   SetUserFirst   (P : Pointer);  virtual;
    procedure   SetDisplayMenu (P : Pointer);  virtual;
    procedure   SetUserSecond  (P : Pointer);  virtual;
    procedure   SetNextMenu    (P : Pointer);  virtual;
    procedure   SetUserThird   (P : Pointer);  virtual;

    function    GetUserFirst   : Pointer;  virtual;
    function    GetDisplayMenu : Pointer;  virtual;
    function    GetUserSecond  : Pointer;  virtual;
    function    GetNextMenu    : Pointer;  virtual;
    function    GetUserThird   : Pointer;  virtual;

    procedure   SetActMenu(A : Word);  virtual;
                {nastavuje hodnotu aktualni ridici promenne}
    function    GetActMenu : Word;     virtual;
    function    GetOldMenu : Word;     virtual;

{$ifdef Ver60}
    procedure   SetTerminateChar(SetChr: tSetChar);           virtual;
    procedure   AddTerminateChar(AddChr: tSetChar);           virtual;
    procedure   SubTerminateChar(SubChr: tSetChar);           virtual;
    procedure   AddSubTerminateChar(AddChr,SubChr: tSetChar); virtual;

    procedure   SetTransTab(SetChr: tSetChar; IndCtrlTab: tIndCtrlTab); virtual;
    procedure   SetCtrlTab(SetIndCtrlTab: tSetIndCtrlTab; Menu: Word);  virtual;
    procedure   SetTransCtrlTab(SetChr: tSetChar; IndCtrlTab: tIndCtrlTab; Menu: Word); virtual;
{$endif}
{$ifdef Ver70}
    procedure   SetTerminateChar(const SetChr: tSetChar);           virtual;
    procedure   AddTerminateChar(const AddChr: tSetChar);           virtual;
    procedure   SubTerminateChar(const SubChr: tSetChar);           virtual;
    procedure   AddSubTerminateChar(const AddChr,SubChr: tSetChar); virtual;

    procedure   SetTransTab(const SetChr: tSetChar; IndCtrlTab: tIndCtrlTab); virtual;
    procedure   SetCtrlTab(const SetIndCtrlTab: tSetIndCtrlTab; Menu: Word);  virtual;
    procedure   SetTransCtrlTab(const SetChr: tSetChar; IndCtrlTab: tIndCtrlTab; Menu: Word); virtual;
{$endif}
    procedure   SetEditWin(WBeginX,WBeginY,WWidth,WHeight:Byte); virtual;
                {Nastavuje promenne EditW....}
  end;

const                      {konstanta pro inicializaci TransTab}
  cTransTab : tTransTab =
        {   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   A,   B,   C,   D,   E,   F}
        {                                    BEL,  BS,  HT,  LF,            CR,         }
     {0}( i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, iCr, i00, i00,
        {                                                        ESC,           sBS,    }
     {1}  i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00,iRet, i00, i00, i00, i00,
        {  SP,   !,   ",   #,   $,   %,   &,   ',   (,   ),   *,   +,   ,,   -,   .,   /}
     {2}  i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00,
        {   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   :,   ;,   <,   =,   >,   ?}
     {3}  i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00,
        {   @,   A,   B,   C,   D,   E,   F,   G,   H,   I,   J,   K,   L,   M,   N,   O}
     {4}  i00,iYes, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, iNo, i00,
        {   P,   Q,   R,   S,   T,   U,   V,   W,   X,   Y,   Z,   [,   \,   ],   ^,   _}
     {5}  i00, i00, i00, i00, i00, i00, i00, i00, i00,iYes, i00, i00, i00, i00, i00, i00,
        {   `,   a,   b,   c,   d,   e,   f,   g,   h,   i,   j,   k,   l,   m,   n,   o}
     {6}  i00,iYes, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, iNo, i00,
        {   p,   q,   r,   s,   t,   u,   v,   w,   x,   y,   z,  }{,   |,  }{,   ~, DEL}
     {7}  i00, i00, i00, i00, i00, i00, i00, i00, i00,iYes, i00, i00, i00, i00, i00, i00,
        {                                                                               }
     {8}  i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00,
        {                                                                               }
     {9}  i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00,
        {                                                                               }
     {A}  i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00,
        {                                                         F1,  F2,  F3,  F4,  F5}
     {B}  i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00,
        {  F6,  F7,  F8,  F9, F10,          Home,  Up,PgUp,       Le,       Ri,      End}
     {C}  i00, i00, i00, i00, i00, i00, i00, i00, iUp, i00, i00, iLe, i00, iRi, i00, i00,
        {  Dn,PgDn, Ins,                                                                }
     {D}  iDn, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00,
        {                                                                               }
     {E}  i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00,
        {                                                                               }
     {F}  i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00, i00);
        {   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   A,   B,   C,   D,   E,   F}


                 {konstanta pro inicializaci CtrlTab}
  cCtrlTab   : tCtrlTab =
    (
    {iBeg,i00,iUp,iDn,iCr,iYes,iNo,iLe,iRi}
        0,  0,  0,  0,  0,   0,  0,  0,  0,
    {iCall1, iCall2, iCall3, iCall4, iCall5, iCall6, iCall7, iCall8, iCall9, iCall10}
          0,     0,     0,     0,     0,     0,     0,     0,     0,      0,
    {iCall11,iCall12,iCall13,iCall14,iCall15,iCall16,iCall17,iCall18,iCall19,iCall20}
          0,     0,     0,     0,     0,     0,     0,     0,     0,      0,
    {iCall21,iCall22,iCall23,iCall24,iCall25,iCall26,iCall27,iCall28,iCall29,iCall30}
          0,     0,     0,     0,     0,     0,     0,     0,     0,      0,
    {iCall31,iCall32,iCall33,iCall34,iCall35,iCall36,iCall37,iCall38,iCall39,iCall40}
          0,     0,     0,     0,     0,     0,     0,     0,     0,      0,
    {iRet  }
          0,
    {iJmp11, iJmp12, iJmp13, iJmp14, iJmp15, iJmp16, iJmp17, iJmp18, iJmp19, iJmp20}
          0,     0,     0,     0,     0,     0,     0,     0,     0,      0,
    {iJmp11, iJmp12, iJmp13, iJmp14, iJmp15, iJmp16, iJmp17, iJmp18, iJmp19, iJmp20}
          0,     0,     0,     0,     0,     0,     0,     0,     0,      0,
    {iJmp21, iJmp22, iJmp23, iJmp24, iJmp25, iJmp26, iJmp27, iJmp28, iJmp29, iJmp30}
          0,     0,     0,     0,     0,     0,     0,     0,     0,      0,
    {iJmp31, iJmp32, iJmp33, iJmp34, iJmp35, iJmp36, iJmp37, iJmp38, iJmp39, iJmp40}
          0,     0,     0,     0,     0,     0,     0,     0,     0,      0,
    {iEnd  }
          0);


procedure edNop(P: pAMenu); {prazdna procedura, nedela nic}

implementation

procedure edNop(P: pAMenu); {prazdna procedura, nedela nic}
begin
end;

{------------------TStackMenu------------------------}
constructor tStackMenu.Init;
begin
  {$ifdef Ver60}
   TObject.Init;
  {$else}
   inherited Init;
  {$endif}
  StackPointer:=0;
end;

procedure   tStackMenu.PushMenu(A:word); {str‡ˇ do stacku slovo A}
begin
  if StackPointer>=cStackSize then ;
  StackArray[StackPointer]:=A;
  inc(StackPointer);
end;

{-------------------------}
procedure tStackMenu.CondPushMenu(A:word);
                                      {str‡ˇ do stacku slovo A, pokud
                                      tam u‘ nenˇ}
begin
  if TopMenu<>A then PushMenu(A);
end;

{-------------------------}
function    tStackMenu.PopMenu : word;   {vyt hne ze stacku slovo A}
begin
  if StackPointer>0 then
  begin
    dec(StackPointer);
    PopMenu:=StackArray[StackPointer];
  end
  else PopMenu:=1;
end;

{-------------------------}
function   tStackMenu.CondPopMenu(A:word): Word;
                                       {pokud je slovo A ve stacku,
                                       tak ho vyt hne}
var B : word;
begin
  if TopMenu=A then  B:=PopMenu;
  CondPopMenu:=TopMenu;
end;

{-------------------------}
function    tStackMenu.TopMenu : word; {uk ‘e poslednˇ polo‘ku ve stacku}
begin
  if StackPointer>0 then
  begin
    TopMenu:=StackArray[StackPointer-1];
  end
  else TopMenu:=0;
end;

{---------------------------TAMenu----------------------------}
constructor tAMenu.Init(Menu: pMenu; EndIndex: Word;
                        var DisplayString, HelpString: String);
                           {A je ukazatel na pole Pointeru na procedury
                           typu tMMenu, EndInex je index posledni
                           procedury v poli A^, pDisplayStr je ukazatel
                           na string pro zobrazeni na vDisplay, pHelpStr
                           je ukazatel na string pro zobrazeni helpu.
                           SizeStack je velikost stacku pro menu.}
var i : Byte;
begin
{$ifdef Ver60}
  TObject.Init;
{$else}
  inherited Init;
{$endif}

{ v InitParam
  UserFirst
  MenuDisplay
  UserSecond
  MenuNext
  UserThird
}
  MenuDispStr   :=@DisplayString;
  MenuHelpStr   :=@HelpString;
  MenuArray     :=Menu;
  StackMenu.Init;
  ChangeMenu    :=True;
  ActMenu       :=0;
  PreMenu       :=1;
  OldMenu       :=0;
  EndMenu       :=EndIndex;
{ v InitParam
  TransTab
}
  TransUpCase   :=True;
{ v InitParam
  CtrlTab
}
  ClrScreen     :=True;

  ActChar       :=#$0;
  TerminateChar :=[#$0];
  VerifyChar    :=[#$0];
{
  EditWBeginX
  EditWBeginY
  EditWWidth
  EditWHigh
  EditVal
}
  EditEnter     :=True;
  EditSemiLogReal:=False;
  EditValWidth  :=cEditValWidth;
  EditValDecimals:=cEditValDecimals;
  EditLowLimit  :=-1e38;
  EditHiLimit   := 1e38;
  EditMultipl   :=1;
  EditNumElementsSet:=8;
  EditReject0   :=False;
  EditOk        :=False;
  EditWaitTime  :=1000;
  EditNum       :=nReal;
  EditBinCursor :=1; {!We 30.5.2001}

  MenuInt     :=[];
  MenuIntEnable    :=False;
  MenuIntCnt        :=0;
  MenuIntChar      :=#$0;

  PrimEditWBeginX:=1;
  PrimEditWBeginY:=4;
  PrimEditWWidth :=16;
  PrimEditWHeight:=1;
  SetEditWin(PrimEditWBeginX,PrimEditWBeginY,PrimEditWWidth,PrimEditWHeight);

  PrimEditEnter :=True;
  PrimClrScreen :=True;
  PrimEditWidth :=cPrimEditWidth;

  InitParam;
end;

{-------------------------}
procedure   tAMenu.SetUserFirst(P : Pointer);
begin
  UserFirst := tMMenu(P);
end;
{-------------------------}
procedure   tAMenu.SetDisplayMenu(P : Pointer);
begin
  DisplayMenu := tMMenu(P);
end;
{-------------------------}
procedure   tAMenu.SetUserSecond(P : Pointer);
begin
  UserSecond := tMMenu(P);
end;
{-------------------------}
procedure   tAMenu.SetNextMenu(P : Pointer);
begin
  NextMenu := tMMenu(P);
end;
{-------------------------}
procedure   tAMenu.SetUserThird(P : Pointer);
begin
  UserThird := tMMenu(P);
end;

{-------------------------}
function   tAMenu.GetUserFirst: Pointer;
var
  p : pointer;
begin
  tMMenu(p)      := UserFirst;
  GetUserFirst   := p;
end;
{-------------------------}
function   tAMenu.GetDisplayMenu: Pointer;
var
  p : pointer;
begin
  tMMenu(p)      := DisplayMenu;
  GetDisplayMenu := p;
end;
{-------------------------}
function   tAMenu.GetUserSecond: Pointer;
var
  p : pointer;
begin
  tMMenu(p)      := UserSecond;
  GetUserSecond  := p;
end;
{-------------------------}
function   tAMenu.GetNextMenu: Pointer;
var
  p : pointer;
begin
  tMMenu(p)      := NextMenu;
  GetNextMenu    := p;
end;
{-------------------------}
function   tAMenu.GetUserThird: Pointer;
var
  p : pointer;
begin
  tMMenu(p)    := UserThird;
  GetUserThird := p;
end;
{-------------------------}
procedure  tAMenu.InitParam;
                                {Ve skokove tabulce nastavuje implicitni
                                 procedury pro probehnuti RUN a implicitni
                                 nastaveni modifikacnich promennych objektu}
var
  p : Pointer;
begin
  UserFirst      :=edNop;
  DisplayMenu    :=edNop;
  UserSecond     :=edNop;
  p:=@tAMenu.mNextMenu;
  NextMenu       :=tMMenu(p);
  UserThird      :=edNop;
  TransTab       :=cTransTab;
  CtrlTab        :=cCtrlTab;
  CtrlTab[i00]   :=ActMenu;                              {pro ostatni ActChary}
  CtrlTab[iCr]   :=ActMenu;                              {Cr}
  CtrlTab[iLe]   :=ActMenu;                              {Le}
  CtrlTab[iRi]   :=ActMenu;                              {Ri}
  if ActMenu<>0 then
    CtrlTab[iUp]:=ActMenu-1;    {Up}
  if ActMenu<EndMenu then
    CtrlTab[iDn]:=ActMenu+1;    {Dn}

  ClrScreen      :=PrimClrScreen;
  ActChar        :=#$0;
  SetEditWin(PrimEditWBeginX,PrimEditWBeginY,PrimEditWWidth,PrimEditWHeight);
  EditEnter      :=PrimEditEnter;
  EditOk         :=False;
  EditSemilogReal:=false;
  EditReject0    :=false;
  EditValWidth   :=cEditValWidth;
  EditValDecimals:=cEditValDecimals;
  EditLowLimit   :=-1e38;
  EditHiLimit    :=+1e38;
  EditMultipl    :=1;
  EditWaitTime   :=1000;
end;
{-------------------------}
procedure  tAMenu.Run;
                                {Podle ActMenu vybere nastavovaci proceduru
                                 pro menu a spusti ji. Ta provede modifikaci
                                 promennych objektu. Po navratu probehne
                                 volani vsech metod podle skokove tabulky
                                 pMetod}
begin
  ActChar   :=#$0;
  ChangeMenu:=ActMenu<>PreMenu;
  if ChangeMenu then
  begin
    OldMenu:=PreMenu;
    PreMenu:=ActMenu;
    InitParam;                         {implicitni nastaveni}
  end
  else
    PreMenu:=ActMenu;
  MenuArray^[ActMenu](Pointer(@Self)); {vybrana inicializacni procedura}
  UserFirst(Pointer(@Self));            {1. user procedura}
  DisplayMenu(Pointer(@Self));

  UserSecond(Pointer(@Self));           {2. user procedura nebo Edit}

  Term^.Disp^.UpdateDisplay;           { refresh displeje }

  NextMenu(Pointer(@Self));             {detekce prijateho ActCharu}
  UserThird(Pointer(@Self));           {3. user procedura}
end;

{-------------------------}
procedure  tAMenu.mNextMenu;
                                {Metoda pro modifikaci ridici promenne podle
                                 prijateho ActCharu}
var
  A,B : Word;
  tt : tIndCtrlTab;
begin
  if MenuInt<>[] then
  begin
    if MenuIntEnable then
    begin
      MenuIntChar:=ActChar;
      ActChar:=#0;
      StackMenu.CondPushMenu(ActMenu);
      if 0 in MenuInt then
      begin
        SetActMenu(EndMenu);
        MenuInt:=MenuInt-[0];
      end
      else if 1 in MenuInt then
      begin
        SetActMenu(EndMenu-1);
        MenuInt:=MenuInt-[1];
      end
      else if 2 in MenuInt then
      begin
        SetActMenu(EndMenu-2);
        MenuInt:=MenuInt-[2];
      end
      else if 3 in MenuInt then
      begin
        SetActMenu(EndMenu-3);
        MenuInt:=MenuInt-[3];
      end
      else if 4 in MenuInt then
      begin
        SetActMenu(EndMenu-4);
        MenuInt:=MenuInt-[4];
      end
      else if 5 in MenuInt then
      begin
        SetActMenu(EndMenu-5);
        MenuInt:=MenuInt-[5];
      end
      else if 6 in MenuInt then
      begin
        SetActMenu(EndMenu-6);
        MenuInt:=MenuInt-[6];
      end
      else if 7 in MenuInt then
      begin
        SetActMenu(EndMenu-7);
        MenuInt:=MenuInt-[7];
      end;
      MenuIntEnable:=False;
      MenuIntCnt:=1;
      Exit;
    end;
  end;

  if TransUpCase then
    ActChar:= UpCase(ActChar);
  if ActChar in TerminateChar then
  with StackMenu do
  begin
    tt:=TransTab[ActChar];
    if (tt in [iCall1..iCall40]) then
    begin
      if (CtrlTab[tt] <= EndMenu) then
      begin
        CondPushMenu(ActMenu);
        SetActMenu(CtrlTab[tt]);
        if MenuIntCnt>0 then
          Inc(MenuIntCnt);
      end;
    end
    else if tt=iRet then
    begin
      SetActMenu(PopMenu);  {Esc}
      if MenuIntCnt>0 then
      begin
        Dec(MenuIntCnt);
        if MenuIntCnt=0 then
        begin
          MenuIntEnable:=true;
          ActChar:=MenuIntChar;
        end;
      end;
    end
    else if (tt in [iJmp1..iJmp40]) then
    begin
      if (CtrlTab[tt] <= EndMenu) then
        SetActMenu(CtrlTab[tt]);
    end
    else if tt=iUp then
    begin
      A:=CondPopMenu(CtrlTab[tt]);
      SetActMenu(CtrlTab[tt]);
    end
    else {if CtrlTab[tt]>0 then}  {!W 17.7.1997}
      SetActMenu(CtrlTab[tt]);
  end;
end;


{-------------------------}
procedure  tAMenu.SetActMenu(A : Word);
                                {nastavuje hodnotu aktualni ridici promenne}
begin
  if A<=EndMenu  then ActMenu:=A;
end;

{-------------------------}
function   tAMenu.GetActMenu : Word;
begin
  GetActMenu := ActMenu;
end;

{-------------------------}
function   tAMenu.GetOldMenu : Word;
begin
  GetOldMenu := OldMenu;
end;

{-------------------------}
{$ifdef Ver60}
procedure  tAMenu.SetTerminateChar(SetChr: tSetChar);
{$endif}
{$ifdef Ver70}
procedure  tAMenu.SetTerminateChar(const SetChr: tSetChar);
{$endif}
begin
  TerminateChar:=SetChr;
end;
{-------------------------}
{$ifdef Ver60}
procedure  tAMenu.AddTerminateChar(AddChr: tSetChar);
{$endif}
{$ifdef Ver70}
procedure  tAMenu.AddTerminateChar(const AddChr: tSetChar);
{$endif}
begin
  TerminateChar:=TerminateChar+AddChr;
end;
{-------------------------}
{$ifdef Ver60}
procedure  tAMenu.SubTerminateChar(SubChr: tSetChar);
{$endif}
{$ifdef Ver70}
procedure  tAMenu.SubTerminateChar(const SubChr: tSetChar);
{$endif}
begin
  TerminateChar:=TerminateChar-SubChr;
end;
{-------------------------}
{$ifdef Ver60}
procedure  tAMenu.AddSubTerminateChar(AddChr,SubChr: tSetChar);
{$endif}
{$ifdef Ver70}
procedure  tAMenu.AddSubTerminateChar(const AddChr,SubChr: tSetChar);
{$endif}
begin
  TerminateChar:=TerminateChar+AddChr-SubChr;
end;

{-------------------------}
{$ifdef Ver60}
procedure  tAMenu.SetTransTab(SetChr: tSetChar; IndCtrlTab: tIndCtrlTab);
{$endif}
{$ifdef Ver70}
procedure  tAMenu.SetTransTab(const SetChr: tSetChar; IndCtrlTab: tIndCtrlTab);
{$endif}
var
  z1,z2,z3 : Char;
begin
  z1:=#$0;
  z2:=#$0f;
  repeat
    if ([z1..z2] * SetChr)<>[] then
    begin
      for z3:=z1 to z2 do
      begin
        if z3 in SetChr then
        begin
          TransTab[z3]:=IndCtrlTab;
        end;
      end;
    end;
   {$R-}
    z1:=Chr(Ord(z1)+$10);
    z2:=Chr(Ord(z2)+$10);
   {$R+}
  until z1=#$0;
end;
{-------------------------}
{$ifdef Ver60}
procedure  tAMenu.SetCtrlTab(SetIndCtrlTab: tSetIndCtrlTab; Menu: Word);
{$endif}
{$ifdef Ver70}
procedure  tAMenu.SetCtrlTab(const SetIndCtrlTab: tSetIndCtrlTab; Menu: Word);
{$endif}
var
  i1,i2,i3 : tIndCtrlTab;
begin
  i1:=iBeg;
  i2:=tIndCtrlTab(Ord(iBeg)+$0f);
  repeat
    if ([i1..i2] * SetIndCtrlTab)<>[] then
    begin
      for i3:=i1 to i2 do
      begin
        if i3 in SetIndCtrlTab then
        begin
          CtrlTab[i3]:=Menu;
        end;
      end;
    end;
   {$R-}
    i1:=tIndCtrlTab(Ord(i1)+$10);
    i2:=tIndCtrlTab(Ord(i2)+$10);
   {$R+}
  until i1=iBeg;
end;
{-------------------------}
{$ifdef Ver60}
procedure  tAMenu.SetTransCtrlTab(SetChr: tSetChar; IndCtrlTab: tIndCtrlTab; Menu: Word);
{$endif}
{$ifdef Ver70}
procedure  tAMenu.SetTransCtrlTab(const SetChr: tSetChar; IndCtrlTab: tIndCtrlTab; Menu: Word);
{$endif}
var
  z1,z2,z3 : Char;
begin
  z1:=#$0;
  z2:=#$0f;
  repeat
    if ([z1..z2] * SetChr)<>[] then
    begin
      for z3:=z1 to z2 do
      begin
        if z3 in SetChr then
        begin
          TransTab[z3]:=IndCtrlTab;
        end;
      end;
    end;
   {$R-}
    z1:=Chr(Ord(z1)+$10);
    z2:=Chr(Ord(z2)+$10);
   {$R+}
  until z1=#$0;
  CtrlTab[IndCtrlTab]:=Menu;
end;
{-------------------------}
procedure  tAMenu.SetEditWin(WBeginX,WBeginY,WWidth,WHeight:Byte);
                                {Nastavuje promenne EditW....}
begin
  EditWBeginX := WBeginX;
  EditWBeginY := WBeginY;
  EditWWidth  := WWidth;
  EditWHeight := WHeight;
end;
{-------------------------}
end.
