-- Topal: GPG/GnuPG and Alpine/Pine integration
-- Copyright (C) 2001--2022  Phillip J. Brooke
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 3 as
-- published by the Free Software Foundation.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.

with Char_Menus;
with CL_Menus;
with Globals;    use Globals;

pragma Elaborate_All(Char_Menus, CL_Menus);

package Menus is

   -- Yes/no.

   type YN_Index is (Yes, No);

   package YN_Menus is new Char_Menus (Index => YN_Index);

   function YN_Menu
   is new YN_Menus.Menu (Accept_Chars =>
                           YN_Menus.MA'(No  => ToUBS("Nn"),
                                        Yes => ToUBS("Yy")),
                         Char_Words   =>
                           YN_Menus.MA'(No  => ToUBS("[No]"),
                                        Yes => ToUBS("[Yes]")),
                         Default_Prompt => "{Y}es or {n}o?  ");

   -- Yes/no/remote.

   type YNR_Index is (Yes, No, Remote);

   package YNR_Menus is new Char_Menus (Index => YNR_Index);

   function YNR_Menu
   is new YNR_Menus.Menu (Accept_Chars =>
                           YNR_Menus.MA'(No  => ToUBS("Nn"),
                                         Yes => ToUBS("Yy"),
                                         Remote => ToUBS("Rr")),
                         Char_Words   =>
                           YNR_Menus.MA'(No  => ToUBS("[No]"),
                                         Yes => ToUBS("[Yes]"),
                                         Remote => ToUBS("[Remote]")),
                         Default_Prompt => "{Y}es, {n}o or {r}emote?  ");

   -- Continue?

   type Wait_Index is (Continue);

   package Wait_Menus is new Char_Menus (Index => Wait_Index);

   function Wait_Menu
   is new Wait_Menus.Menu (Accept_Chars =>
                             Wait_Menus.MA'(Continue => ToUBS(" ")),
                           Char_Words   =>
                             Wait_Menus.MA'(Continue =>
                                              ToUBS("[Continue]")),
                           Default_Prompt => "Press {space} to continue: ");

   -- Configuration top edit menu.

   type Edit_Index is (Quit, Save, Binary_Paths, GPG_Options,
                       DV_Settings, Own_Key, Key_Assoc, Key_Excl,
                       Set_Defaults, Toggle_Debug, Reset,
                       Toggle_ISO, MV_D_Setting, MV_V_Setting,
                       UGA_Setting,
                       Toggle_OIDN, Toggle_OIDH,
                       Toggle_SOS, Toggle_WIMS);

   package Edit_Menus is new Char_Menus (Index => Edit_Index);

   function Edit_Menu
   is new Edit_Menus.Menu
     (Accept_Chars =>
        Edit_Menus.MA'(Quit         => ToUBS("qQ"),
                       Save         => ToUBS("sS"),
                       Binary_Paths => ToUBS("pP"),
                       GPG_Options  => ToUBS("oO"),
                       DV_Settings  => ToUBS("eE"),
                       Own_Key      => ToUBS("mM"),
                       Key_Assoc    => ToUBS("aA"),
                       Key_Excl     => ToUBS("xX"),
                       Set_Defaults => ToUBS("dD"),
                       Toggle_Debug => ToUBS("bB"),
                       Toggle_ISO   => ToUBS("cC"),
                       MV_D_Setting   => ToUBS("vV"),
                       MV_V_Setting   => ToUBS("wW"),
                       UGA_Setting  => ToUBS("gG"),
                       Toggle_OIDN  => ToUBS("iI"),
                       Toggle_OIDH  => ToUBS("hH"),
                       Toggle_SOS   => ToUBS("nN"),
                       Toggle_WIMS   => ToUBS("tT"),
                       Reset        => ToUBS("rR")),
      Char_Words =>
        Edit_Menus.MA'(Quit         => ToUBS("[Quit editing]"),
                       Save         => ToUBS("[Save changes]"),
                       Binary_Paths => ToUBS("[Change binary paths]"),
                       GPG_Options  => ToUBS("[Change GPG options]"),
                       DV_Settings  => ToUBS("[Change decrypt/verify settings]"),
                       Own_Key      => ToUBS("[Change own key]"),
                       Key_Assoc    => ToUBS("[Edit key associations]"),
                       Key_Excl     => ToUBS("[Edit key exclusions]"),
                       Set_Defaults => ToUBS("[Set all defaults]"),
                       Toggle_Debug => ToUBS("[Toggle debugging]"),
                       Toggle_ISO   => ToUBS("[Toggle inline-separate-output]"),
                       MV_D_Setting   => ToUBS("[Change MIME viewer (decrypt) setting]"),
                       MV_V_Setting   => ToUBS("[Change MIME viewer (verify) setting]"),
                       UGA_Setting  => ToUBS("[Change use-agent setting]"),
                       Toggle_OIDN  => ToUBS("[Toggle omit-inline-disposition-name]"),
                       Toggle_OIDH  => ToUBS("[Toggle omit-inline-disposition-header]"),
                       Toggle_SOS   => ToUBS("[Toggle save-on-send]"),
                       Toggle_WIMS  => ToUBS("[Toggle wait-if-missing-keys"),
                       Reset        => ToUBS("[Reset to current saved configuration]")),
      Default_Prompt => "Change: "
      & " {m} Own key"
      & "                         {o} GPG options" & NL
      & "         {e} Decrypt/verify settings"
      & "         {c} Toggle inline-separate-output" & NL
      & "         {h} Toggle omit-inline-disposition-header" & NL
      & "         {i} Toggle omit-inline-disposition-name" & NL
      & "         {n} Toggle save-on-send             {t} Toggle wait-if-missing-keys" & NL
      & "         MIME viewer: {v} Change (decrypt) setting  {w} Change (verify) setting" & NL
      & "         {g} Change use GPG agent" & NL
