------------------------------------------------------------------------------
--                                                                          --
--                       GNAT ncurses Binding Samples                       --
--                                                                          --
--                                 ncurses                                  --
--                                                                          --
--                                 B O D Y                                  --
--                                                                          --
------------------------------------------------------------------------------
-- Copyright (c) 2000-2006,2008 Free Software Foundation, Inc.              --
--                                                                          --
-- Permission is hereby granted, free of charge, to any person obtaining a  --
-- copy of this software and associated documentation files (the            --
-- "Software"), to deal in the Software without restriction, including      --
-- without limitation the rights to use, copy, modify, merge, publish,      --
-- distribute, distribute with modifications, sublicense, and/or sell       --
-- copies of the Software, and to permit persons to whom the Software is    --
-- furnished to do so, subject to the following conditions:                 --
--                                                                          --
-- The above copyright notice and this permission notice shall be included  --
-- in all copies or substantial portions of the Software.                   --
--                                                                          --
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  --
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               --
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   --
-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   --
-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    --
-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    --
-- THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               --
--                                                                          --
-- Except as contained in this notice, the name(s) of the above copyright   --
-- holders shall not be used in advertising or otherwise to promote the     --
-- sale, use or other dealings in this Software without prior written       --
-- authorization.                                                           --
------------------------------------------------------------------------------
--  Author: Eugene V. Melaragno <aldomel@ix.netcom.com> 2000
--  Version Control
--  $Revision: 1.8 $
--  $Date: 2008/07/26 18:47:50 $
--  Binding Version 01.00
------------------------------------------------------------------------------
--  TODO use Default_Character where appropriate

--  This is an Ada version of ncurses
--  I translated this because it tests the most features.

with Terminal_Interface.Curses; use Terminal_Interface.Curses;
with Terminal_Interface.Curses.Trace; use Terminal_Interface.Curses.Trace;

with Ada.Text_IO; use Ada.Text_IO;

with Ada.Characters.Latin_1;
--  with Ada.Characters.Handling;

with Ada.Command_Line; use Ada.Command_Line;

with Ada.Strings.Unbounded;

with ncurses2.util; use ncurses2.util;
with ncurses2.getch_test;
with ncurses2.attr_test;
with ncurses2.color_test;
with ncurses2.demo_panels;
with ncurses2.color_edit;
with ncurses2.slk_test;
with ncurses2.acs_display;
with ncurses2.acs_and_scroll;
with ncurses2.flushinp_test;
with ncurses2.test_sgr_attributes;
with ncurses2.menu_test;
with ncurses2.demo_pad;
with ncurses2.demo_forms;
with ncurses2.overlap_test;
with ncurses2.trace_set;

with ncurses2.getopt; use ncurses2.getopt;

