--  This file is covered by the Internet Software Consortium (ISC) License
--  Reference: ../License.txt

with JohnnyText;

package body Display is

   package JT renames JohnnyText;

   ----------------------
   --  launch_monitor  --
   ----------------------
   function launch_monitor (num_builders : builders) return Boolean is
   begin
      TIC.Init_Screen;
      if not TIC.Has_Colors then
         TIC.End_Windows;
         return False;
      end if;
      TIC.Set_Echo_Mode (False);
      TIC.Set_Raw_Mode (True);
      TIC.Set_Cbreak_Mode (True);
      TIC.Set_Cursor_Visibility (Visibility => cursor_vis);

      establish_colors;

      launch_summary_zone;
      launch_builders_zone (num_builders);
      launch_actions_zone (num_builders);
      return True;
   end launch_monitor;

   -------------------------
   --  terminate_monitor  --
   -------------------------
   procedure terminate_monitor is
   begin
      TIC.Delete (Win => zone_actions);
      TIC.Delete (Win => zone_builders);
      TIC.Delete (Win => zone_summary);
      TIC.End_Windows;
   end terminate_monitor;

   ---------------------------
   --  launch_summary_zone  --
   ---------------------------
   procedure launch_summary_zone
   is
      line1 : String := "Total 0       Built 0      Ignored 0      " &
                        "Load  0.00  Pkg/hour 0   ";
      line2 : String := " Left 0      Failed 0      skipped 0      " &
                        "swap  0.0%   Impulse 0     00:00:00";
   begin
      zone_summary := TIC.Create (Number_Of_Lines       => 2,
                                  Number_Of_Columns     => app_width,
                                  First_Line_Position   => 0,
                                  First_Column_Position => 0);

      TIC.Set_Character_Attributes (Win   => zone_summary,
                                    Attr  => bright_bold,
                                    Color => TIC.Color_Pair (c_sumlabel));

      TIC.Move_Cursor (Win => zone_summary, Line => 0, Column => 0);
      TIC.Add (Win => zone_summary, Str => line1);
      TIC.Move_Cursor (Win => zone_summary, Line => 1, Column => 0);
      TIC.Add (Win => zone_summary, Str => line2);

      TIC.Refresh (Win => zone_summary);
   end launch_summary_zone;

   ----------------------------
   --  launch_builders_zone  --
   ----------------------------
   procedure launch_builders_zone (num_builders : builders)
   is
      hghtint : constant Integer := 4 + Integer (num_builders);
      height  : constant TIC.Line_Position := TIC.Line_Position (hghtint);
      lastrow : constant TIC.Line_Position := inc (height, -1);
      dashes  : constant String (1 .. 79) := (others => '=');
      header  : String (1 .. 79) := (others => ' ');
      headtxt : constant String := " ID  Elapsed   Build Phase      " &
        "Origin                                   Lines";
   begin
      header (1 .. headtxt'Length) := headtxt;
      zone_builders := TIC.Create (Number_Of_Lines       => height,
                                   Number_Of_Columns     => app_width,
                                   First_Line_Position   => 2,
                                   First_Column_Position => 0);

      TIC.Set_Character_Attributes (Win   => zone_builders,
                                    Attr  => bright,
                                    Color => TIC.Color_Pair (c_dashes));
      TIC.Move_Cursor (Win => zone_builders, Line => 0, Column => 0);
      TIC.Add (Win => zone_builders, Str => dashes);
      TIC.Move_Cursor (Win => zone_builders, Line => 2, Column => 0);
      TIC.Add (Win => zone_builders, Str => dashes);
      TIC.Move_Cursor (Win => zone_builders, Line => lastrow, Column => 0);
      TIC.Add (Win => zone_builders, Str => dashes);

      TIC.Set_Character_Attributes (Win   => zone_builders,
                                    Attr  => dimmed_bold,
                                    Color => TIC.Color_Pair (c_tableheader));
      TIC.Move_Cursor (Win => zone_builders, Line => 1, Column => 0);
      TIC.Add (Win => zone_builders, Str => header);

      TIC.Refresh (Win => zone_builders);
   end launch_builders_zone;

   ---------------------------
   --  launch_actions_zone  --
   ---------------------------
   procedure launch_actions_zone (num_builders : builders)
   is
      consumed   : constant Integer := Integer (num_builders) + 4 + 2;
      difference : constant Integer := 0 - consumed;
      viewheight : constant TIC.Line_Position := inc (TIC.Lines, difference);
      viewpos    : constant TIC.Line_Position := TIC.Line_Position (consumed);
   begin
      zone_actions := TIC.Create (Number_Of_Lines       => viewheight,
                                  Number_Of_Columns     => app_width,
                                  First_Line_Position   => viewpos,
                                  First_Column_Position => 0);
   end launch_actions_zone;

   -----------
   --  inc  --
   -----------
   function inc (X : TIC.Line_Position; by : Integer) return TIC.Line_Position
   is
      use type TIC.Line_Position;
   begin
      return X + TIC.Line_Position (by);
   end inc;

   -----------------
   --  summarize  --
   -----------------
   procedure summarize (data : summary_rec)
   is
      function pad (S : String; amount : Positive := 5) return String;
      function fmtpc (f : Float; percent : Boolean) return String;
      procedure colorado (S : String; color :  TIC.Color_Pair;
                          col : TIC.Column_Position;
                          row : TIC.Line_Position;
                          dim : Boolean := False);

      remaining : constant Integer := data.Initially - data.Built -
        data.Failed - data.Ignored - data.Skipped;

      function pad (S : String; amount : Positive := 5) return String
      is
         result : String (1 .. amount) := (others => ' ');
         slen   : constant Natural := S'Length;
      begin
         result (1 .. slen) := S;
         return result;
      end pad;
      function fmtpc (f : Float; percent : Boolean) return String
      is
         type loadtype is delta 0.01 digits 3;
         result : String (1 .. 5) := (others => ' ');
         raw1   : constant loadtype := loadtype (f);
         raw2   : constant String := raw1'Img;
         rlen   : constant Natural := raw2'Length;
         start  : constant Natural := 6 - rlen;
      begin
         result (start .. 5) := raw2;
         if percent then
            result (5) := '%';
         end if;
         return result;
      end fmtpc;
      procedure colorado (S : String; color :  TIC.Color_Pair;
                          col : TIC.Column_Position;
                          row : TIC.Line_Position;
                          dim : Boolean := False)
      is
         attribute : TIC.Character_Attribute_Set := bright_bold;
      begin
         if dim then
            attribute := dimmed;
         end if;
         TIC.Set_Character_Attributes (Win   => zone_summary,
                                       Attr  => attribute,
                                       Color => color);
         TIC.Move_Cursor (Win => zone_summary, Line => row, Column => col);
         TIC.Add (Win => zone_summary, Str => S);
      end colorado;

      L1F1 : constant String := pad (JT.int2str (data.Initially));
      L1F2 : constant String := pad (JT.int2str (data.Built));
      L1F3 : constant String := pad (JT.int2str (data.Ignored));
      L1F4 : constant String := fmtpc (data.load, False);
      L1F5 : constant String := pad (JT.int2str (data.pkg_hour), 4);

      L2F1 : constant String := pad (JT.int2str (remaining));
      L2F2 : constant String := pad (JT.int2str (data.Failed));
      L2F3 : constant String := pad (JT.int2str (data.Skipped));
      L2F4 : constant String := fmtpc (data.swap, True);
      L2F5 : constant String := pad (JT.int2str (data.impulse), 4);

   begin

      colorado (L1F1, c_standard,  6, 0);
      colorado (L1F2, c_success,  20, 0);
      colorado (L1F3, c_ignored,  35, 0);
      colorado (L1F4, c_standard, 47, 0, True);
      colorado (L1F5, c_standard, 63, 0, True);

      colorado (L2F1, c_standard,  6, 1);
      colorado (L2F2, c_failure,  20, 1);
      colorado (L2F3, c_skipped,  35, 1);
      colorado (L2F4, c_standard, 47, 1, True);
      colorado (L2F5, c_standard, 63, 1, True);
      colorado (data.elapsed, c_elapsed, 69, 1);

      TIC.Refresh (Win => zone_summary);
   end summarize;

   -----------------------
   --  update_builder   --
   -----------------------
   procedure update_builder (BR : builder_rec)
   is
      procedure colorado (S : String; color :  TIC.Color_Pair;
                          col : TIC.Column_Position;
                          row : TIC.Line_Position;
                          dim : Boolean := False);
      procedure print_id;
      row : TIC.Line_Position := inc (TIC.Line_Position (BR.id), 2);

      procedure print_id is
      begin
         TIC.Set_Character_Attributes (Win   => zone_builders,
                                       Attr  => c_slave (BR.id).attribute,
                                       Color => c_slave (BR.id).palette);
         TIC.Move_Cursor (Win => zone_builders, Line => row, Column => 1);
         TIC.Add (Win => zone_builders, Str => BR.slavid);
      end print_id;
      procedure colorado (S : String; color :  TIC.Color_Pair;
                          col : TIC.Column_Position;
                          row : TIC.Line_Position;
                          dim : Boolean := False)
      is
         attribute : TIC.Character_Attribute_Set := bright_bold;
      begin
         if dim then
            attribute := dimmed;
         end if;
         TIC.Set_Character_Attributes (Win   => zone_builders,
                                       Attr  => attribute,
                                       Color => color);
         TIC.Move_Cursor (Win => zone_builders, Line => row, Column => col);
         TIC.Add (Win => zone_builders, Str => S);
      end colorado;
   begin
      print_id;
      colorado (BR.Elapsed, c_standard,  5, row, True);
      colorado (BR.phase,   c_bldphase, 15, row, True);
      colorado (BR.origin,  c_origin,   32, row, False);
      colorado (BR.LLines,  c_standard, 71, row, True);
   end update_builder;

   ------------------------------
   --  refresh_builder_window  --
   ------------------------------
   procedure refresh_builder_window is
   begin
      TIC.Refresh (Win => zone_builders);
   end refresh_builder_window;

   ------------------------
   --  establish_colors  --
   ------------------------
   procedure establish_colors is
   begin
      TIC.Start_Color;
      TIC.Init_Pair (TIC.Color_Pair (1), TIC.White,   TIC.Black);
      TIC.Init_Pair (TIC.Color_Pair (2), TIC.Green,   TIC.Black);
      TIC.Init_Pair (TIC.Color_Pair (3), TIC.Red,     TIC.Black);
      TIC.Init_Pair (TIC.Color_Pair (4), TIC.Yellow,  TIC.Black);
      TIC.Init_Pair (TIC.Color_Pair (5), TIC.Black,   TIC.Black);
      TIC.Init_Pair (TIC.Color_Pair (6), TIC.Cyan,    TIC.Black);
      TIC.Init_Pair (TIC.Color_Pair (7), TIC.Blue,    TIC.Black);
      TIC.Init_Pair (TIC.Color_Pair (8), TIC.Magenta, TIC.Black);
      TIC.Init_Pair (TIC.Color_Pair (9), TIC.Blue,    TIC.White);

      c_standard    := TIC.Color_Pair (1);
      c_success     := TIC.Color_Pair (2);
      c_failure     := TIC.Color_Pair (3);
      c_ignored     := TIC.Color_Pair (4);
      c_skipped     := TIC.Color_Pair (5);
      c_sumlabel    := TIC.Color_Pair (6);
      c_dashes      := TIC.Color_Pair (7);
      c_elapsed     := TIC.Color_Pair (4);
      c_tableheader := TIC.Color_Pair (1);
      c_origin      := TIC.Color_Pair (6);
      c_bldphase    := TIC.Color_Pair (4);

      c_slave  (1).palette   := TIC.Color_Pair (1);  --  white / Black
      c_slave  (1).attribute := bright;

      c_slave  (2).palette   := TIC.Color_Pair (2);  --  light green / Black
      c_slave  (2).attribute := bright;

      c_slave  (3).palette   := TIC.Color_Pair (4);  --  yellow / Black
      c_slave  (3).attribute := bright;

      c_slave  (4).palette   := TIC.Color_Pair (3);  --  light red / Black
      c_slave  (4).attribute := bright;

      c_slave  (5).palette   := TIC.Color_Pair (8);  --  light magenta / Black
      c_slave  (5).attribute := bright;

      c_slave  (6).palette   := TIC.Color_Pair (7);  --  light blue / Black
      c_slave  (6).attribute := bright;

      c_slave  (7).palette   := TIC.Color_Pair (6);  --  light cyan / Black
      c_slave  (7).attribute := bright;

      c_slave  (8).palette   := TIC.Color_Pair (5);  --  dark grey / Black
      c_slave  (8).attribute := bright;

      c_slave  (9).palette   := TIC.Color_Pair (1);  --  light grey / Black
      c_slave  (9).attribute := dimmed;

      c_slave (10).palette   := TIC.Color_Pair (2);  --  light green / Black
      c_slave (10).attribute := dimmed;

      c_slave (11).palette   := TIC.Color_Pair (4);  --  brown / Black
      c_slave (11).attribute := dimmed;

      c_slave (12).palette   := TIC.Color_Pair (3);  --  dark red / Black
      c_slave (12).attribute := dimmed;

      c_slave (13).palette   := TIC.Color_Pair (8);  --  dark magenta / Black
      c_slave (13).attribute := dimmed;

      c_slave (14).palette   := TIC.Color_Pair (7);  --  dark blue / Black
      c_slave (14).attribute := dimmed;

      c_slave (15).palette   := TIC.Color_Pair (6);  --  dark cyan / Black
      c_slave (15).attribute := dimmed;

      c_slave (16).palette   := TIC.Color_Pair (9);  --  white / dark blue
      c_slave (16).attribute := dimmed;

      for bld in builders (17) .. builders (32)  loop
         c_slave (bld) := c_slave (bld - 16);
         c_slave (bld - 16).attribute.Bold_Character := True;
      end loop;
      for bld in builders (33) .. builders (64)  loop
         c_slave (bld) := c_slave (bld - 32);
      end loop;

   end establish_colors;

end Display;

--  This file is covered by the Internet Software Consortium (ISC) License
--  Reference: ../License.txt

with JohnnyText;

package body Display is

   package JT renames JohnnyText;

   ----------------------
   --  launch_monitor  --
   ----------------------
   function launch_monitor (num_builders : builders) return Boolean is
   begin
      TIC.Init_Screen;
      if not TIC.Has_Colors then
         TIC.End_Windows;
         return False;
      end if;
      TIC.Set_Echo_Mode (False);
      TIC.Set_Raw_Mode (True);
      TIC.Set_Cbreak_Mode (True);
      TIC.Set_Cursor_Visibility (Visibility => cursor_vis);

      establish_colors;

      launch_summary_zone;
      launch_builders_zone (num_builders);
      launch_actions_zone (num_builders);
      return True;
   end launch_monitor;

   -------------------------
   --  terminate_monitor  --
   -------------------------
   procedure terminate_monitor is
   begin
      TIC.Delete (Win => zone_actions);
      TIC.Delete (Win => zone_builders);
      TIC.Delete (Win => zone_summary);
      TIC.End_Windows;
   end terminate_monitor;

   ---------------------------
   --  launch_summary_zone  --
   ---------------------------
   procedure launch_summary_zone
   is
      line1 : String := "Total 0       Built 0      Ignored 0      " &
                        "Load  0.00  Pkg/hour 0   ";
      line2 : String := " Left 0      Failed 0      skipped 0      " &
                        "swap  0.0%   Impulse 0     00:00:00";
   begin
      zone_summary := TIC.Create (Number_Of_Lines       => 2,
                                  Number_Of_Columns     => app_width,
                                  First_Line_Position   => 0,
                                  First_Column_Position => 0);

      TIC.Set_Character_Attributes (Win   => zone_summary,
                                    Attr  => bright_bold,
                                    Color => TIC.Color_Pair (c_sumlabel));

      TIC.Move_Cursor (Win => zone_summary, Line => 0, Column => 0);
      TIC.Add (Win => zone_summary, Str => line1);
      TIC.Move_Cursor (Win => zone_summary, Line => 1, Column => 0);
      TIC.Add (Win => zone_summary, Str => line2);

      TIC.Refresh (Win => zone_summary);
   end launch_summary_zone;

   ----------------------------
   --  launch_builders_zone  --
   ----------------------------
   procedure launch_builders_zone (num_builders : builders)
   is
      hghtint : constant Integer := 4 + Integer (num_builders);
      height  : constant TIC.Line_Position := TIC.Line_Position (hghtint);
      lastrow : constant TIC.Line_Position := inc (height, -1);
      dashes  : constant String (1 .. 79) := (others => '=');
      header  : String (1 .. 79) := (others => ' ');
      headtxt : constant String := " ID  Elapsed   Build Phase      " &
        "Origin                                   Lines";
   begin
      header (1 .. headtxt'Length) := headtxt;
      zone_builders := TIC.Create (Number_Of_Lines       => height,
                                   Number_Of_Columns     => app_width,
                                   First_Line_Position   => 2,
                                   First_Column_Position => 0);

      TIC.Set_Character_Attributes (Win   => zone_builders,
                                    Attr  => bright,
                                    Color => TIC.Color_Pair (c_dashes));
      TIC.Move_Cursor (Win => zone_builders, Line => 0, Column => 0);
      TIC.Add (Win => zone_builders, Str => dashes);
      TIC.Move_Cursor (Win => zone_builders, Line => 2, Column => 0);
      TIC.Add (Win => zone_builders, Str => dashes);
      TIC.Move_Cursor (Win => zone_builders, Line => lastrow, Column => 0);
      TIC.Add (Win => zone_builders, Str => dashes);

      TIC.Set_Character_Attributes (Win   => zone_builders,
                                    Attr  => dimmed_bold,
                                    Color => TIC.Color_Pair (c_tableheader));
      TIC.Move_Cursor (Win => zone_builders, Line => 1, Column => 0);
      TIC.Add (Win => zone_builders, Str => header);

      TIC.Refresh (Win => zone_builders);
   end launch_builders_zone;

   ---------------------------
   --  launch_actions_zone  --
   ---------------------------
   procedure launch_actions_zone (num_builders : builders)
   is
      consumed   : constant Integer := Integer (num_builders) + 4 + 2;
      difference : constant Integer := 0 - consumed;
      viewheight : constant TIC.Line_Position := inc (TIC.Lines, difference);
      viewpos    : constant TIC.Line_Position := TIC.Line_Position (consumed);
   begin
      zone_actions := TIC.Create (Number_Of_Lines       => viewheight,
                                  Number_Of_Columns     => app_width,
                                  First_Line_Position   => viewpos,
                                  First_Column_Position => 0);
   end launch_actions_zone;

   -----------
   --  inc  --
   -----------
   function inc (X : TIC.Line_Position; by : Integer) return TIC.Line_Position
   is
      use type TIC.Line_Position;
   begin
      return X + TIC.Line_Position (by);
   end inc;

   -----------------
   --  summarize  --
   -----------------
   procedure summarize (data : summary_rec)
   is
      function pad (S : String; amount : Positive := 5) return String;
      function fmtpc (f : Float; percent : Boolean) return String;
      procedure colorado (S : String; color :  TIC.Color_Pair;
                          col : TIC.Column_Position;
                          row : TIC.Line_Position;
                          dim : Boolean := False);

      remaining : constant Integer := data.Initially - data.Built -
        data.Failed - data.Ignored - data.Skipped;

      function pad (S : String; amount : Positive := 5) return String
      is
         result : String (1 .. amount) := (others => ' ');
         slen   : constant Natural := S'Length;
      begin
         result (1 .. slen) := S;
         return result;
      end pad;
      function fmtpc (f : Float; percent : Boolean) return String
      is
         type loadtype is delta 0.01 digits 3;
         result : String (1 .. 5) := (others => ' ');
         raw1   : constant loadtype := loadtype (f);
         raw2   : constant String := raw1'Img;
         rlen   : constant Natural := raw2'Length;
         start  : constant Natural := 6 - rlen;
      begin
         result (start .. 5) := raw2;
         if percent then
            result (5) := '%';
         end if;
         return result;
      end fmtpc;
      procedure colorado (S : String; color :  TIC.Color_Pair;
                          col : TIC.Column_Position;
                          row : TIC.Line_Position;
                          dim : Boolean := False)
      is
         attribute : TIC.Character_Attribute_Set := bright_bold;
      begin
         if dim then
            attribute := dimmed;
         end if;
         TIC.Set_Character_Attributes (Win   => zone_summary,
                                       Attr  => attribute,
                                       Color => color);
         TIC.Move_Cursor (Win => zone_summary, Line => row, Column => col);
         TIC.Add (Win => zone_summary, Str => S);
      end colorado;

      L1F1 : constant String := pad (JT.int2str (data.Initially));
      L1F2 : constant String := pad (JT.int2str (data.Built));
      L1F3 : constant String := pad (JT.int2str (data.Ignored));
      L1F4 : constant String := fmtpc (data.load, False);
      L1F5 : constant String := pad (JT.int2str (data.pkg_hour), 4);

      L2F1 : constant String := pad (JT.int2str (remaining));
      L2F2 : constant String := pad (JT.int2str (data.Failed));
      L2F3 : constant String := pad (JT.int2str (data.Skipped));
      L2F4 : constant String := fmtpc (data.swap, True);
      L2F5 : constant String := pad (JT.int2str (data.impulse), 4);

   begin

      colorado (L1F1, c_standard,  6, 0);
      colorado (L1F2, c_success,  20, 0);
      colorado (L1F3, c_ignored,  35, 0);
      colorado (L1F4, c_standard, 47, 0, True);
      colorado (L1F5, c_standard, 63, 0, True);

      colorado (L2F1, c_standard,  6, 1);
      colorado (L2F2, c_failure,  20, 1);
      colorado (L2F3, c_skipped,  35, 1);
      colorado (L2F4, c_standard, 47, 1, True);
      colorado (L2F5, c_standard, 63, 1, True);
      colorado (data.elapsed, c_elapsed, 69, 1);

      TIC.Refresh (Win => zone_summary);
   end summarize;

   -----------------------
   --  update_builder   --
   -----------------------
   procedure update_builder (BR : builder_rec)
   is
      procedure colorado (S : String; color :  TIC.Color_Pair;
                          col : TIC.Column_Position;
                          row : TIC.Line_Position;
                          dim : Boolean := False);
      procedure print_id;
      row : TIC.Line_Position := inc (TIC.Line_Position (BR.id), 2);

      procedure print_id is
      begin
         TIC.Set_Character_Attributes (Win   => zone_builders,
                                       Attr  => c_slave (BR.id).attribute,
                                       Color => c_slave (BR.id).palette);
         TIC.Move_Cursor (Win => zone_builders, Line => row, Column => 1);
         TIC.Add (Win => zone_builders, Str => BR.slavid);
      end print_id;
      procedure colorado (S : String; color :  TIC.Color_Pair;
                          col : TIC.Column_Position;
                          row : TIC.Line_Position;
                          dim : Boolean := False)
      is
         attribute : TIC.Character_Attribute_Set := bright_bold;
      begin
         if dim then
            attribute := dimmed;
         end if;
         TIC.Set_Character_Attributes (Win   => zone_builders,
                                       Attr  => attribute,
                                       Color => color);
         TIC.Move_Cursor (Win => zone_builders, Line => row, Column => col);
         TIC.Add (Win => zone_builders, Str => S);
      end colorado;
   begin
      print_id;
      colorado (BR.Elapsed, c_standard,  5, row, True);
      colorado (BR.phase,   c_bldphase, 15, row, True);
      colorado (BR.origin,  c_origin,   32, row, False);
      colorado (BR.LLines,  c_standard, 71, row, True);
   end update_builder;

   ------------------------------
   --  refresh_builder_window  --
   ------------------------------
   procedure refresh_builder_window is
   begin
      TIC.Refresh (Win => zone_builders);
   end refresh_builder_window;

   ------------------------
   --  establish_colors  --
   ------------------------
   procedure establish_colors is
   begin
      TIC.Start_Color;
      TIC.Init_Pair (TIC.Color_Pair (1), TIC.White,   TIC.Black);
      TIC.Init_Pair (TIC.Color_Pair (2), TIC.Green,   TIC.Black);
      TIC.Init_Pair (TIC.Color_Pair (3), TIC.Red,     TIC.Black);
      TIC.Init_Pair (TIC.Color_Pair (4), TIC.Yellow,  TIC.Black);
      TIC.Init_Pair (TIC.Color_Pair (5), TIC.Black,   TIC.Black);
      TIC.Init_Pair (TIC.Color_Pair (6), TIC.Cyan,    TIC.Black);
      TIC.Init_Pair (TIC.Color_Pair (7), TIC.Blue,    TIC.Black);
      TIC.Init_Pair (TIC.Color_Pair (8), TIC.Magenta, TIC.Black);
      TIC.Init_Pair (TIC.Color_Pair (9), TIC.Blue,    TIC.White);

      c_standard    := TIC.Color_Pair (1);
      c_success     := TIC.Color_Pair (2);
      c_failure     := TIC.Color_Pair (3);
      c_ignored     := TIC.Color_Pair (4);
      c_skipped     := TIC.Color_Pair (5);
      c_sumlabel    := TIC.Color_Pair (6);
      c_dashes      := TIC.Color_Pair (7);
      c_elapsed     := TIC.Color_Pair (4);
      c_tableheader := TIC.Color_Pair (1);
      c_origin      := TIC.Color_Pair (6);
      c_bldphase    := TIC.Color_Pair (4);

      c_slave  (1).palette   := TIC.Color_Pair (1);  --  white / Black
      c_slave  (1).attribute := bright;

      c_slave  (2).palette   := TIC.Color_Pair (2);  --  light green / Black
      c_slave  (2).attribute := bright;

      c_slave  (3).palette   := TIC.Color_Pair (4);  --  yellow / Black
      c_slave  (3).attribute := bright;

      c_slave  (4).palette   := TIC.Color_Pair (8);  --  light magenta / Black
      c_slave  (4).attribute := bright;

      c_slave  (5).palette   := TIC.Color_Pair (3);  --  light red / Black
      c_slave  (5).attribute := bright;

      c_slave  (6).palette   := TIC.Color_Pair (7);  --  light blue / Black
      c_slave  (6).attribute := bright;

      c_slave  (7).palette   := TIC.Color_Pair (6);  --  light cyan / Black
      c_slave  (7).attribute := bright;

      c_slave  (8).palette   := TIC.Color_Pair (5);  --  dark grey / Black
      c_slave  (8).attribute := bright;

      c_slave  (9).palette   := TIC.Color_Pair (1);  --  light grey / Black
      c_slave  (9).attribute := dimmed;

      c_slave (10).palette   := TIC.Color_Pair (2);  --  light green / Black
      c_slave (10).attribute := dimmed;

      c_slave (11).palette   := TIC.Color_Pair (4);  --  brown / Black
      c_slave (11).attribute := dimmed;

      c_slave (12).palette   := TIC.Color_Pair (8);  --  dark magenta / Black
      c_slave (12).attribute := dimmed;

      c_slave (13).palette   := TIC.Color_Pair (3);  --  dark red / Black
      c_slave (13).attribute := dimmed;

      c_slave (14).palette   := TIC.Color_Pair (7);  --  dark blue / Black
      c_slave (14).attribute := dimmed;

      c_slave (15).palette   := TIC.Color_Pair (6);  --  dark cyan / Black
      c_slave (15).attribute := dimmed;

      c_slave (16).palette   := TIC.Color_Pair (9);  --  white / dark blue
      c_slave (16).attribute := dimmed;

      for bld in builders (17) .. builders (32)  loop
         c_slave (bld) := c_slave (bld - 16);
         c_slave (bld - 16).attribute.Bold_Character := True;
      end loop;
      for bld in builders (33) .. builders (64)  loop
         c_slave (bld) := c_slave (bld - 32);
      end loop;

   end establish_colors;

end Display;

Switch magenta and red order again

Switch magenta and red order again


-----------------------------------------------------------------------
--  gen-artifacts-xmi -- UML-XMI artifact for Code Generator
--  Copyright (C) 2012 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------

with DOM.Core;
with Gen.Model.Packages;
with Gen.Model.XMI;

--  The Gen.Artifacts.XMI package is an artifact for the generation of Ada code
--  from an UML XMI description.
package Gen.Artifacts.XMI is

   --  ------------------------------
   --  UML XMI artifact
   --  ------------------------------
   type Artifact is new Gen.Artifacts.Artifact with private;

   --  After the configuration file is read, processes the node whose root
   --  is passed in Node and initializes the Model with the information.
   overriding
   procedure Initialize (Handler : in out Artifact;
                         Path    : in String;
                         Node    : in DOM.Core.Node;
                         Model   : in out Gen.Model.Packages.Model_Definition'Class;
                         Context : in out Generator'Class);

   --  Prepare the model after all the configuration files have been read and before
   --  actually invoking the generation.
   overriding
   procedure Prepare (Handler : in out Artifact;
                      Model   : in out Gen.Model.Packages.Model_Definition'Class;
                      Context : in out Generator'Class);

   --  Read the UML/XMI model file.
   procedure Read_Model (Handler : in out Artifact;
                         File    : in String;
                         Context : in out Generator'Class);

   --  Read the UML configuration files that define the pre-defined types, stereotypes
   --  and other components used by a model.  These files are XMI files as well.
   --  All the XMI files in the UML config directory are read.
   procedure Read_UML_Configuration (Handler : in out Artifact;
                                     Context : in out Generator'Class);

private

   type Artifact is new Gen.Artifacts.Artifact with record
      Nodes      : aliased Gen.Model.XMI.UML_Model;
      Has_Config : Boolean := False;

      --  Stereotype which triggers the generation of database table.
      Table_Stereotype      : Gen.Model.XMI.Stereotype_Element_Access;
      PK_Stereotype         : Gen.Model.XMI.Stereotype_Element_Access;
      FK_Stereotype         : Gen.Model.XMI.Stereotype_Element_Access;
      Data_Model_Stereotype : Gen.Model.XMI.Stereotype_Element_Access;
      Nullable_Stereotype   : Gen.Model.XMI.Stereotype_Element_Access;
      Not_Null_Stereotype   : Gen.Model.XMI.Stereotype_Element_Access;
      Use_FK_Stereotype     : Gen.Model.XMI.Stereotype_Element_Access;

      --  Tag definitions which control the generation.
      Has_List_Tag          : Gen.Model.XMI.Tag_Definition_Element_Access;
      Table_Name_Tag        : Gen.Model.XMI.Tag_Definition_Element_Access;

      --  Stereotype which triggers the generation of AWA bean types.
      Bean_Stereotype  : Gen.Model.XMI.Stereotype_Element_Access;
   end record;

end Gen.Artifacts.XMI;

-----------------------------------------------------------------------
--  gen-artifacts-xmi -- UML-XMI artifact for Code Generator
--  Copyright (C) 2012 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------

with DOM.Core;
with Gen.Model.Packages;
with Gen.Model.XMI;

--  The Gen.Artifacts.XMI package is an artifact for the generation of Ada code
--  from an UML XMI description.
package Gen.Artifacts.XMI is

   --  ------------------------------
   --  UML XMI artifact
   --  ------------------------------
   type Artifact is new Gen.Artifacts.Artifact with private;

   --  After the configuration file is read, processes the node whose root
   --  is passed in Node and initializes the Model with the information.
   overriding
   procedure Initialize (Handler : in out Artifact;
                         Path    : in String;
                         Node    : in DOM.Core.Node;
                         Model   : in out Gen.Model.Packages.Model_Definition'Class;
                         Context : in out Generator'Class);

   --  Prepare the model after all the configuration files have been read and before
   --  actually invoking the generation.
   overriding
   procedure Prepare (Handler : in out Artifact;
                      Model   : in out Gen.Model.Packages.Model_Definition'Class;
                      Context : in out Generator'Class);

   --  Read the UML/XMI model file.
   procedure Read_Model (Handler : in out Artifact;
                         File    : in String;
                         Context : in out Generator'Class);

   --  Read the UML configuration files that define the pre-defined types, stereotypes
   --  and other components used by a model.  These files are XMI files as well.
   --  All the XMI files in the UML config directory are read.
   procedure Read_UML_Configuration (Handler : in out Artifact;
                                     Context : in out Generator'Class);

private

   type Artifact is new Gen.Artifacts.Artifact with record
      Nodes      : aliased Gen.Model.XMI.UML_Model;
      Has_Config : Boolean := False;

      --  Stereotype which triggers the generation of database table.
      Table_Stereotype      : Gen.Model.XMI.Stereotype_Element_Access;
      PK_Stereotype         : Gen.Model.XMI.Stereotype_Element_Access;
      FK_Stereotype         : Gen.Model.XMI.Stereotype_Element_Access;
      Data_Model_Stereotype : Gen.Model.XMI.Stereotype_Element_Access;
      Nullable_Stereotype   : Gen.Model.XMI.Stereotype_Element_Access;
      Not_Null_Stereotype   : Gen.Model.XMI.Stereotype_Element_Access;
      Use_FK_Stereotype     : Gen.Model.XMI.Stereotype_Element_Access;
      Version_Stereotype    : Gen.Model.XMI.Stereotype_Element_Access;

      --  Tag definitions which control the generation.
      Has_List_Tag          : Gen.Model.XMI.Tag_Definition_Element_Access;
      Table_Name_Tag        : Gen.Model.XMI.Tag_Definition_Element_Access;

      --  Stereotype which triggers the generation of AWA bean types.
      Bean_Stereotype  : Gen.Model.XMI.Stereotype_Element_Access;
   end record;

end Gen.Artifacts.XMI;

Add the <<Version>> stereotype

Add the <<Version>> stereotype


-----------------------------------------------------------------------
--  gen-commands-docs -- Extract and generate documentation for the project
--  Copyright (C) 2012 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------

with GNAT.Command_Line;

with Ada.Text_IO;
package body Gen.Commands.Docs is

   use GNAT.Command_Line;

   --  ------------------------------
   --  Execute the command with the arguments.
   --  ------------------------------
   procedure Execute (Cmd       : in Command;
                      Generator : in out Gen.Generator.Handler) is
      pragma Unreferenced (Cmd);
   begin
      Generator.Read_Project ("dynamo.xml", True);

      --  Setup the target directory where the distribution is created.
      declare
         Target_Dir : constant String := Get_Argument;
      begin
         if Target_Dir'Length = 0 then
            Generator.Error ("Missing target directory");
            return;
         end if;
         Generator.Set_Result_Directory (Target_Dir);
      end;

      --  Read the package description.
      declare
         Package_File : constant String := Get_Argument;
      begin
         if Package_File'Length > 0 then
            Gen.Generator.Read_Package (Generator, Package_File);
         else
            Gen.Generator.Read_Package (Generator, "package.xml");
         end if;
      end;

      --  Run the generation.
      Gen.Generator.Prepare (Generator);
      Gen.Generator.Generate_All (Generator);
      Gen.Generator.Finish (Generator);
   end Execute;

   --  ------------------------------
   --  Write the help associated with the command.
   --  ------------------------------
   procedure Help (Cmd       : in Command;
                   Generator : in out Gen.Generator.Handler) is
      pragma Unreferenced (Cmd, Generator);
      use Ada.Text_IO;
   begin
      Put_Line ("build-doc: Extract and generate the project documentation");
      Put_Line ("Usage: build-doc");
      New_Line;
      Put_Line ("  Extract the documentation from the project source files and generate the");
      Put_Line ("  project documentation.  The following files are scanned:");
      Put_Line ("    - Ada specifications (src/*.ads)");
      Put_Line ("    - XML configuration files (config/*.xml)");
      Put_Line ("    - XML database model files (db/*.xml)");
   end Help;

end Gen.Commands.Docs;

-----------------------------------------------------------------------
--  gen-commands-docs -- Extract and generate documentation for the project
--  Copyright (C) 2012 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------

with GNAT.Command_Line;

with Ada.Text_IO;

with Gen.Artifacts.Docs;
with Gen.Model.Packages;
package body Gen.Commands.Docs is

   use GNAT.Command_Line;

   --  ------------------------------
   --  Execute the command with the arguments.
   --  ------------------------------
   procedure Execute (Cmd       : in Command;
                      Generator : in out Gen.Generator.Handler) is
      pragma Unreferenced (Cmd);

      Doc : Gen.Artifacts.Docs.Artifact;
      M   : Gen.Model.Packages.Model_Definition;
   begin
      Generator.Read_Project ("dynamo.xml", False);

      --  Setup the target directory where the distribution is created.
      declare
         Target_Dir : constant String := Get_Argument;
      begin
         if Target_Dir'Length = 0 then
            Generator.Error ("Missing target directory");
            return;
         end if;
         Generator.Set_Result_Directory (Target_Dir);
      end;
--
--        --  Read the package description.
--        declare
--           Package_File : constant String := Get_Argument;
--        begin
--           if Package_File'Length > 0 then
--              Gen.Generator.Read_Package (Generator, Package_File);
--           else
--              Gen.Generator.Read_Package (Generator, "package.xml");
--           end if;
--        end;

      Doc.Prepare (M, Generator);
--        --  Run the generation.
--        Gen.Generator.Prepare (Generator);
--        Gen.Generator.Generate_All (Generator);
--        Gen.Generator.Finish (Generator);
   end Execute;

   --  ------------------------------
   --  Write the help associated with the command.
   --  ------------------------------
   procedure Help (Cmd       : in Command;
                   Generator : in out Gen.Generator.Handler) is
      pragma Unreferenced (Cmd, Generator);
      use Ada.Text_IO;
   begin
      Put_Line ("build-doc: Extract and generate the project documentation");
      Put_Line ("Usage: build-doc");
      New_Line;
      Put_Line ("  Extract the documentation from the project source files and generate the");
      Put_Line ("  project documentation.  The following files are scanned:");
      Put_Line ("    - Ada specifications (src/*.ads)");
      Put_Line ("    - XML configuration files (config/*.xml)");
      Put_Line ("    - XML database model files (db/*.xml)");
   end Help;

end Gen.Commands.Docs;

Create the documentation artifact and invoke it for the build-doc command


-----------------------------------------------------------------------
--  util-dates -- Date utilities
--  Copyright (C) 2011 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------

package body Util.Dates is

   --  ------------------------------
   --  Split the date into a date record (See Ada.Calendar.Formatting.Split).
   --  ------------------------------
   procedure Split (Into       : out Date_Record;
                    Date       : in Ada.Calendar.Time;
                    Time_Zone  : in Ada.Calendar.Time_Zones.Time_Offset := 0) is
   begin
      Into.Date      := Date;
      Into.Time_Zone := Time_Zone;
      Ada.Calendar.Formatting.Split (Date        => Date,
                                     Year        => Into.Year,
                                     Month       => Into.Month,
                                     Day         => Into.Month_Day,
                                     Hour        => Into.Hour,
                                     Minute      => Into.Minute,
                                     Second      => Into.Second,
                                     Sub_Second  => Into.Sub_Second,
                                     Leap_Second => Into.Leap_Second,
                                     Time_Zone   => Time_Zone);
      Into.Day := Ada.Calendar.Formatting.Day_Of_Week (Date);
   end Split;

end Util.Dates;

-----------------------------------------------------------------------
--  util-dates -- Date utilities
--  Copyright (C) 2011, 2013 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
with Ada.Calendar.Arithmetic;
package body Util.Dates is

   --  ------------------------------
   --  Split the date into a date record (See Ada.Calendar.Formatting.Split).
   --  ------------------------------
   procedure Split (Into       : out Date_Record;
                    Date       : in Ada.Calendar.Time;
                    Time_Zone  : in Ada.Calendar.Time_Zones.Time_Offset := 0) is
   begin
      Into.Date      := Date;
      Into.Time_Zone := Time_Zone;
      Ada.Calendar.Formatting.Split (Date        => Date,
                                     Year        => Into.Year,
                                     Month       => Into.Month,
                                     Day         => Into.Month_Day,
                                     Hour        => Into.Hour,
                                     Minute      => Into.Minute,
                                     Second      => Into.Second,
                                     Sub_Second  => Into.Sub_Second,
                                     Leap_Second => Into.Leap_Second,
                                     Time_Zone   => Time_Zone);
      Into.Day := Ada.Calendar.Formatting.Day_Of_Week (Date);
   end Split;

   --  ------------------------------
   --  Get a time representing the given date at 00:00:00.
   --  ------------------------------
   function Get_Day_Start (Date : in Date_Record) return Ada.Calendar.Time is
   begin
      return Ada.Calendar.Formatting.Time_Of (Year        => Date.Year,
                                              Month       => Date.Month,
                                              Day         => Date.Month_Day,
                                              Hour        => 0,
                                              Minute      => 0,
                                              Second      => 0,
                                              Sub_Second  => 0.0,
                                              Time_Zone   => Date.Time_Zone);
   end Get_Day_Start;

   function Get_Day_Start (Date : in Ada.Calendar.Time) return Ada.Calendar.Time is
      D : Date_Record;
   begin
      Split (D, Date);
      return Get_Day_Start (D);
   end Get_Day_Start;

   --  ------------------------------
   --  Get a time representing the beginning of the week at 00:00:00.
   --  ------------------------------
   function Get_Week_Start (Date : in Date_Record) return Ada.Calendar.Time is
      use Ada.Calendar.Formatting;
      use Ada.Calendar.Arithmetic;

      T : constant Ada.Calendar.Time := Time_Of (Year        => Date.Year,
                                                 Month       => Date.Month,
                                                 Day         => Date.Month_Day,
                                                 Hour        => 0,
                                                 Minute      => 0,
                                                 Second      => 0,
                                                 Sub_Second  => 0.0,
                                                 Time_Zone   => Date.Time_Zone);
      Day : constant Ada.Calendar.Formatting.Day_Name := Ada.Calendar.Formatting.Day_Of_Week (T);
   begin
      if Day = Ada.Calendar.Formatting.Monday then
         return T;
      else
         return T - Day_Count (Day_Name'Pos (Day) - Day_Name'Pos (Monday));
      end if;
   end Get_Week_Start;

   function Get_Week_Start (Date : in Ada.Calendar.Time) return Ada.Calendar.Time is
      D : Date_Record;
   begin
      Split (D, Date);
      return Get_Week_Start (D);
   end Get_Week_Start;

   --  ------------------------------
   --  Get a time representing the beginning of the month at 00:00:00.
   --  ------------------------------
   function Get_Month_Start (Date : in Date_Record) return Ada.Calendar.Time is
   begin
      return Ada.Calendar.Formatting.Time_Of (Year        => Date.Year,
                                              Month       => Date.Month,
                                              Day         => Ada.Calendar.Day_Number'First,
                                              Hour        => 0,
                                              Minute      => 0,
                                              Second      => 0,
                                              Sub_Second  => 0.0,
                                              Time_Zone   => Date.Time_Zone);
   end Get_Month_Start;

   function Get_Month_Start (Date : in Ada.Calendar.Time) return Ada.Calendar.Time is
      D : Date_Record;
   begin
      Split (D, Date);
      return Get_Month_Start (D);
   end Get_Month_Start;

end Util.Dates;

Implement the new functions Get_Day_Start, Get_Week_Start and Get_Month_Start


-----------------------------------------------------------------------
--  wiki-filters-html -- Wiki HTML filters
--  Copyright (C) 2015, 2016 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
private with Ada.Containers.Vectors;

--  === HTML Filters ===
--  The <b>Wiki.Filters.Html</b> package implements a customizable HTML filter that verifies
--  the HTML content embedded in the Wiki text.
--
--  The HTML filter may be declared and configured as follows:
--
--    F : aliased Wiki.Filters.Html.Html_Filter_Type;
--    ...
--    F.Forbidden (Wiki.Filters.Html.SCRIPT_TAG);
--    F.Forbidden (Wiki.Filters.Html.A_TAG);
--
--  The <tt>Set_Document</tt> operation is used to link the HTML filter to a next filter
--  or to the HTML or text renderer:
--
--    F.Set_Document (Renderer'Access);
--
--  The HTML filter is then either inserted as a document for a previous filter or for
--  the wiki parser:
--
--    Wiki.Parsers.Parse (F'Access, Wiki_Text, Syntax);
--
package Wiki.Filters.Html is

   use Wiki.Nodes;

   --  ------------------------------
   --  Filter type
   --  ------------------------------
   type Html_Filter_Type is new Filter_Type with private;

   --  Add a simple node such as N_LINE_BREAK, N_HORIZONTAL_RULE or N_PARAGRAPH to the document.
   overriding
   procedure Add_Node (Filter    : in out Html_Filter_Type;
                       Document  : in out Wiki.Nodes.Document;
                       Kind      : in Wiki.Nodes.Simple_Node_Kind);

   --  Add a text content with the given format to the document.
   overriding
   procedure Add_Text (Filter    : in out Html_Filter_Type;
                       Document  : in out Wiki.Nodes.Document;
                       Text      : in Wiki.Strings.WString;
                       Format    : in Wiki.Nodes.Format_Map);

   --  Add a section header with the given level in the document.
   overriding
   procedure Add_Header (Filter    : in out Html_Filter_Type;
                         Document  : in out Wiki.Nodes.Document;
                         Header    : in Wiki.Strings.WString;
                         Level     : in Natural);

   --  Push a HTML node with the given tag to the document.
   overriding
   procedure Push_Node (Filter     : in out Html_Filter_Type;
                        Document   : in out Wiki.Nodes.Document;
                        Tag        : in Wiki.Nodes.Html_Tag_Type;
                        Attributes : in out Wiki.Attributes.Attribute_List_Type);

   --  Pop a HTML node with the given tag.
   overriding
   procedure Pop_Node (Filter   : in out Html_Filter_Type;
                       Document : in out Wiki.Nodes.Document;
                       Tag      : in Wiki.Nodes.Html_Tag_Type);

   --  Add a link.
   overriding
   procedure Add_Link (Filter     : in out Html_Filter_Type;
                       Document   : in out Wiki.Nodes.Document;
                       Name       : in Wiki.Strings.WString;
                       Attributes : in out Wiki.Attributes.Attribute_List_Type);

   --  Add an image.
   overriding
   procedure Add_Image (Filter     : in out Html_Filter_Type;
                        Document   : in out Wiki.Nodes.Document;
                        Name       : in Wiki.Strings.WString;
                        Attributes : in out Wiki.Attributes.Attribute_List_Type);

   --  Finish the document after complete wiki text has been parsed.
   overriding
   procedure Finish (Filter   : in out Html_Filter_Type;
                     Document : in out Wiki.Nodes.Document);

   --  Mark the HTML tag as being forbidden.
   procedure Forbidden (Filter : in out Html_Filter_Type;
                        Tag    : in Html_Tag_Type);

   --  Mark the HTML tag as being allowed.
   procedure Allowed (Filter : in out Html_Filter_Type;
                      Tag    : in Html_Tag_Type);

   --  Mark the HTML tag as being hidden.  The tag and its inner content including the text
   --  will be removed and not passed to the final document.
   procedure Hide (Filter : in out Html_Filter_Type;
                   Tag    : in Html_Tag_Type);

   --  Mark the HTML tag as being visible.
   procedure Visible (Filter : in out Html_Filter_Type;
                      Tag    : in Html_Tag_Type);

   --  Flush the HTML element that have not yet been closed.
   procedure Flush_Stack (Filter   : in out Html_Filter_Type;
                          Document : in out Wiki.Nodes.Document);

private

   use Wiki.Nodes;

   type Tag_Boolean_Array is array (Html_Tag_Type) of Boolean;

   package Tag_Vectors is
     new Ada.Containers.Vectors (Index_Type   => Positive,
                                 Element_Type => Html_Tag_Type);

   subtype Tag_Vector is Tag_Vectors.Vector;
   subtype Tag_Cursor is Tag_Vectors.Cursor;

   type Html_Filter_Type is new Filter_Type with record
      Allowed    : Tag_Boolean_Array := (UNKNOWN_TAG => False,
                                         SCRIPT_TAG  => False,
                                         HTML_TAG    => False,
                                         HEAD_TAG    => False,
                                         BODY_TAG    => False,
                                         META_TAG    => False,
                                         TITLE_TAG   => False,
                                         others      => True);

      Hidden     : Tag_Boolean_Array := (UNKNOWN_TAG => False,
                                         SCRIPT_TAG  => True,
                                         STYLE_TAG   => True,
                                         others      => False);
      Stack      : Tag_Vector;
      Hide_Level : Natural := 0;
   end record;

end Wiki.Filters.Html;

-----------------------------------------------------------------------
--  wiki-filters-html -- Wiki HTML filters
--  Copyright (C) 2015, 2016 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
private with Ada.Containers.Vectors;

--  === HTML Filters ===
--  The <b>Wiki.Filters.Html</b> package implements a customizable HTML filter that verifies
--  the HTML content embedded in the Wiki text.
--
--  The HTML filter may be declared and configured as follows:
--
--    F : aliased Wiki.Filters.Html.Html_Filter_Type;
--    ...
--    F.Forbidden (Wiki.Filters.Html.SCRIPT_TAG);
--    F.Forbidden (Wiki.Filters.Html.A_TAG);
--
--  The <tt>Set_Document</tt> operation is used to link the HTML filter to a next filter
--  or to the HTML or text renderer:
--
--    F.Set_Document (Renderer'Access);
--
--  The HTML filter is then either inserted as a document for a previous filter or for
--  the wiki parser:
--
--    Wiki.Parsers.Parse (F'Access, Wiki_Text, Syntax);
--
package Wiki.Filters.Html is

   use Wiki.Nodes;

   --  ------------------------------
   --  Filter type
   --  ------------------------------
   type Html_Filter_Type is new Filter_Type with private;

   --  Add a simple node such as N_LINE_BREAK, N_HORIZONTAL_RULE or N_PARAGRAPH to the document.
   overriding
   procedure Add_Node (Filter    : in out Html_Filter_Type;
                       Document  : in out Wiki.Nodes.Document;
                       Kind      : in Wiki.Nodes.Simple_Node_Kind);

   --  Add a text content with the given format to the document.
   overriding
   procedure Add_Text (Filter    : in out Html_Filter_Type;
                       Document  : in out Wiki.Nodes.Document;
                       Text      : in Wiki.Strings.WString;
                       Format    : in Wiki.Format_Map);

   --  Add a section header with the given level in the document.
   overriding
   procedure Add_Header (Filter    : in out Html_Filter_Type;
                         Document  : in out Wiki.Nodes.Document;
                         Header    : in Wiki.Strings.WString;
                         Level     : in Natural);

   --  Push a HTML node with the given tag to the document.
   overriding
   procedure Push_Node (Filter     : in out Html_Filter_Type;
                        Document   : in out Wiki.Nodes.Document;
                        Tag        : in Wiki.Nodes.Html_Tag_Type;
                        Attributes : in out Wiki.Attributes.Attribute_List_Type);

   --  Pop a HTML node with the given tag.
   overriding
   procedure Pop_Node (Filter   : in out Html_Filter_Type;
                       Document : in out Wiki.Nodes.Document;
                       Tag      : in Wiki.Nodes.Html_Tag_Type);

   --  Add a link.
   overriding
   procedure Add_Link (Filter     : in out Html_Filter_Type;
                       Document   : in out Wiki.Nodes.Document;
                       Name       : in Wiki.Strings.WString;
                       Attributes : in out Wiki.Attributes.Attribute_List_Type);

   --  Add an image.
   overriding
   procedure Add_Image (Filter     : in out Html_Filter_Type;
                        Document   : in out Wiki.Nodes.Document;
                        Name       : in Wiki.Strings.WString;
                        Attributes : in out Wiki.Attributes.Attribute_List_Type);

   --  Finish the document after complete wiki text has been parsed.
   overriding
   procedure Finish (Filter   : in out Html_Filter_Type;
                     Document : in out Wiki.Nodes.Document);

   --  Mark the HTML tag as being forbidden.
   procedure Forbidden (Filter : in out Html_Filter_Type;
                        Tag    : in Html_Tag_Type);

   --  Mark the HTML tag as being allowed.
   procedure Allowed (Filter : in out Html_Filter_Type;
                      Tag    : in Html_Tag_Type);

   --  Mark the HTML tag as being hidden.  The tag and its inner content including the text
   --  will be removed and not passed to the final document.
   procedure Hide (Filter : in out Html_Filter_Type;
                   Tag    : in Html_Tag_Type);

   --  Mark the HTML tag as being visible.
   procedure Visible (Filter : in out Html_Filter_Type;
                      Tag    : in Html_Tag_Type);

   --  Flush the HTML element that have not yet been closed.
   procedure Flush_Stack (Filter   : in out Html_Filter_Type;
                          Document : in out Wiki.Nodes.Document);

private

   use Wiki.Nodes;

   type Tag_Boolean_Array is array (Html_Tag_Type) of Boolean;

   package Tag_Vectors is
     new Ada.Containers.Vectors (Index_Type   => Positive,
                                 Element_Type => Html_Tag_Type);

   subtype Tag_Vector is Tag_Vectors.Vector;
   subtype Tag_Cursor is Tag_Vectors.Cursor;

   type Html_Filter_Type is new Filter_Type with record
      Allowed    : Tag_Boolean_Array := (UNKNOWN_TAG => False,
                                         SCRIPT_TAG  => False,
                                         HTML_TAG    => False,
                                         HEAD_TAG    => False,
                                         BODY_TAG    => False,
                                         META_TAG    => False,
                                         TITLE_TAG   => False,
                                         others      => True);

      Hidden     : Tag_Boolean_Array := (UNKNOWN_TAG => False,
                                         SCRIPT_TAG  => True,
                                         STYLE_TAG   => True,
                                         others      => False);
      Stack      : Tag_Vector;
      Hide_Level : Natural := 0;
   end record;

end Wiki.Filters.Html;

Use Wiki.Format_Map type

Use Wiki.Format_Map type


-----------------------------------------------------------------------
--  awa-wikis-beans -- Beans for module wikis
--  Copyright (C) 2015 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------

with Ada.Strings.Unbounded;

with Util.Beans.Basic;
with Util.Beans.Objects;

with ADO;

with AWA.Wikis.Modules;
with AWA.Wikis.Models;
with AWA.Tags.Beans;

package AWA.Wikis.Beans is

   type Wiki_View_Bean is new AWA.Wikis.Models.Wiki_View_Info with record
      --  The wiki module instance.
      Module        : Modules.Wiki_Module_Access := null;

      --  The wiki space identifier.
      Wiki_Space_Id : ADO.Identifier;

      --  List of tags associated with the wiki page.
      Tags          : aliased AWA.Tags.Beans.Tag_List_Bean;
      Tags_Bean     : Util.Beans.Basic.Readonly_Bean_Access;
   end record;
   type Wiki_View_Bean_Access is access all Wiki_View_Bean'Class;

   --  Get the value identified by the name.
   overriding
   function Get_Value (From : in Wiki_View_Bean;
                       Name : in String) return Util.Beans.Objects.Object;

   --  Set the value identified by the name.
   overriding
   procedure Set_Value (From  : in out Wiki_View_Bean;
                        Name  : in String;
                        Value : in Util.Beans.Objects.Object);

   --  Load the information about the wiki page to display it.
   overriding
   procedure Load (Bean    : in out Wiki_View_Bean;
                   Outcome : in out Ada.Strings.Unbounded.Unbounded_String);

   --  Create the Wiki_View_Bean bean instance.
   function Create_Wiki_View_Bean (Module : in AWA.Wikis.Modules.Wiki_Module_Access)
                                  return Util.Beans.Basic.Readonly_Bean_Access;

   type Wiki_Space_Bean is new AWA.Wikis.Models.Wiki_Space_Bean with record
      Module    : Modules.Wiki_Module_Access := null;

      --  List of tags associated with the question.
      Tags      : aliased AWA.Tags.Beans.Tag_List_Bean;
      Tags_Bean : Util.Beans.Basic.Readonly_Bean_Access;
   end record;
   type Wiki_Space_Bean_Access is access all Wiki_Space_Bean'Class;

   --  Get the value identified by the name.
   overriding
   function Get_Value (From : in Wiki_Space_Bean;
                       Name : in String) return Util.Beans.Objects.Object;

   --  Set the value identified by the name.
   overriding
   procedure Set_Value (From  : in out Wiki_Space_Bean;
                        Name  : in String;
                        Value : in Util.Beans.Objects.Object);

   --  Create or save the wiki space.
   overriding
   procedure Save (Bean    : in out Wiki_Space_Bean;
                   Outcome : in out Ada.Strings.Unbounded.Unbounded_String);

   --  Delete the wiki space.
   procedure Delete (Bean    : in out Wiki_Space_Bean;
                     Outcome : in out Ada.Strings.Unbounded.Unbounded_String);

   --  Create the Wiki_Space_Bean bean instance.
   function Create_Wiki_Space_Bean (Module : in AWA.Wikis.Modules.Wiki_Module_Access)
                                  return Util.Beans.Basic.Readonly_Bean_Access;

   --  ------------------------------
   --  Wiki Page Bean
   --  ------------------------------
   --  The <tt>Wiki_Page_Bean</tt> is used to edit a wiki page.  The model type inherit from
   --  the <tt>Wiki_Page</tt> and the wiki page text is hold in the <tt>Content</tt> member.
   --  When a new content is updated, the <tt>Set_Value</tt> procedure sets it in the
   --  <tt>New_Content</tt> member.  It is compared to the current wiki text to decide whether
   --  we have to create a new version or not.
   type Wiki_Page_Bean is new AWA.Wikis.Models.Wiki_Page_Bean with record
      Module     : Modules.Wiki_Module_Access := null;

      --  The page content.
      Content     : Models.Wiki_Content_Ref;
      Has_Content : Boolean := False;
      New_Content : Ada.Strings.Unbounded.Unbounded_String;
      New_Comment : Ada.Strings.Unbounded.Unbounded_String;

      Wiki_Space  : Wiki_Space_Bean;

      --  List of tags associated with the wiki page.
      Tags        : aliased AWA.Tags.Beans.Tag_List_Bean;
      Tags_Bean   : Util.Beans.Basic.Readonly_Bean_Access;
   end record;
   type Wiki_Page_Bean_Access is access all Wiki_Page_Bean'Class;

   --  Returns True if the wiki page has a new text content and requires
   --  a new version to be created.
   function Has_New_Content (Bean : in Wiki_Page_Bean) return Boolean;

   --  Get the value identified by the name.
   overriding
   function Get_Value (From : in Wiki_Page_Bean;
                       Name : in String) return Util.Beans.Objects.Object;

   --  Set the value identified by the name.
   overriding
   procedure Set_Value (From  : in out Wiki_Page_Bean;
                        Name  : in String;
                        Value : in Util.Beans.Objects.Object);

   --  Create or save the wiki page.
   overriding
   procedure Save (Bean    : in out Wiki_Page_Bean;
                   Outcome : in out Ada.Strings.Unbounded.Unbounded_String);

   --  Load the wiki page.
   overriding
   procedure Load (Bean    : in out Wiki_Page_Bean;
                   Outcome : in out Ada.Strings.Unbounded.Unbounded_String);

   --  Delete the wiki page.
   overriding
   procedure Delete (Bean    : in out Wiki_Page_Bean;
                     Outcome : in out Ada.Strings.Unbounded.Unbounded_String);

   --  Create the Wiki_Page_Bean bean instance.
   function Create_Wiki_Page_Bean (Module : in AWA.Wikis.Modules.Wiki_Module_Access)
                                    return Util.Beans.Basic.Readonly_Bean_Access;
   --  ------------------------------
   --  Wiki List Bean
   --  ------------------------------
   --  The Wiki_List_Bean gives a list of visible wikis to be displayed to users.
   --  The list can be filtered by a given tag.  The list pagination is supported.
   type Wiki_List_Bean is new AWA.Wikis.Models.Wiki_Page_List_Bean with record
      Module     : Modules.Wiki_Module_Access := null;
      Pages      : aliased AWA.Wikis.Models.Wiki_Page_Info_List_Bean;
      Tags       : AWA.Tags.Beans.Entity_Tag_Map;
      Pages_Bean : AWA.Wikis.Models.Wiki_Page_Info_List_Bean_Access;
   end record;
   type Wiki_List_Bean_Access is access all Wiki_List_Bean'Class;

   --  Get the value identified by the name.
   overriding
   function Get_Value (From : in Wiki_List_Bean;
                       Name : in String) return Util.Beans.Objects.Object;

   --  Set the value identified by the name.
   overriding
   procedure Set_Value (From  : in out Wiki_List_Bean;
                        Name  : in String;
                        Value : in Util.Beans.Objects.Object);

   overriding
   procedure Load (From    : in out Wiki_List_Bean;
                   Outcome : in out Ada.Strings.Unbounded.Unbounded_String);

   --  Load the list of pages.  If a tag was set, filter the list of pages with the tag.
   procedure Load_List (Into : in out Wiki_List_Bean);

   --  Create the Post_List_Bean bean instance.
   function Create_Wiki_List_Bean (Module : in AWA.Wikis.Modules.Wiki_Module_Access)
                                   return Util.Beans.Basic.Readonly_Bean_Access;

   type Init_Flag is (INIT_WIKI_LIST);
   type Init_Map is array (Init_Flag) of Boolean;

   --  ------------------------------
   --  Admin List Bean
   --  ------------------------------
   --  The Wiki_Admin_Bean is used for the administration of a wiki.  It gives the
   --  list of wikis and pages that are created, published or not.
   type Wiki_Admin_Bean is new Util.Beans.Basic.Bean with record
      Module : AWA.Wikis.Modules.Wiki_Module_Access := null;

      --  The wiki space identifier.
      Wiki_Id          : ADO.Identifier := ADO.NO_IDENTIFIER;

      --  List of blogs.
      Wiki_List        : aliased AWA.Wikis.Models.Wiki_Info_List_Bean;
      Wiki_List_Bean   : AWA.Wikis.Models.Wiki_Info_List_Bean_Access;

      --  Initialization flags.
      Init_Flags       : aliased Init_Map := (others => False);
      Flags            : access Init_Map;
   end record;
   type Wiki_Admin_Bean_Access is access all Wiki_Admin_Bean;

   --  Get the wiki space identifier.
   function Get_Wiki_Id (List : in Wiki_Admin_Bean) return ADO.Identifier;

   overriding
   function Get_Value (List : in Wiki_Admin_Bean;
                       Name : in String) return Util.Beans.Objects.Object;

   --  Set the value identified by the name.
   overriding
   procedure Set_Value (From  : in out Wiki_Admin_Bean;
                        Name  : in String;
                        Value : in Util.Beans.Objects.Object);

   --  Load the list of wikis.
   procedure Load_Wikis (List : in Wiki_Admin_Bean);

   --  Create the Wiki_Admin_Bean bean instance.
   function Create_Wiki_Admin_Bean (Module : in AWA.Wikis.Modules.Wiki_Module_Access)
                                    return Util.Beans.Basic.Readonly_Bean_Access;

end AWA.Wikis.Beans;

-----------------------------------------------------------------------
--  awa-wikis-beans -- Beans for module wikis
--  Copyright (C) 2015 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------

with Ada.Strings.Unbounded;

with Util.Beans.Basic;
with Util.Beans.Objects;

with ADO;

with AWA.Wikis.Modules;
with AWA.Wikis.Models;
with AWA.Tags.Beans;

package AWA.Wikis.Beans is

   type Wiki_View_Bean is new AWA.Wikis.Models.Wiki_View_Info with record
      --  The wiki module instance.
      Module        : Modules.Wiki_Module_Access := null;

      --  The wiki space identifier.
      Wiki_Space_Id : ADO.Identifier;

      --  List of tags associated with the wiki page.
      Tags          : aliased AWA.Tags.Beans.Tag_List_Bean;
      Tags_Bean     : Util.Beans.Basic.Readonly_Bean_Access;
   end record;
   type Wiki_View_Bean_Access is access all Wiki_View_Bean'Class;

   --  Get the value identified by the name.
   overriding
   function Get_Value (From : in Wiki_View_Bean;
                       Name : in String) return Util.Beans.Objects.Object;

   --  Set the value identified by the name.
   overriding
   procedure Set_Value (From  : in out Wiki_View_Bean;
                        Name  : in String;
                        Value : in Util.Beans.Objects.Object);

   --  Load the information about the wiki page to display it.
   overriding
   procedure Load (Bean    : in out Wiki_View_Bean;
                   Outcome : in out Ada.Strings.Unbounded.Unbounded_String);

   --  Create the Wiki_View_Bean bean instance.
   function Create_Wiki_View_Bean (Module : in AWA.Wikis.Modules.Wiki_Module_Access)
                                  return Util.Beans.Basic.Readonly_Bean_Access;

   type Wiki_Space_Bean is new AWA.Wikis.Models.Wiki_Space_Bean with record
      Module    : Modules.Wiki_Module_Access := null;

      --  List of tags associated with the question.
      Tags      : aliased AWA.Tags.Beans.Tag_List_Bean;
      Tags_Bean : Util.Beans.Basic.Readonly_Bean_Access;
   end record;
   type Wiki_Space_Bean_Access is access all Wiki_Space_Bean'Class;

   --  Get the value identified by the name.
   overriding
   function Get_Value (From : in Wiki_Space_Bean;
                       Name : in String) return Util.Beans.Objects.Object;

   --  Set the value identified by the name.
   overriding
   procedure Set_Value (From  : in out Wiki_Space_Bean;
                        Name  : in String;
                        Value : in Util.Beans.Objects.Object);

   --  Create or save the wiki space.
   overriding
   procedure Save (Bean    : in out Wiki_Space_Bean;
                   Outcome : in out Ada.Strings.Unbounded.Unbounded_String);

   --  Delete the wiki space.
   procedure Delete (Bean    : in out Wiki_Space_Bean;
                     Outcome : in out Ada.Strings.Unbounded.Unbounded_String);

   --  Create the Wiki_Space_Bean bean instance.
   function Create_Wiki_Space_Bean (Module : in AWA.Wikis.Modules.Wiki_Module_Access)
                                  return Util.Beans.Basic.Readonly_Bean_Access;

   --  ------------------------------
   --  Wiki Page Bean
   --  ------------------------------
   --  The <tt>Wiki_Page_Bean</tt> is used to edit a wiki page.  The model type inherit from
   --  the <tt>Wiki_Page</tt> and the wiki page text is hold in the <tt>Content</tt> member.
   --  When a new content is updated, the <tt>Set_Value</tt> procedure sets it in the
   --  <tt>New_Content</tt> member.  It is compared to the current wiki text to decide whether
   --  we have to create a new version or not.
   type Wiki_Page_Bean is new AWA.Wikis.Models.Wiki_Page_Bean with record
      Module     : Modules.Wiki_Module_Access := null;

      --  The page content.
      Content     : Models.Wiki_Content_Ref;
      Has_Content : Boolean := False;
      New_Content : Ada.Strings.Unbounded.Unbounded_String;
      New_Comment : Ada.Strings.Unbounded.Unbounded_String;

      Wiki_Space  : Wiki_Space_Bean;

      --  List of tags associated with the wiki page.
      Tags        : aliased AWA.Tags.Beans.Tag_List_Bean;
      Tags_Bean   : Util.Beans.Basic.Readonly_Bean_Access;
   end record;
   type Wiki_Page_Bean_Access is access all Wiki_Page_Bean'Class;

   --  Returns True if the wiki page has a new text content and requires
   --  a new version to be created.
   function Has_New_Content (Bean : in Wiki_Page_Bean) return Boolean;

   --  Get the value identified by the name.
   overriding
   function Get_Value (From : in Wiki_Page_Bean;
                       Name : in String) return Util.Beans.Objects.Object;

   --  Set the value identified by the name.
   overriding
   procedure Set_Value (From  : in out Wiki_Page_Bean;
                        Name  : in String;
                        Value : in Util.Beans.Objects.Object);

   --  Create or save the wiki page.
   overriding
   procedure Save (Bean    : in out Wiki_Page_Bean;
                   Outcome : in out Ada.Strings.Unbounded.Unbounded_String);

   --  Load the wiki page.
   overriding
   procedure Load (Bean    : in out Wiki_Page_Bean;
                   Outcome : in out Ada.Strings.Unbounded.Unbounded_String);

   --  Delete the wiki page.
   overriding
   procedure Delete (Bean    : in out Wiki_Page_Bean;
                     Outcome : in out Ada.Strings.Unbounded.Unbounded_String);

   --  Create the Wiki_Page_Bean bean instance.
   function Create_Wiki_Page_Bean (Module : in AWA.Wikis.Modules.Wiki_Module_Access)
                                    return Util.Beans.Basic.Readonly_Bean_Access;

   --  ------------------------------
   --  Wiki List Bean
   --  ------------------------------
   --  The Wiki_List_Bean gives a list of visible wikis to be displayed to users.
   --  The list can be filtered by a given tag.  The list pagination is supported.
   type Wiki_List_Bean is new AWA.Wikis.Models.Wiki_Page_List_Bean with record
      Module     : Modules.Wiki_Module_Access := null;
      Pages      : aliased AWA.Wikis.Models.Wiki_Page_Info_List_Bean;
      Tags       : AWA.Tags.Beans.Entity_Tag_Map;
      Pages_Bean : AWA.Wikis.Models.Wiki_Page_Info_List_Bean_Access;
   end record;
   type Wiki_List_Bean_Access is access all Wiki_List_Bean'Class;

   --  Get the value identified by the name.
   overriding
   function Get_Value (From : in Wiki_List_Bean;
                       Name : in String) return Util.Beans.Objects.Object;

   --  Set the value identified by the name.
   overriding
   procedure Set_Value (From  : in out Wiki_List_Bean;
                        Name  : in String;
                        Value : in Util.Beans.Objects.Object);

   overriding
   procedure Load (From    : in out Wiki_List_Bean;
                   Outcome : in out Ada.Strings.Unbounded.Unbounded_String);

   --  Load the list of pages.  If a tag was set, filter the list of pages with the tag.
   procedure Load_List (Into : in out Wiki_List_Bean);

   --  Create the Post_List_Bean bean instance.
   function Create_Wiki_List_Bean (Module : in AWA.Wikis.Modules.Wiki_Module_Access)
                                   return Util.Beans.Basic.Readonly_Bean_Access;

   --  ------------------------------
   --  Wiki Version List Bean
   --  ------------------------------
   type Wiki_Version_List_Bean is new AWA.Wikis.Models.Wiki_Version_List_Bean with record
      Module        : Modules.Wiki_Module_Access := null;
      Versions      : aliased AWA.Wikis.Models.Wiki_Version_Info_List_Bean;
      Versions_Bean : AWA.Wikis.Models.Wiki_Version_Info_List_Bean_Access;
   end record;
   type Wiki_Version_List_Bean_Access is access all Wiki_Version_List_Bean'Class;

   --  Get the value identified by the name.
   overriding
   function Get_Value (From : in Wiki_Version_List_Bean;
                       Name : in String) return Util.Beans.Objects.Object;

   --  Set the value identified by the name.
   overriding
   procedure Set_Value (From  : in out Wiki_Version_List_Bean;
                        Name  : in String;
                        Value : in Util.Beans.Objects.Object);

   overriding
   procedure Load (From    : in out Wiki_Version_List_Bean;
                   Outcome : in out Ada.Strings.Unbounded.Unbounded_String);

   --  Create the Post_List_Bean bean instance.
   function Create_Wiki_Version_List_Bean (Module : in AWA.Wikis.Modules.Wiki_Module_Access)
                                           return Util.Beans.Basic.Readonly_Bean_Access;

   type Init_Flag is (INIT_WIKI_LIST);
   type Init_Map is array (Init_Flag) of Boolean;

   --  ------------------------------
   --  Admin List Bean
   --  ------------------------------
   --  The Wiki_Admin_Bean is used for the administration of a wiki.  It gives the
   --  list of wikis and pages that are created, published or not.
   type Wiki_Admin_Bean is new Util.Beans.Basic.Bean with record
      Module : AWA.Wikis.Modules.Wiki_Module_Access := null;

      --  The wiki space identifier.
      Wiki_Id          : ADO.Identifier := ADO.NO_IDENTIFIER;

      --  List of blogs.
      Wiki_List        : aliased AWA.Wikis.Models.Wiki_Info_List_Bean;
      Wiki_List_Bean   : AWA.Wikis.Models.Wiki_Info_List_Bean_Access;

      --  Initialization flags.
      Init_Flags       : aliased Init_Map := (others => False);
      Flags            : access Init_Map;
   end record;
   type Wiki_Admin_Bean_Access is access all Wiki_Admin_Bean;

   --  Get the wiki space identifier.
   function Get_Wiki_Id (List : in Wiki_Admin_Bean) return ADO.Identifier;

   overriding
   function Get_Value (List : in Wiki_Admin_Bean;
                       Name : in String) return Util.Beans.Objects.Object;

   --  Set the value identified by the name.
   overriding
   procedure Set_Value (From  : in out Wiki_Admin_Bean;
                        Name  : in String;
                        Value : in Util.Beans.Objects.Object);

   --  Load the list of wikis.
   procedure Load_Wikis (List : in Wiki_Admin_Bean);

   --  Create the Wiki_Admin_Bean bean instance.
   function Create_Wiki_Admin_Bean (Module : in AWA.Wikis.Modules.Wiki_Module_Access)
                                    return Util.Beans.Basic.Readonly_Bean_Access;

end AWA.Wikis.Beans;

Declare the Wiki_Version_List_Bean type with the Get_Value, Set_Value and Load operations