--      & "         {a} Key associations (interactive config not implemented)" & NL
--      & "         {x} Key exclusions (interactive config not implemented)" & NL
      & "         {p} Binary paths (interactive config not implemented)" & NL
      & "         {r} Set config to current saved file"
      & "       {d} Set all defaults" & NL
      & "         {b} Toggle debugging" & NL
      & "         {s} Save changes"
      & "                           {q} Quit editing" & NL);

   -- Configuration options submenu.

   type Options_Index is (Quit,
                          Change_General, Change_GPG,
                          Change_Receiving, Change_Sending,
                          Default_General, Default_GPG,
                          Default_Receiving, Default_Sending,
                          Default_All);

   package Options_Menus is new Char_Menus (Index => Options_Index);

   function Options_Menu
   is new Options_Menus.Menu
     (Accept_Chars =>
        Options_Menus.MA'(Quit              => ToUBS("qQ"),
                          Change_General    => ToUBS("bB"),
                          Change_GPG        => ToUBS("aA"),
                          Change_Receiving  => ToUBS("cC"),
                          Change_Sending    => ToUBS("dD"),
                          Default_General   => ToUBS("fF"),
                          Default_GPG       => ToUBS("eE"),
                          Default_Receiving => ToUBS("gG"),
                          Default_Sending   => ToUBS("hH"),
                          Default_All       => ToUBS("iI")),
      Char_Words =>
        Options_Menus.MA'(Quit              => ToUBS("[Quit options submenu]"),
                          Change_General    => ToUBS("[Change general options]"),
                          Change_GPG        => ToUBS("[Change GPG options]"),
                          Change_Receiving  => ToUBS("[Change receiving options]"),
                          Change_Sending    => ToUBS("[Change sending options]"),
                          Default_General   => ToUBS("[Set general options to default]"),
                          Default_GPG       => ToUBS("[Set GPG options to default]"),
                          Default_Receiving => ToUBS("[Set receiving options to default]"),
                          Default_Sending   => ToUBS("[Set sending options to default]"),
                          Default_All       => ToUBS("[Set all defaults]")),
      Default_Prompt => "Change:   {a} GPG  {b} General  {c} Receiving  {d} Sending" & NL &
        "Defaults: {e} GPG  {f} General  {g} Receiving  {h} Sending" & NL &
        "{q} Quit this submenu    {i} Set all defaults" & NL);

   -- Configuration settings submenu.

   type Settings_Index is (Decrypt_Cached,
                           Decrypt_Cached_Use,
                           Decrypt_Not_Cached,
                           Decrypt_Not_Cached_Use,
                           Verify_Cached,
                           Verify_Cached_Use,
                           Verify_Not_Cached,
                           Verify_Not_Cached_Use,
                           Quit,
                           All_Defaults,
                           Toggle_Decrypt_Cached_Fast,
                           Toggle_Verify_Cached_Fast,
                           Toggle_Verify_Not_Cached_Fast);

   package Settings_Menus is new Char_Menus (Index => Settings_Index);

   function Settings_Menu
   is new Settings_Menus.Menu
     (Accept_Chars =>
        Settings_Menus.MA'(Decrypt_Cached                => ToUBS("aA"),
                           Decrypt_Cached_Use            => ToUBS("bB"),
                           Decrypt_Not_Cached            => ToUBS("cC"),
                           Decrypt_Not_Cached_Use        => ToUBS("dD"),
                           Verify_Cached                 => ToUBS("eE"),
                           Verify_Cached_Use             => ToUBS("fF"),
                           Verify_Not_Cached             => ToUBS("gG"),
                           Verify_Not_Cached_Use         => ToUBS("hH"),
                           Quit                          => ToUBS("qQ"),
                           All_Defaults                  => ToUBS("iI"),
                           Toggle_Decrypt_Cached_Fast    => ToUBS("jJ"),
                           Toggle_Verify_Cached_Fast     => ToUBS("kK"),
                           Toggle_Verify_Not_Cached_Fast => ToUBS("lL")),
      Char_Words =>
        Settings_Menus.MA'
        (Decrypt_Cached                 => ToUBS("[Decrypt, cached]"),
         Decrypt_Cached_Use             => ToUBS("[Decrypt, cached, cache usage]"),
         Decrypt_Not_Cached             => ToUBS("[Decrypt, not cached]"),
         Decrypt_Not_Cached_Use         => ToUBS("[Decrypt, not cached, cache usage]"),
         Verify_Cached                  => ToUBS("[Verify, cached]"),
         Verify_Cached_Use              => ToUBS("[Verify, cached, cache usage]"),
         Verify_Not_Cached              => ToUBS("[Verify, not cached]"),
         Verify_Not_Cached_Use          => ToUBS("[Verify, not cached, cache usage]"),
         Quit                           => ToUBS("[Quit settings submenu]"),
         All_Defaults                   => ToUBS("[Set all defaults]"),
         Toggle_Decrypt_Cached_Fast     => ToUBS("[Toggle decrypt/cached fast continue]"),
         Toggle_Verify_Cached_Fast      => ToUBS("[Toggle verify/cached fast continue]"),
         Toggle_Verify_Not_Cached_Fast  => ToUBS("[Toggle verify/not cached fast continue]")),
      Default_Prompt =>
        "Decrypt: {a} Cached  {b} Cache usage  {c} Not cached  {d} Cache usage" & NL &
        "Verify:  {e} Cached  {f} Cache usage  {g} Not cached  {h} Cache usage" & NL &
        "Tgl fast continue:  {j} Decrypt/cached  {k} Verify/cached  {l} Verify/not cached" & NL &
        "{q} Quit this submenu    {i} Set all defaults" & NL);

   -- Configuration three way switch.

   type Three_Way_Index is (Always, Ask, Never);

   package Three_Way_Menus is new Char_Menus (Index => Three_Way_Index);

   function Three_Way_Menu
   is new Three_Way_Menus.Menu
     (Accept_Chars =>
        Three_Way_Menus.MA'(Always => ToUBS("aA"),
                            Ask    => ToUBS("sS"),
                            Never  => ToUBS("nN")),
      Char_Words =>
        Three_Way_Menus.MA'(Always => ToUBS("[Always]"),
                            Ask    => ToUBS("[Ask]"),
                            Never  => ToUBS("[Never]")),
      Default_Prompt => "{a} Always  {s} Ask  {n} Never:  ");

   -- Configuration five way switch.

   type Five_Way_Index is (UUse, Replace, AskReplace, IgnoreCache, OfferAll);

   package Five_Way_Menus is new Char_Menus (Index => Five_Way_Index);

   function Five_Way_Menu
   is new Five_Way_Menus.Menu
     (Accept_Chars =>
        Five_Way_Menus.MA'(UUse        => ToUBS("uU"),
                           Replace     => ToUBS("rR"),
                           AskReplace  => ToUBS("aA"),
                           IgnoreCache => ToUBS("iI"),
                           OfferAll    => ToUBS("oO")),
      Char_Words =>
        Five_Way_Menus.MA'(UUse        => ToUBS("[Use]"),
                           Replace     => ToUBS("[Replace]"),
                           AskReplace  => ToUBS("[Ask-replace]"),
                           IgnoreCache => ToUBS("[Ignore cache]"),
                           OfferAll    => ToUBS("[Offer all]")),
      Default_Prompt => "{u} Use  {r} Replace  {a} Ask-replace  {i} Ignore  {o} Offer: ");

   -- Use-replace-ignore choice.

   type URI_Index is (UUse, Replace, Ignore);

   package URI_Menus is new Char_Menus (Index => URI_Index);

   function URI_Menu
   is new URI_Menus.Menu (Accept_Chars =>
                            URI_Menus.MA'(UUse    => ToUBS("uU"),
                                          Replace => ToUBS("rR"),
                                          Ignore  => ToUBS("iI")),
                           Char_Words   =>
                             URI_Menus.MA'(UUse    => ToUBS("[Use]"),
                                           Replace => ToUBS("[Replace]"),
                                           Ignore  => ToUBS("[Ignore]")),
                           Default_Prompt => "Cache file exists: {u}se it, {r}eplace it, or {i}gnore it?  ");

   -- Sending menu.

   type SendMime_Index is (AAbort, ListEdit, AddOwn, EditOwn,
                           AttachEdit, ViewMail, EditMail,
                           Encrypt, SignEncrypt, ClearSign,
                           NoGPG,
                           -- PO means `preserve original';
                           -- otherwise, overwrite original.
                           EncryptPO, SignEncryptPO, ClearSignPO,
                           DetachSignPO,
                           Configure,
                           Remote, Go,
                           -- Stuff that used to be in the MIME menu.
                           InlinePlain, AppPGP,
                           Multipart, MultipartEncap,
			   SMIME);
   subtype Send_Modes is SendMime_Index range Encrypt .. DetachSignPO;
   subtype MIME_Modes is SendMime_Index Range InlinePlain .. SMIME;

   package Send_Menus is new Char_Menus (Index => SendMime_Index);

   function Send_Menu_Pine_Mime
   is new Send_Menus.Menu
     (Accept_Chars =>
        Send_Menus.MA'(AAbort          => ToUBS("qQ"),
                       ListEdit        => ToUBS("lLkK"),
                       AddOwn          => ToUBS("@"),
                       EditOwn         => ToUBS("wW"),
                       AttachEdit      => ToUBS("aA"),
                       ViewMail        => ToUBS("vV"),
                       EditMail        => ToUBS("mM"),
                       Encrypt         => ToUBS("eE"),
                       SignEncrypt     => ToUBS("sS"),
                       ClearSign       => ToUBS("cC"),
                       Configure       => ToUBS("oO"),
                       NoGPG           => ToUBS("nN"),
                       Remote          => ToUBS("rR"),
                       Go              => ToUBS("gG"),
                       InlinePlain     => ToUBS("1"),
                       AppPGP          => ToUBS("2"),
                       Multipart       => ToUBS("3"),
                       MultipartEncap  => ToUBS("4"),
		       SMIME           => ToUBS("pP"),
                       EncryptPO | SignEncryptPO | ClearSignPO | DetachSignPO => ToUBS("")),
      Char_Words   =>
        Send_Menus.MA'(AAbort          => ToUBS("[Abort]"),
                       ListEdit        => ToUBS("[List/edit current recipient keys]"),
                       AddOwn          => ToUBS("[Add own key]"),
                       EditOwn         => ToUBS("[Edit own key]"),
                       AttachEdit      => ToUBS("[List/edit attachments]"),
                       ViewMail        => ToUBS("[View mail]"),
                       EditMail        => ToUBS("[Edit mail]"),
                       Encrypt         => ToUBS("[Encrypt]"),
                       SignEncrypt     => ToUBS("[Sign-encrypt]"),
                       ClearSign       => ToUBS("[Clearsign]"),
                       Configure       => ToUBS("[Configuration]"),
                       NoGPG           => ToUBS("[Unchanged; no crypto]"),
                       Remote          => ToUBS("[Remote now]"),
                       Go              => ToUBS("[Go now]"),
                       InlinePlain     => ToUBS("[Inline plain text]"),
                       AppPGP          => ToUBS("[application/pgp]"),
                       Multipart       => ToUBS("[RFC2015 multipart]"),
                       MultipartEncap  => ToUBS("[Multipart encapsulated]"),
		       SMIME           => ToUBS("[SMIME]"),
                       EncryptPO | SignEncryptPO | ClearSignPO | DetachSignPO => ToUBS("")),
      Default_Prompt =>
"{lkr} List/edit recip. keys   {@} Add own key       {w} Edit own key" & NL &
"{n} Pass through unchanged    {1} Inline plain      {v} View mail " & NL &
"{e} Encrypt                   {2} app/pgp           {m} Edit mail" & NL &
"{s} Sign-encrypt              {3} multipart/*       {a} List/edit attachments" & NL &
"{c} Clearsign                 {4} multipart encap   {o} Configuration" & NL &
"{g} Go!                       {r} Remote!           {q} Abort!" & NL &
"                              {p} S/MIME  " & NL
     );

   function Send_Menu_Pine_Plain
   is new Send_Menus.Menu
     (Accept_Chars =>
        Send_Menus.MA'(AAbort          => ToUBS("qQ"),
                       ListEdit        => ToUBS("lLkK"),
                       AddOwn          => ToUBS("@"),
                       EditOwn         => ToUBS("wW"),
                       AttachEdit      => ToUBS(""),
                       ViewMail        => ToUBS("vV"),
                       EditMail        => ToUBS("mM"),
                       Encrypt         => ToUBS("eE"),
                       SignEncrypt     => ToUBS("sS"),
                       ClearSign       => ToUBS("cC"),
                       Configure       => ToUBS("oO"),
                       NoGPG           => ToUBS("nN"),
                       Remote          => ToUBS("rR"),
                       Go              => ToUBS("gG"),
                       InlinePlain | AppPGP | Multipart | MultipartEncap
		       | SMIME
                       | EncryptPO | SignEncryptPO | ClearSignPO | DetachSignPO => ToUBS("")),
      Char_Words   =>
        Send_Menus.MA'(AAbort          => ToUBS("[Abort]"),
                       ListEdit        => ToUBS("[List/edit current recipient keys]"),
                       AddOwn          => ToUBS("[Add own key]"),
                       EditOwn         => ToUBS("[Edit own key]"),
                       AttachEdit      => ToUBS(""),
                       ViewMail        => ToUBS("[View mail]"),
                       EditMail        => ToUBS("[Edit mail]"),
                       Encrypt         => ToUBS("[Encrypt]"),
                       SignEncrypt     => ToUBS("[Sign-encrypt]"),
                       ClearSign       => ToUBS("[Clearsign]"),
                       Configure       => ToUBS("[Configuration]"),
                       NoGPG           => ToUBS("[Unchanged; no GPG]"),
                       Remote          => ToUBS("[Remote now]"),
                       Go              => ToUBS("[Go now]"),
                       InlinePlain | AppPGP | Multipart | MultipartEncap
		       | SMIME
                       | EncryptPO | SignEncryptPO | ClearSignPO | DetachSignPO => ToUBS("")),
      Default_Prompt =>
"{lkr} List/edit recip. keys   {@} Add own key       {w} Edit own key" & NL &
"{n} Pass through unchanged                          {v} View mail " & NL &
"{e} Encrypt                                         {m} Edit mail" & NL &
"{s} Sign-encrypt                                    " & NL &
"{c} Clearsign                                       {o} Configuration" & NL &
"{g} Go!                       {r} Remote!           {q} Abort!" & NL
);

   function Send_Menu_NP
   is new Send_Menus.Menu
     (Accept_Chars =>
        Send_Menus.MA'(AAbort            => ToUBS("qQ"),
                       ListEdit          => ToUBS("lLkK"),
                       AddOwn            => ToUBS("@"),
                       EditOwn           => ToUBS("wW"),
                       AttachEdit        => ToUBS(""),
                       ViewMail          => ToUBS("vV"),
                       EditMail          => ToUBS("mM"),
                       Encrypt           => ToUBS("e"),
                       SignEncrypt       => ToUBS("s"),
                       ClearSign         => ToUBS("c"),
                       EncryptPO         => ToUBS("E"),
                       SignEncryptPO     => ToUBS("S"),
                       ClearSignPO       => ToUBS("C"),
                       DetachSignPO      => ToUBS("D"),
                       NoGPG             => ToUBS("nN"),
                       Configure         => ToUBS("oO"),
                       Go                => ToUBS("gG"),
                       Remote | InlinePlain | AppPGP | Multipart | MultipartEncap | SMIME   => ToUBS("")),
      Char_Words   =>
        Send_Menus.MA'(AAbort            => ToUBS("[Abort]"),
                       ListEdit          => ToUBS("[List/edit current recipient keys]"),
                       AddOwn            => ToUBS("[Add own key]"),
                       EditOwn           => ToUBS("[Edit own key]"),
                       AttachEdit        => ToUBS(""),
                       ViewMail          => ToUBS("[View mail]"),
                       EditMail          => ToUBS("[Edit mail]"),
                       Encrypt           => ToUBS("[Encrypt, overwrite original]"),
                       SignEncrypt       => ToUBS("[Sign-encrypt, overwrite original]"),
                       ClearSign         => ToUBS("[Clearsign, overwrite original]"),
                       EncryptPO         => ToUBS("[Encrypt, preserve original]"),
                       SignEncryptPO     => ToUBS("[Sign-encrypt, preserve original]"),
                       ClearSignPO       => ToUBS("[Clearsign, preserve original]"),
                       DetachSignPO      => ToUBS("[Detach-sign]"),
                       NoGPG             => ToUBS("[Unchanged; no GPG]"),
                       Configure         => ToUBS("[Configuration]"),
                       Go                => ToUBS("[Go now]"),
                       Remote | InlinePlain | AppPGP | Multipart | MultipartEncap | SMIME   => ToUBS("")),
      Default_Prompt =>
"{lkr} List/edit recip. keys   {@} Add own key       {w} Edit own key" & NL &
"{n} Pass through unchanged    {D} Detach sig prsv   {v} View mail " & NL &
"{e} Encrypt                   {E} Encrypt prsv      {m} Edit mail" & NL &
"{s} Sign-encrypt              {S} Sign-encrypt prsv {o} Configuration" & NL &
"{c} Clearsign                 {C} Clearsign prsv    {q} Abort!" & NL &
"{g} Go!                       D, E, S and C preserve original file" & NL
);


   -- Operations on a specific key.

   type Specific_Key_Index is (Done, Display, DisplayVerbose, Remove, SSelect);

   package Specific_Key_Menus is new Char_Menus (Index => Specific_Key_Index);

   function Specific_Key_Menu1
   is new Specific_Key_Menus.Menu
     (Accept_Chars =>
        Specific_Key_Menus.MA'(Done           => ToUBS("kKqQlL"),
                               Display        => ToUBS("dD"),
                               DisplayVerbose => ToUBS("vV"),
                               Remove         => ToUBS("rR"),
                               SSelect        => ToUBS("")),
      Char_Words   =>
        Specific_Key_Menus.MA'(Done           => ToUBS("[Return to key list]"),
                               Display        => ToUBS("[Display details]"),
                               DisplayVerbose => ToUBS("[Verbose display details]"),
                               Remove         => ToUBS("[Remove key]"),
                               SSelect        => ToUBS("")),
      Default_Prompt =>
          "{d} Display details of key with less  {v} Verbosely"
        & NL
        & "{r} Remove key from list              {kql} Return to key list  "
        & NL);

   function Specific_Key_Menu2
   is new Specific_Key_Menus.Menu
     (Accept_Chars =>
        Specific_Key_Menus.MA'(Done           => ToUBS("kKqQlL"),
                               Display        => ToUBS("dD"),
                               DisplayVerbose => ToUBS("vV"),
                               Remove         => ToUBS(""),
                               SSelect        => ToUBS("sS")),
      Char_Words   =>
        Specific_Key_Menus.MA'(Done           => ToUBS("[Return to key list]"),
                               Display        => ToUBS("[Display details]"),
                               DisplayVerbose => ToUBS("[Verbose display details]"),
                               Remove         => ToUBS(""),
                               SSelect        => ToUBS("[Select this key]")),
      Default_Prompt =>
          "{d} Display details of key with less  {v} Verbosely"
        & NL
        & "{s} Select this key                   {kql} Return to key list  "
        & NL);

   -- Key list menu.

   type Keylist_Index is (Done, AddPattern, AddSearch);

   package Keylist_Menus is new CL_Menus (Index => Keylist_Index);

   function Keylist_Menu
   is new Keylist_Menus.Menu
     (Accept_Chars =>
        Keylist_Menus.MA'(Done       => ToUBS("dDqQ"),
                          AddPattern => ToUBS("aAkK"),
                          AddSearch  => ToUBS("sS")),
     Char_Words   =>
        Keylist_Menus.MA'(Done       => ToUBS("[Return to main send menu]"),
                          AddPattern => ToUBS("[Add keys from main keyring]"),
                          AddSearch  => ToUBS("[Select key from search]")),
      Default_Prompt =>
   "Select key or {dq} to quit and return to main send menu"
& NL
&  "           or {s} to select a key after searching in the main keyring"
& NL
&  "           or {ak} to add keys from the main keyring " & NL
& "                    (not recommended, use `s')"
     & NL,
     Default_Number_Word => "[",
     Default_Number_Trailword => "]" );

   function Keylist_Menu2
   is new Keylist_Menus.Menu
     (Accept_Chars =>
        Keylist_Menus.MA'(Done       => ToUBS("dDqQ"),
                          AddPattern => ToUBS(""),
                          AddSearch  => ToUBS("")),
     Char_Words   =>
        Keylist_Menus.MA'(Done       => ToUBS("[Return to main send menu]"),
                          AddPattern => ToUBS(""),
                          AddSearch  => ToUBS("")),
       Default_Prompt => "Select key, or {dq} to quit and return to main send menu"
        & NL,
     Default_Number_Word => "[",
     Default_Number_Trailword => "]" );

   -- Attachment list menu.

   type Attachlist_Index is (Done, Add);

   package Attachlist_Menus is new CL_Menus (Index => Attachlist_Index);

   function Attachlist_Menu
   is new Attachlist_Menus.Menu
     (Accept_Chars =>
        Attachlist_Menus.MA'(Done => ToUBS("dDqQ"),
                             Add  => ToUBS("aA")),
      Char_Words   =>
        Attachlist_Menus.MA'(Done => ToUBS("[Return to main send menu]"),
                             Add  => ToUBS("[Add file]")),
      Default_Prompt =>
        "Select file to remove" & NL
        & "{a} to add a file"
        & NL & "{dq} to quit and return to main send menu"
        & NL,
      Default_Number_Word => "[",
      Default_Number_Trailword => "]" );

   -- Two menus for MIME viewers, one which includes ask.

   type MIME_Viewer_Index is (Ask, Metamail, Run_Mailcap, Save, Skip);

   MV_Values : constant array (Mime_Viewer_Index) of Integer
     := (Ask => 1,
         Metamail => 2,
         Run_Mailcap => 3,
         Save => 4,
         Skip => 5);

   package MIME_Viewer_Menus is new Char_Menus (Index => MIME_Viewer_Index);

   function MIME_Viewer_Menu1
   is new MIME_Viewer_Menus.Menu
     (Accept_Chars =>
        MIME_Viewer_Menus.MA'(Ask         => ToUBS("aA"),
                              Metamail    => ToUBS("mM"),
                              Run_Mailcap => ToUBS("rR"),
                              Save        => ToUBS("sS"),
                              Skip        => ToUBS("kK")),
      Char_Words =>
        MIME_Viewer_Menus.MA'(Ask         => ToUBS("[Ask]"),
                              Metamail    => ToUBS("[Metamail]"),
                              Run_Mailcap => ToUBS("[Run-Mailcap]"),
                              Save        => ToUBS("[Save]"),
                              Skip        => ToUBS("[Skip]")),
      Default_Prompt => "{a} Ask  {m} metamail  {r} run-mailcap  {s} Save  {k} Skip:  ");

   function MIME_Viewer_Menu2
   is new MIME_Viewer_Menus.Menu
     (Accept_Chars =>
        MIME_Viewer_Menus.MA'(Ask         => ToUBS(""),
                              Metamail    => ToUBS("mM"),
                              Run_Mailcap => ToUBS("rR"),
                              Save        => ToUBS("sS"),
                              Skip        => ToUBS("kK")),
      Char_Words =>
        MIME_Viewer_Menus.MA'(Ask         => ToUBS(""),
                              Metamail    => ToUBS("[Metamail]"),
                              Run_Mailcap => ToUBS("[Run-Mailcap]"),
                              Save        => ToUBS("[Save]"),
                              Skip        => ToUBS("[Skip]")),
      Default_Prompt => "{m} metamail  {r} run-mailcap  {s} Save  {k} Skip:  ");

   -- Menu for use-agent.

   type Use_Agent_Index is (Never, Decrypt_Only, Always);

   UGA_Values : constant array (Use_Agent_Index) of Integer
     := (Never => 1,
         Decrypt_Only => 2,
         Always => 3);

   package Use_Agent_Menus is new Char_Menus (Index => Use_Agent_Index);

   function Use_Agent_Menu
   is new Use_Agent_Menus.Menu
     (Accept_Chars =>
        Use_Agent_Menus.MA'(Never         => ToUBS("nN"),
                            Decrypt_Only  => ToUBS("dD"),
                            Always        => ToUBS("aA")),
      Char_Words =>
        Use_Agent_Menus.MA'(Never         => ToUBS("[Never]"),
                            Decrypt_Only  => ToUBS("[Decrypt only]"),
                            Always        => ToUBS("[Always]")),
      Default_Prompt => "{n} Never  {d} Decrypt only  {a} Always:  ");

   -- Wait procedure.
   procedure Wait;

end Menus;