package body ncurses2.m is
   use Int_IO;

   function To_trace (n : Integer) return Trace_Attribute_Set;
   procedure usage;
   procedure Set_Terminal_Modes;
   function Do_Single_Test (c : Character) return Boolean;

   function To_trace (n : Integer) return Trace_Attribute_Set is
      a : Trace_Attribute_Set := (others => False);
      m : Integer;
      rest : Integer;
   begin
      m := n  mod 2;
      if 1 = m then
         a.Times := True;
      end if;
      rest := n / 2;

      m := rest mod 2;
      if 1 = m then
         a.Tputs := True;
      end if;
      rest := rest / 2;
      m := rest mod 2;
      if 1 = m then
         a.Update := True;
      end if;
      rest := rest / 2;
      m := rest mod 2;
      if 1 = m then
         a.Cursor_Move := True;
      end if;
      rest := rest / 2;
      m := rest mod 2;
      if 1 = m then
         a.Character_Output := True;
      end if;
      rest := rest / 2;
      m := rest mod 2;
      if 1 = m then
         a.Calls := True;
      end if;
      rest := rest / 2;
      m := rest mod 2;
      if 1 = m then
         a.Virtual_Puts := True;
      end if;
      rest := rest / 2;
      m := rest mod 2;
      if 1 = m then
         a.Input_Events := True;
      end if;
      rest := rest / 2;
      m := rest mod 2;
      if 1 = m then
         a.TTY_State := True;
      end if;
      rest := rest / 2;
      m := rest mod 2;
      if 1 = m then
         a.Internal_Calls := True;
      end if;
      rest := rest / 2;
      m := rest mod 2;
      if 1 = m then
         a.Character_Calls := True;
      end if;
      rest := rest / 2;
      m := rest mod 2;
      if 1 = m then
         a.Termcap_TermInfo := True;
      end if;

      return a;
   end To_trace;

   --   these are type Stdscr_Init_Proc;

   function rip_footer (
                        Win : Window;
                        Columns : Column_Count) return Integer;
   pragma Convention (C, rip_footer);

   function rip_footer (
                        Win : Window;
                        Columns : Column_Count) return Integer is
   begin
      Set_Background (Win, (Ch => ' ',
                            Attr => (Reverse_Video => True, others => False),
                            Color => 0));
      Erase (Win);
      Move_Cursor (Win, 0, 0);
      Add (Win, "footer:"  & Columns'Img & " columns");
      Refresh_Without_Update (Win);
      return 0; -- Curses_OK;
   end rip_footer;

   function rip_header (
                        Win : Window;
                        Columns : Column_Count) return Integer;
   pragma Convention (C, rip_header);

   function rip_header (
                        Win : Window;
                        Columns : Column_Count) return Integer is
   begin
      Set_Background (Win, (Ch => ' ',
                            Attr => (Reverse_Video => True, others => False),
                            Color => 0));
      Erase (Win);
      Move_Cursor (Win, 0, 0);
      Add (Win, "header:"  & Columns'Img & " columns");
      --  'Img is a GNAT extention
      Refresh_Without_Update (Win);
      return 0; -- Curses_OK;
   end rip_header;

   procedure usage is
      --  type Stringa is access String;
      use Ada.Strings.Unbounded;
      --  tbl : constant array (Positive range <>) of Stringa := (
      tbl : constant array (Positive range <>) of Unbounded_String
        := (
            To_Unbounded_String ("Usage: ncurses [options]"),
            To_Unbounded_String (""),
            To_Unbounded_String ("Options:"),
            To_Unbounded_String ("  -a f,b   set default-colors " &
                                 "(assumed white-on-black)"),
            To_Unbounded_String ("  -d       use default-colors if terminal " &
                                 "supports them"),
            To_Unbounded_String ("  -e fmt   specify format for soft-keys " &
                                 "test (e)"),
            To_Unbounded_String ("  -f       rip-off footer line " &
                                 "(can repeat)"),
            To_Unbounded_String ("  -h       rip-off header line " &
                                 "(can repeat)"),
            To_Unbounded_String ("  -s msec  specify nominal time for " &
                                 "panel-demo (default: 1, to hold)"),
            To_Unbounded_String ("  -t mask  specify default trace-level " &
                                 "(may toggle with ^T)")
            );
   begin
      for n in tbl'Range loop
         Put_Line (Standard_Error, To_String (tbl (n)));
      end loop;
      --     exit(EXIT_FAILURE);
      --  TODO should we use Set_Exit_Status and throw and exception?
   end usage;

   procedure Set_Terminal_Modes is begin
      Set_Raw_Mode (SwitchOn => False);
      Set_Cbreak_Mode (SwitchOn => True);
      Set_Echo_Mode (SwitchOn => False);
      Allow_Scrolling (Mode => True);
      Use_Insert_Delete_Line (Do_Idl => True);
      Set_KeyPad_Mode (SwitchOn => True);
   end Set_Terminal_Modes;

   nap_msec : Integer := 1;

   function Do_Single_Test (c : Character) return Boolean is
   begin
      case c is
         when 'a' =>
            getch_test;
         when 'b' =>
            attr_test;
         when 'c' =>
            if not Has_Colors then
               Cannot ("does not support color.");
            else
               color_test;
            end if;
         when 'd' =>
            if not Has_Colors then
               Cannot ("does not support color.");
            elsif not Can_Change_Color then
               Cannot ("has hardwired color values.");
            else
               color_edit;
            end if;
         when 'e' =>
            slk_test;
         when 'f' =>
            acs_display;
         when 'o' =>
            demo_panels (nap_msec);
         when 'g' =>
            acs_and_scroll;
         when 'i' =>
            flushinp_test (Standard_Window);
         when 'k' =>
            test_sgr_attributes;
         when 'm' =>
            menu_test;
         when 'p' =>
            demo_pad;
         when 'r' =>
            demo_forms;
         when 's' =>
            overlap_test;
         when 't' =>
            trace_set;
         when '?' =>
            null;
         when others => return False;
      end case;
      return True;
   end Do_Single_Test;

   command : Character;
   my_e_param : Soft_Label_Key_Format := Four_Four;
   assumed_colors : Boolean := False;
   default_colors : Boolean := False;
   default_fg : Color_Number := White;
   default_bg : Color_Number := Black;
   --  nap_msec was an unsigned long integer in the C version,
   --  yet napms only takes an int!

   c : Integer;
   c2 : Character;
   optind : Integer := 1; -- must be initialized to one.
   optarg : getopt.stringa;

   length : Integer;
   tmpi : Integer;

   package myio is new Ada.Text_IO.Integer_IO (Integer);
   use myio;

   save_trace : Integer := 0;
   save_trace_set : Trace_Attribute_Set;

   function main return Integer is
   begin
      loop
         Qgetopt (c, Argument_Count, Argument'Access,
                  "a:de:fhs:t:", optind, optarg);
         exit when c = -1;
         c2 := Character'Val (c);
         case c2 is
            when 'a' =>
               --  Ada doesn't have scanf, it doesn't even have a
               --  regular expression library.
               assumed_colors := True;
               myio.Get (optarg.all, Integer (default_fg), length);
               myio.Get (optarg.all (length + 2 .. optarg.all'Length),
                         Integer (default_bg), length);
            when 'd' =>
               default_colors := True;
            when 'e' =>
               myio.Get (optarg.all, tmpi, length);
               if tmpi > 3 then
                  usage;
                  return 1;
               end if;
               my_e_param := Soft_Label_Key_Format'Val (tmpi);
            when 'f' =>
               Rip_Off_Lines (-1, rip_footer'Access);
            when 'h' =>
               Rip_Off_Lines (1, rip_header'Access);
            when 's' =>
               myio.Get (optarg.all, nap_msec, length);
            when 't' =>
               myio.Get (optarg.all, save_trace, length);
            when others =>
               usage;
               return 1;
         end case;
      end loop;

      --  the C version had a bunch of macros here.

      --   if (!isatty(fileno(stdin)))
      --   isatty is not available in the standard Ada so skip it.
      save_trace_set := To_trace (save_trace);
      Trace_On (save_trace_set);

      Init_Soft_Label_Keys (my_e_param);

      Init_Screen;
      Set_Background (Ch => (Ch    => Blank,
                             Attr  => Normal_Video,
                             Color => Color_Pair'First));

      if Has_Colors then
         Start_Color;
         if default_colors then
            Use_Default_Colors;
         elsif assumed_colors then
            Assume_Default_Colors (default_fg, default_bg);
         end if;
      end if;

      Set_Terminal_Modes;
      Save_Curses_Mode (Curses);

      End_Windows;

      --  TODO add macro #if blocks.
      Put_Line ("Welcome to " & Curses_Version & ".  Press ? for help.");

      loop
         Put_Line ("This is the ncurses main menu");
         Put_Line ("a = keyboard and mouse input test");
         Put_Line ("b = character attribute test");
         Put_Line ("c = color test pattern");
         Put_Line ("d = edit RGB color values");
         Put_Line ("e = exercise soft keys");
         Put_Line ("f = display ACS characters");
         Put_Line ("g = display windows and scrolling");
         Put_Line ("i = test of flushinp()");
         Put_Line ("k = display character attributes");
         Put_Line ("m = menu code test");
         Put_Line ("o = exercise panels library");
         Put_Line ("p = exercise pad features");
         Put_Line ("q = quit");
         Put_Line ("r = exercise forms code");
         Put_Line ("s = overlapping-refresh test");
         Put_Line ("t = set trace level");
         Put_Line ("? = repeat this command summary");

         Put ("> ");
         Flush;

         command := Ada.Characters.Latin_1.NUL;
         --              get_input:
         --              loop
         declare
            Ch : Character;
         begin
            Get (Ch);
            --  TODO if read(ch) <= 0
            --  TODO ada doesn't have an Is_Space function
            command := Ch;
            --  TODO if ch = '\n' or '\r' are these in Ada?
         end;
         --              end loop get_input;

         declare
         begin
            if Do_Single_Test (command) then
               Flush_Input;
               Set_Terminal_Modes;
               Reset_Curses_Mode (Curses);
               Clear;
               Refresh;
               End_Windows;
               if command = '?' then
                  Put_Line ("This is the ncurses capability tester.");
                  Put_Line ("You may select a test from the main menu by " &
                            "typing the");
                  Put_Line ("key letter of the choice (the letter to left " &
                            "of the =)");
                  Put_Line ("at the > prompt.  The commands `x' or `q' will " &
                            "exit.");
               end if;
               --  continue; --why continue in the C version?
            end if;
         exception
            when Curses_Exception => End_Windows;
         end;

         exit when command = 'q';
      end loop;
      Curses_Free_All;
      return 0; -- TODO ExitProgram(EXIT_SUCCESS);
   end main;

end ncurses2.m;
