-----------------------------------------------------------------------
--  awa-tags-beans -- Beans for the tags module
--  Copyright (C) 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.Strings.Unbounded;
with Ada.Containers.Hashed_Maps;
with Ada.Containers.Ordered_Sets;
with Ada.Finalization;

with Util.Beans.Basic;
with Util.Beans.Objects.Lists;
with Util.Beans.Lists.Strings;
with Util.Strings.Vectors;

with ADO;
with ADO.Utils;
with ADO.Schemas;
with ADO.Sessions;

with AWA.Tags.Models;
with AWA.Tags.Modules;

--  == Tag Beans ==
--  Several bean types are provided to represent and manage a list of tags.
--
--  === Tag_List_Bean ===
--  The <tt>Tag_List_Bean</tt> holds a list of tags and provides operations used by the
--  <tt>awa:tagList</tt> component to add or remove tags within a <tt>h:form</tt> component.
--  A bean can be declared and configured as follows in the XML application configuration file:
--
--    <managed-bean>
--      <managed-bean-name>questionTags</managed-bean-name>
--      <managed-bean-class>AWA.Tags.Beans.Tag_List_Bean</managed-bean-class>
--      <managed-bean-scope>request</managed-bean-scope>
--      <managed-property>
--        <property-name>entity_type</property-name>
--        <property-class>String</property-class>
--        <value>Awa_Question</value>
--      </managed-property>
--      <managed-property>
--        <property-name>permission</property-name>
--        <property-class>String</property-class>
--        <value>question-edit</value>
--      </managed-property>
--    </managed-bean>
--
--  The <tt>entity_type</tt> property defines the name of the database table to which the tags
--  are assigned.  The <tt>permission</tt> property defines the permission name that must be used
--  to verify that the user has the permission do add or remove the tag.  Such permission is
--  verified only when the <tt>awa:tagList</tt> component is used within a form.
--
--  === Tag_Search_Bean ===
--  The <tt>Tag_Search_Bean</tt> is dedicated to searching for tags that start with a given
--  pattern.  The auto complete feature of the <tt>awa:tagList</tt> component can use this
--  bean type to look in the database for tags matching a start pattern.  The declaration of the
--  bean should define the database table to search for tags associated with a given database
--  table.  This is done in the XML configuration with the <tt>entity_type</tt> property.
--
--    <managed-bean>
--      <managed-bean-name>questionTagSearch</managed-bean-name>
--      <managed-bean-class>AWA.Tags.Beans.Tag_Search_Bean</managed-bean-class>
--      <managed-bean-scope>request</managed-bean-scope>
--      <managed-property>
--        <property-name>entity_type</property-name>
--        <property-class>String</property-class>
--        <value>awa_question</value>
--      </managed-property>
--    </managed-bean>
--
--  === Tag_Info_List_Bean ===
--  The <tt>Tag_Info_List_Bean</tt> holds a collection of tags with their weight.  It is used
--  by the <tt>awa:tagCloud</tt> component.
--
--    <managed-bean>
--      <managed-bean-name>questionTagList</managed-bean-name>
--      <managed-bean-class>AWA.Tags.Beans.Tag_Info_List_Bean</managed-bean-class>
--      <managed-bean-scope>request</managed-bean-scope>
--      <managed-property>
--        <property-name>entity_type</property-name>
--        <property-class>String</property-class>
--        <value>awa_question</value>
--      </managed-property>
--    </managed-bean>
--
package AWA.Tags.Beans is

   --  Compare two tags on their count and name.
   function "<" (Left, Right : in AWA.Tags.Models.Tag_Info) return Boolean;

   package Tag_Ordered_Sets is
     new Ada.Containers.Ordered_Sets (Element_Type => AWA.Tags.Models.Tag_Info,
                                      "="          => AWA.Tags.Models."=");

   type Tag_List_Bean is
     new Util.Beans.Objects.Lists.List_Bean and Util.Beans.Basic.Bean with private;

   type Tag_List_Bean_Access is access all Tag_List_Bean'Class;

   --  Set the value identified by the name.
   --  If the name cannot be found, the method should raise the No_Value
   --  exception.
   overriding
   procedure Set_Value (From  : in out Tag_List_Bean;
                        Name  : in String;
                        Value : in Util.Beans.Objects.Object);

   --  Set the entity type (database table) onto which the tags are associated.
   procedure Set_Entity_Type (Into  : in out Tag_List_Bean;
                              Table : in ADO.Schemas.Class_Mapping_Access);

   --  Set the permission to check before removing or adding a tag on the entity.
   procedure Set_Permission (Into       : in out Tag_List_Bean;
                             Permission : in String);

   --  Load the tags associated with the given database identifier.
   procedure Load_Tags (Into          : in out Tag_List_Bean;
                        Session       : in ADO.Sessions.Session;
                        For_Entity_Id : in ADO.Identifier);

   --  Set the list of tags to add.
   procedure Set_Added (Into  : in out Tag_List_Bean;
                        Tags  : in Util.Strings.Vectors.Vector);

   --  Set the list of tags to remove.
   procedure Set_Deleted (Into : in out Tag_List_Bean;
                          Tags : in Util.Strings.Vectors.Vector);

   --  Update the tags associated with the tag entity represented by <tt>For_Entity_Id</tt>.
   --  The list of tags defined by <tt>Set_Deleted</tt> are removed first and the list of
   --  tags defined by <tt>Set_Added</tt> are associated with the database entity.
   procedure Update_Tags (From          : in Tag_List_Bean;
                          For_Entity_Id : in ADO.Identifier);

   --  Create the tag list bean instance.
   function Create_Tag_List_Bean (Module : in AWA.Tags.Modules.Tag_Module_Access)
                                  return Util.Beans.Basic.Readonly_Bean_Access;

   type Tag_Search_Bean is
     new Util.Beans.Objects.Lists.List_Bean and Util.Beans.Basic.Bean with private;
   type Tag_Search_Bean_Access is access all Tag_Search_Bean'Class;

   --  Set the value identified by the name.
   --  If the name cannot be found, the method should raise the No_Value
   --  exception.
   overriding
   procedure Set_Value (From  : in out Tag_Search_Bean;
                        Name  : in String;
                        Value : in Util.Beans.Objects.Object);

   --  Search the tags that match the search string.
   procedure Search_Tags (Into    : in out Tag_Search_Bean;
                          Session : in ADO.Sessions.Session;
                          Search  : in String);

   --  Set the entity type (database table) onto which the tags are associated.
   procedure Set_Entity_Type (Into  : in out Tag_Search_Bean;
                              Table : in ADO.Schemas.Class_Mapping_Access);

   --  Create the tag search bean instance.
   function Create_Tag_Search_Bean (Module : in AWA.Tags.Modules.Tag_Module_Access)
                                    return Util.Beans.Basic.Readonly_Bean_Access;

   type Tag_Info_List_Bean is
     new AWA.Tags.Models.Tag_Info_List_Bean and Util.Beans.Basic.Bean with private;
   type Tag_Info_List_Bean_Access is access all Tag_Info_List_Bean'Class;

   --  Set the value identified by the name.
   --  If the name cannot be found, the method should raise the No_Value
   --  exception.
   overriding
   procedure Set_Value (From  : in out Tag_Info_List_Bean;
                        Name  : in String;
                        Value : in Util.Beans.Objects.Object);

   --  Load the list of tags.
   procedure Load_Tags (Into    : in out Tag_Info_List_Bean;
                        Session : in out ADO.Sessions.Session);

   --  Create the tag info list bean instance.
   function Create_Tag_Info_List_Bean (Module : in AWA.Tags.Modules.Tag_Module_Access)
                                       return Util.Beans.Basic.Readonly_Bean_Access;

   --  The <tt>Entity_Tag_Map</tt> contains a list of tags associated with some entities.
   --  It allows to retrieve from the database all the tags associated with several entities
   --  and get the list of tags for a given entity.
   type Entity_Tag_Map is new Ada.Finalization.Limited_Controlled with private;

   --  Get the list of tags associated with the given entity.
   --  Returns null if the entity does not have any tag.
   function Get_Tags (From       : in Entity_Tag_Map;
                      For_Entity : in ADO.Identifier)
                      return Util.Beans.Lists.Strings.List_Bean_Access;

   --  Get the list of tags associated with the given entity.
   --  Returns a null object if the entity does not have any tag.
   function Get_Tags (From       : in Entity_Tag_Map;
                      For_Entity : in ADO.Identifier)
                      return Util.Beans.Objects.Object;

   --  Release the list of tags.
   procedure Clear (List : in out Entity_Tag_Map);

   --  Load the list of tags associated with a list of entities.
   procedure Load_Tags (Into        : in out Entity_Tag_Map;
                        Session     : in out ADO.Sessions.Session'Class;
                        Entity_Type : in String;
                        List        : in ADO.Utils.Identifier_Vector);

   --  Release the list of tags.
   overriding
   procedure Finalize (List : in out Entity_Tag_Map);

private

   type Tag_List_Bean is
     new Util.Beans.Objects.Lists.List_Bean and Util.Beans.Basic.Bean with record
      Module      : AWA.Tags.Modules.Tag_Module_Access;
      Entity_Type : Ada.Strings.Unbounded.Unbounded_String;
      Permission  : Ada.Strings.Unbounded.Unbounded_String;
      Current     : Natural := 0;
      Added       : Util.Strings.Vectors.Vector;
      Deleted     : Util.Strings.Vectors.Vector;
   end record;

   type Tag_Search_Bean is
     new Util.Beans.Objects.Lists.List_Bean and Util.Beans.Basic.Bean with record
      Module      : AWA.Tags.Modules.Tag_Module_Access;
      Entity_Type : Ada.Strings.Unbounded.Unbounded_String;
   end record;

   type Tag_Info_List_Bean is
     new AWA.Tags.Models.Tag_Info_List_Bean and Util.Beans.Basic.Bean with record
      Module      : AWA.Tags.Modules.Tag_Module_Access;
      Entity_Type : Ada.Strings.Unbounded.Unbounded_String;
   end record;

   package Entity_Tag_Maps is
     new Ada.Containers.Hashed_Maps (Key_Type        => ADO.Identifier,
                                     Element_Type    => Util.Beans.Lists.Strings.List_Bean_Access,
                                     Hash            => ADO.Utils.Hash,
                                     Equivalent_Keys => ADO."=",
                                     "="             => Util.Beans.Lists.Strings."=");

   type Entity_Tag_Map is new Ada.Finalization.Limited_Controlled with record
      Tags : Entity_Tag_Maps.Map;
   end record;

end AWA.Tags.Beans;

-----------------------------------------------------------------------
--  awa-tags-beans -- Beans for the tags module
--  Copyright (C) 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.Strings.Unbounded;
with Ada.Containers.Hashed_Maps;
with Ada.Containers.Ordered_Sets;
with Ada.Finalization;

with Util.Beans.Basic;
with Util.Beans.Objects.Lists;
with Util.Beans.Lists.Strings;
with Util.Strings.Vectors;

with ADO;
with ADO.Utils;
with ADO.Schemas;
with ADO.Sessions;

with AWA.Tags.Models;
with AWA.Tags.Modules;

--  == Tag Beans ==
--  Several bean types are provided to represent and manage a list of tags.
--  The tag module registers the bean constructors when it is initialized.
--  To use them, one must declare a bean definition in the application XML configuration.
--
--  === Tag_List_Bean ===
--  The <tt>Tag_List_Bean</tt> holds a list of tags and provides operations used by the
--  <tt>awa:tagList</tt> component to add or remove tags within a <tt>h:form</tt> component.
--  A bean can be declared and configured as follows in the XML application configuration file:
--
--    <managed-bean>
--      <managed-bean-name>questionTags</managed-bean-name>
--      <managed-bean-class>AWA.Tags.Beans.Tag_List_Bean</managed-bean-class>
--      <managed-bean-scope>request</managed-bean-scope>
--      <managed-property>
--        <property-name>entity_type</property-name>
--        <property-class>String</property-class>
--        <value>awa_question</value>
--      </managed-property>
--      <managed-property>
--        <property-name>permission</property-name>
--        <property-class>String</property-class>
--        <value>question-edit</value>
--      </managed-property>
--    </managed-bean>
--
--  The <tt>entity_type</tt> property defines the name of the database table to which the tags
--  are assigned.  The <tt>permission</tt> property defines the permission name that must be used
--  to verify that the user has the permission do add or remove the tag.  Such permission is
--  verified only when the <tt>awa:tagList</tt> component is used within a form.
--
--  === Tag_Search_Bean ===
--  The <tt>Tag_Search_Bean</tt> is dedicated to searching for tags that start with a given
--  pattern.  The auto complete feature of the <tt>awa:tagList</tt> component can use this
--  bean type to look in the database for tags matching a start pattern.  The declaration of the
--  bean should define the database table to search for tags associated with a given database
--  table.  This is done in the XML configuration with the <tt>entity_type</tt> property.
--
--    <managed-bean>
--      <managed-bean-name>questionTagSearch</managed-bean-name>
--      <managed-bean-class>AWA.Tags.Beans.Tag_Search_Bean</managed-bean-class>
--      <managed-bean-scope>request</managed-bean-scope>
--      <managed-property>
--        <property-name>entity_type</property-name>
--        <property-class>String</property-class>
--        <value>awa_question</value>
--      </managed-property>
--    </managed-bean>
--
--  === Tag_Info_List_Bean ===
--  The <tt>Tag_Info_List_Bean</tt> holds a collection of tags with their weight.  It is used
--  by the <tt>awa:tagCloud</tt> component.
--
--    <managed-bean>
--      <managed-bean-name>questionTagList</managed-bean-name>
--      <managed-bean-class>AWA.Tags.Beans.Tag_Info_List_Bean</managed-bean-class>
--      <managed-bean-scope>request</managed-bean-scope>
--      <managed-property>
--        <property-name>entity_type</property-name>
--        <property-class>String</property-class>
--        <value>awa_question</value>
--      </managed-property>
--    </managed-bean>
--
package AWA.Tags.Beans is

   --  Compare two tags on their count and name.
   function "<" (Left, Right : in AWA.Tags.Models.Tag_Info) return Boolean;

   package Tag_Ordered_Sets is
     new Ada.Containers.Ordered_Sets (Element_Type => AWA.Tags.Models.Tag_Info,
                                      "="          => AWA.Tags.Models."=");

   type Tag_List_Bean is
     new Util.Beans.Objects.Lists.List_Bean and Util.Beans.Basic.Bean with private;

   type Tag_List_Bean_Access is access all Tag_List_Bean'Class;

   --  Set the value identified by the name.
   --  If the name cannot be found, the method should raise the No_Value
   --  exception.
   overriding
   procedure Set_Value (From  : in out Tag_List_Bean;
                        Name  : in String;
                        Value : in Util.Beans.Objects.Object);

   --  Set the entity type (database table) onto which the tags are associated.
   procedure Set_Entity_Type (Into  : in out Tag_List_Bean;
                              Table : in ADO.Schemas.Class_Mapping_Access);

   --  Set the permission to check before removing or adding a tag on the entity.
   procedure Set_Permission (Into       : in out Tag_List_Bean;
                             Permission : in String);

   --  Load the tags associated with the given database identifier.
   procedure Load_Tags (Into          : in out Tag_List_Bean;
                        Session       : in ADO.Sessions.Session;
                        For_Entity_Id : in ADO.Identifier);

   --  Set the list of tags to add.
   procedure Set_Added (Into  : in out Tag_List_Bean;
                        Tags  : in Util.Strings.Vectors.Vector);

   --  Set the list of tags to remove.
   procedure Set_Deleted (Into : in out Tag_List_Bean;
                          Tags : in Util.Strings.Vectors.Vector);

   --  Update the tags associated with the tag entity represented by <tt>For_Entity_Id</tt>.
   --  The list of tags defined by <tt>Set_Deleted</tt> are removed first and the list of
   --  tags defined by <tt>Set_Added</tt> are associated with the database entity.
   procedure Update_Tags (From          : in Tag_List_Bean;
                          For_Entity_Id : in ADO.Identifier);

   --  Create the tag list bean instance.
   function Create_Tag_List_Bean (Module : in AWA.Tags.Modules.Tag_Module_Access)
                                  return Util.Beans.Basic.Readonly_Bean_Access;

   type Tag_Search_Bean is
     new Util.Beans.Objects.Lists.List_Bean and Util.Beans.Basic.Bean with private;
   type Tag_Search_Bean_Access is access all Tag_Search_Bean'Class;

   --  Set the value identified by the name.
   --  If the name cannot be found, the method should raise the No_Value
   --  exception.
   overriding
   procedure Set_Value (From  : in out Tag_Search_Bean;
                        Name  : in String;
                        Value : in Util.Beans.Objects.Object);

   --  Search the tags that match the search string.
   procedure Search_Tags (Into    : in out Tag_Search_Bean;
                          Session : in ADO.Sessions.Session;
                          Search  : in String);

   --  Set the entity type (database table) onto which the tags are associated.
   procedure Set_Entity_Type (Into  : in out Tag_Search_Bean;
                              Table : in ADO.Schemas.Class_Mapping_Access);

   --  Create the tag search bean instance.
   function Create_Tag_Search_Bean (Module : in AWA.Tags.Modules.Tag_Module_Access)
                                    return Util.Beans.Basic.Readonly_Bean_Access;

   type Tag_Info_List_Bean is
     new AWA.Tags.Models.Tag_Info_List_Bean and Util.Beans.Basic.Bean with private;
   type Tag_Info_List_Bean_Access is access all Tag_Info_List_Bean'Class;

   --  Set the value identified by the name.
   --  If the name cannot be found, the method should raise the No_Value
   --  exception.
   overriding
   procedure Set_Value (From  : in out Tag_Info_List_Bean;
                        Name  : in String;
                        Value : in Util.Beans.Objects.Object);

   --  Load the list of tags.
   procedure Load_Tags (Into    : in out Tag_Info_List_Bean;
                        Session : in out ADO.Sessions.Session);

   --  Create the tag info list bean instance.
   function Create_Tag_Info_List_Bean (Module : in AWA.Tags.Modules.Tag_Module_Access)
                                       return Util.Beans.Basic.Readonly_Bean_Access;

   --  The <tt>Entity_Tag_Map</tt> contains a list of tags associated with some entities.
   --  It allows to retrieve from the database all the tags associated with several entities
   --  and get the list of tags for a given entity.
   type Entity_Tag_Map is new Ada.Finalization.Limited_Controlled with private;

   --  Get the list of tags associated with the given entity.
   --  Returns null if the entity does not have any tag.
   function Get_Tags (From       : in Entity_Tag_Map;
                      For_Entity : in ADO.Identifier)
                      return Util.Beans.Lists.Strings.List_Bean_Access;

   --  Get the list of tags associated with the given entity.
   --  Returns a null object if the entity does not have any tag.
   function Get_Tags (From       : in Entity_Tag_Map;
                      For_Entity : in ADO.Identifier)
                      return Util.Beans.Objects.Object;

   --  Release the list of tags.
   procedure Clear (List : in out Entity_Tag_Map);

   --  Load the list of tags associated with a list of entities.
   procedure Load_Tags (Into        : in out Entity_Tag_Map;
                        Session     : in out ADO.Sessions.Session'Class;
                        Entity_Type : in String;
                        List        : in ADO.Utils.Identifier_Vector);

   --  Release the list of tags.
   overriding
   procedure Finalize (List : in out Entity_Tag_Map);

private

   type Tag_List_Bean is
     new Util.Beans.Objects.Lists.List_Bean and Util.Beans.Basic.Bean with record
      Module      : AWA.Tags.Modules.Tag_Module_Access;
      Entity_Type : Ada.Strings.Unbounded.Unbounded_String;
      Permission  : Ada.Strings.Unbounded.Unbounded_String;
      Current     : Natural := 0;
      Added       : Util.Strings.Vectors.Vector;
      Deleted     : Util.Strings.Vectors.Vector;
   end record;

   type Tag_Search_Bean is
     new Util.Beans.Objects.Lists.List_Bean and Util.Beans.Basic.Bean with record
      Module      : AWA.Tags.Modules.Tag_Module_Access;
      Entity_Type : Ada.Strings.Unbounded.Unbounded_String;
   end record;

   type Tag_Info_List_Bean is
     new AWA.Tags.Models.Tag_Info_List_Bean and Util.Beans.Basic.Bean with record
      Module      : AWA.Tags.Modules.Tag_Module_Access;
      Entity_Type : Ada.Strings.Unbounded.Unbounded_String;
   end record;

   package Entity_Tag_Maps is
     new Ada.Containers.Hashed_Maps (Key_Type        => ADO.Identifier,
                                     Element_Type    => Util.Beans.Lists.Strings.List_Bean_Access,
                                     Hash            => ADO.Utils.Hash,
                                     Equivalent_Keys => ADO."=",
                                     "="             => Util.Beans.Lists.Strings."=");

   type Entity_Tag_Map is new Ada.Finalization.Limited_Controlled with record
      Tags : Entity_Tag_Maps.Map;
   end record;

end AWA.Tags.Beans;

Fix comments and documentation

Fix comments and documentation


-----------------------------------------------------------------------
--  wiki-render-html -- Wiki HTML renderer
--  Copyright (C) 2011, 2012, 2013, 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 Wiki.Attributes;
with Wiki.Documents;
with Wiki.Streams.Html;
with Wiki.Strings;

--  == HTML Renderer ==
--  The <tt>Text_Renderer</tt> allows to render a wiki document into a text content.
--  The formatting rules are ignored except for the paragraphs and sections.
package Wiki.Render.Html is

   --  ------------------------------
   --  Wiki to HTML renderer
   --  ------------------------------
   type Html_Renderer is new Renderer with private;

   --  Set the output stream.
   procedure Set_Output_Stream (Engine : in out Html_Renderer;
                                Stream : in Wiki.Streams.Html.Html_Output_Stream_Access);

   --  Set the link renderer.
   procedure Set_Link_Renderer (Document : in out Html_Renderer;
                                Links    : in Link_Renderer_Access);

   --  Render the node instance from the document.
   overriding
   procedure Render (Engine : in out Html_Renderer;
                     Doc    : in Wiki.Nodes.Document;
                     Node   : in Wiki.Nodes.Node_Type);

   --  Add a blockquote (<blockquote>).  The level indicates the blockquote nested level.
   --  The blockquote must be closed at the next header.
   procedure Add_Blockquote (Document : in out Html_Renderer;
                             Level    : in Natural);

   --  Add a list item (<li>).  Close the previous paragraph and list item if any.
   --  The list item will be closed at the next list item, next paragraph or next header.
   procedure Add_List_Item (Document : in out Html_Renderer;
                            Level    : in Positive;
                            Ordered  : in Boolean);

   --  Add an image.
   procedure Add_Image (Document    : in out Html_Renderer;
                        Link        : in Unbounded_Wide_Wide_String;
                        Alt         : in Unbounded_Wide_Wide_String;
                        Position    : in Unbounded_Wide_Wide_String;
                        Description : in Unbounded_Wide_Wide_String);

   --  Add a quote.
   procedure Add_Quote (Document : in out Html_Renderer;
                        Quote    : in Unbounded_Wide_Wide_String;
                        Link     : in Unbounded_Wide_Wide_String;
                        Language : in Unbounded_Wide_Wide_String);

   --  Add a text block with the given format.
   procedure Add_Text (Engine   : in out Html_Renderer;
                       Text     : in Wiki.Strings.WString;
                       Format   : in Wiki.Documents.Format_Map);

   --  Add a text block that is pre-formatted.
   procedure Add_Preformatted (Document : in out Html_Renderer;
                               Text     : in Unbounded_Wide_Wide_String;
                               Format   : in Unbounded_Wide_Wide_String);

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

private

   procedure Close_Paragraph (Document : in out Html_Renderer);
   procedure Open_Paragraph (Document : in out Html_Renderer);

   type List_Style_Array is array (1 .. 32) of Boolean;

   Default_Links : aliased Default_Link_Renderer;

   type Html_Renderer is new Renderer with record
      Output         : Wiki.Streams.Html.Html_Output_Stream_Access := null;
      Format         : Wiki.Documents.Format_Map := (others => False);
      Links          : Link_Renderer_Access := Default_Links'Access;
      Has_Paragraph  : Boolean := False;
      Need_Paragraph : Boolean := False;
      Has_Item       : Boolean := False;
      Current_Level  : Natural := 0;
      List_Styles    : List_Style_Array := (others => False);
      Quote_Level    : Natural := 0;
      Html_Level     : Natural := 0;
   end record;

   procedure Render_Tag (Engine : in out Html_Renderer;
                         Doc    : in Wiki.Nodes.Document;
                         Node   : in Wiki.Nodes.Node_Type);

   --  Render a section header in the document.
   procedure Render_Header (Engine : in out Html_Renderer;
                            Header : in Wiki.Strings.WString;
                            Level  : in Positive);

   --  Render a link.
   procedure Render_Link (Engine : in out Html_Renderer;
                          Doc    : in Wiki.Nodes.Document;
                          Title  : in Wiki.Strings.WString;
                          Attr   : in Wiki.Attributes.Attribute_List_Type);

end Wiki.Render.Html;

-----------------------------------------------------------------------
--  wiki-render-html -- Wiki HTML renderer
--  Copyright (C) 2011, 2012, 2013, 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 Wiki.Attributes;
with Wiki.Documents;
with Wiki.Streams.Html;
with Wiki.Strings;

--  == HTML Renderer ==
--  The <tt>Text_Renderer</tt> allows to render a wiki document into a text content.
--  The formatting rules are ignored except for the paragraphs and sections.
package Wiki.Render.Html is

   --  ------------------------------
   --  Wiki to HTML renderer
   --  ------------------------------
   type Html_Renderer is new Renderer with private;

   --  Set the output stream.
   procedure Set_Output_Stream (Engine : in out Html_Renderer;
                                Stream : in Wiki.Streams.Html.Html_Output_Stream_Access);

   --  Set the link renderer.
   procedure Set_Link_Renderer (Document : in out Html_Renderer;
                                Links    : in Link_Renderer_Access);

   --  Render the node instance from the document.
   overriding
   procedure Render (Engine : in out Html_Renderer;
                     Doc    : in Wiki.Nodes.Document;
                     Node   : in Wiki.Nodes.Node_Type);

   --  Add a blockquote (<blockquote>).  The level indicates the blockquote nested level.
   --  The blockquote must be closed at the next header.
   procedure Add_Blockquote (Document : in out Html_Renderer;
                             Level    : in Natural);

   --  Add a list item (<li>).  Close the previous paragraph and list item if any.
   --  The list item will be closed at the next list item, next paragraph or next header.
   procedure Add_List_Item (Document : in out Html_Renderer;
                            Level    : in Positive;
                            Ordered  : in Boolean);

   --  Add a quote.
   procedure Add_Quote (Document : in out Html_Renderer;
                        Quote    : in Unbounded_Wide_Wide_String;
                        Link     : in Unbounded_Wide_Wide_String;
                        Language : in Unbounded_Wide_Wide_String);

   --  Add a text block with the given format.
   procedure Add_Text (Engine   : in out Html_Renderer;
                       Text     : in Wiki.Strings.WString;
                       Format   : in Wiki.Documents.Format_Map);

   --  Add a text block that is pre-formatted.
   procedure Add_Preformatted (Document : in out Html_Renderer;
                               Text     : in Unbounded_Wide_Wide_String;
                               Format   : in Unbounded_Wide_Wide_String);

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

private

   procedure Close_Paragraph (Document : in out Html_Renderer);
   procedure Open_Paragraph (Document : in out Html_Renderer);

   type List_Style_Array is array (1 .. 32) of Boolean;

   Default_Links : aliased Default_Link_Renderer;

   type Html_Renderer is new Renderer with record
      Output         : Wiki.Streams.Html.Html_Output_Stream_Access := null;
      Format         : Wiki.Documents.Format_Map := (others => False);
      Links          : Link_Renderer_Access := Default_Links'Access;
      Has_Paragraph  : Boolean := False;
      Need_Paragraph : Boolean := False;
      Has_Item       : Boolean := False;
      Current_Level  : Natural := 0;
      List_Styles    : List_Style_Array := (others => False);
      Quote_Level    : Natural := 0;
      Html_Level     : Natural := 0;
   end record;

   procedure Render_Tag (Engine : in out Html_Renderer;
                         Doc    : in Wiki.Nodes.Document;
                         Node   : in Wiki.Nodes.Node_Type);

   --  Render a section header in the document.
   procedure Render_Header (Engine : in out Html_Renderer;
                            Header : in Wiki.Strings.WString;
                            Level  : in Positive);

   --  Render a link.
   procedure Render_Link (Engine : in out Html_Renderer;
                          Doc    : in Wiki.Nodes.Document;
                          Title  : in Wiki.Strings.WString;
                          Attr   : in Wiki.Attributes.Attribute_List_Type);

   --  Render an image.
   procedure Render_Image (Engine : in out Html_Renderer;
                           Doc    : in Wiki.Nodes.Document;
                           Title  : in Wiki.Strings.WString;
                           Attr   : in Wiki.Attributes.Attribute_List_Type);

end Wiki.Render.Html;

Rename Add_Image into Render_Image and update prototype


-- Simple template program to allow viewing of 2D objects using OpenGL.
-- All setup is done already--just add the OpenGL code to draw the objects
-- below.  You may also add any special initialization you need.  Search
-- for the text "here:" to find the insertion points.  The optimum viewing
-- area lies between -1 and +1 on both axes.
--
-- W. M. Richards, NiEstu, Phoenix AZ, January 2001
-- Ported to Lumen February 2011 by WMR

-- This code is covered by the GNU GPL, http://www.gnu.org/copyleft/gpl.html
--
-- Copyright 2001, 2011  W. M. Richards

-- Environment
with Ada.Characters.Latin_1;
with Ada.Text_IO;

with Lumen.Events;
with Lumen.Events.Animate;
with Lumen.Events.Keys;
with Lumen.Font.Txf;
with Lumen.GL;
with Lumen.GLU;
with Lumen.Image;
with Lumen.Window;

-- Enclosing procedure
procedure Simple_2D is

   ----------------------------------------------------------------------------

   use Lumen;  -- yes, we're definitely using Lumen

   ----------------------------------------------------------------------------

   -- Constants
   Win_Start : constant GL.SizeI := 500;  -- in pixels; adjust to suit your scene's needs

   -- Keystrokes we care about
   Escape    : constant Events.Key_Symbol := Events.Key_Symbol (Character'Pos (Ada.Characters.Latin_1.ESC));
   Letter_q  : constant Events.Key_Symbol := Events.Key_Symbol (Character'Pos (Ada.Characters.Latin_1.LC_Q));

   ---------------------------------------------------------------------------

   -- App-specific exceptions
   Program_Error : exception;
   Program_Exit  : exception;

   ----------------------------------------------------------------------------

   -- Program variables
   Win          : Window.Window_Handle;
   Curr_W       : Natural   := Win_Start;
   Curr_H       : Natural   := Win_Start;
   Aspect       : GL.Double := GL.Double (Win_Start) / GL.Double (Win_Start);
   StartX       : GL.Double := 0.0;
   StartY       : GL.Double := 0.0;
   RotC         : GL.Double := 0.0;
   Scale        : GL.Double := 1.0;
   XPan         : GL.Double := 0.0;
   YPan         : GL.Double := 0.0;
   Curr_RotC    : GL.Double := 0.0;
   Curr_Scale   : GL.Double := 1.0;
   Curr_XPan    : GL.Double := 0.0;
   Curr_YPan    : GL.Double := 0.0;
   Terminated   : Boolean := False;

   ----------------------------------------------------------------------------
   -----                                                                  -----
   -----                         L O C A L S                              -----
   -----                                                                  -----
   ----------------------------------------------------------------------------

   -- Drop out of the main Gtk loop
   procedure Finish is
   begin  -- Finish
      Terminated := True;
   end Finish;

   ----------------------------------------------------------------------------

   -- Format a string showing current view status
   function Sts_String return String is

      package IntIO is new Ada.Text_IO.Integer_IO (integer);
      package FltIO is new Ada.Text_IO.Float_IO (GL.Double);

      Pad       : String (1 .. 10) := "          ";
      XPanStr   : String (1 .. 6);
      YPanStr   : String (1 .. 6);
      RotCStr   : String (1 .. 6);
      SclStr    : String (1 .. 6);

   begin  -- Sts_String
      FltIO.Put (XPanStr, XPan, Aft => 2, Exp => 0);
      FltIO.Put (YPanStr, YPan, Aft => 2, Exp => 0);
      IntIO.Put (RotCStr, (360 - Integer (RotC)) mod 360);
      FltIO.Put (SclStr,  Scale, Aft => 2, Exp => 0);
      return Pad & "Pan:  (" & XPanStr & ", " & YPanStr & ") " &
             Pad & "Rotation:  " & RotCStr &
             Pad & "Scale:  " & SclStr;
   end Sts_String;

   ----------------------------------------------------------------------------

   -- Set or reset the window view parameters
   procedure Set_View (W, H : in Natural) is
   begin  -- Set_View

      -- Set the globals used in some calculations
      Curr_W := W;
      Curr_H := H;

      -- Viewport dimensions
      GL.Viewport (0, 0, GL.SizeI (W), GL.SizeI (H));

      -- Set up the projection matrix based on the window's shape--wider than
      -- high, or higher than wide
      GL.Matrix_Mode (GL.GL_PROJECTION);
      GL.Load_Identity;
      if W <= H then
         Aspect := GL.Double (H) / GL.Double (W);
         GLU.Ortho_2D (-2.0, 2.0, -2.0 * Aspect, 2.0 * Aspect);
      else
         Aspect := GL.Double (W) / GL.Double (H);
         GLU.Ortho_2D (-2.0 * Aspect, 2.0 * Aspect, -2.0, 2.0);
      end if;
   end Set_View;

   ----------------------------------------------------------------------------

   -- Update the drawing area
   procedure Display is

      ------------------------------------------------------------------------

      -- Local utility routine to draw a line segment
      procedure Draw_Line (X1, Y1, X2, Y2 : in GL.Double) is
      begin  -- Draw_Line
         GL.Begin_Primitive (GL.GL_LINES);
         GL.Vertex (X1, Y1);
         GL.Vertex (X2, Y2);
         GL.End_Primitive;
      end Draw_Line;

      ------------------------------------------------------------------------

      -- Draw visible axes in space
      procedure Draw_Axes is
      begin  -- Draw_Axes
         GL.Color (Float (1.0), 0.0, 0.0, 1.0);   Draw_Line (-1.0,  0.0, 1.0, 0.0);
         GL.Color (Float (0.0), 1.0, 0.0, 1.0);   Draw_Line ( 0.0, -1.0, 0.0, 1.0);
      end Draw_Axes;

      ------------------------------------------------------------------------

   begin  -- Display

      -- Clear to black (the default)
      GL.Clear (GL.GL_COLOR_BUFFER_BIT);

      -- Set up the viewing transforms
      GL.Matrix_Mode (GL.GL_MODELVIEW);
      GL.Load_Identity;
      GL.Translate (XPan, YPan, 0.0);
      GL.Scale (Scale, Scale, Scale);
      GL.Rotate (RotC, 0.0, 0.0, 1.0);

      -- Draw simple 2D axes
      Draw_Axes;
      GL.Flush;

      -- Put the code to draw your objects here:

      -- Swap the drawing we just did into the display area
      Window.Swap (Win);

      -- Update the status bar

   end Display;

   ----------------------------------------------------------------------------
   -----                                                                  -----
   -----                      C A L L B A C K S                           -----
   -----                                                                  -----
   ----------------------------------------------------------------------------

   -- Callback triggered by the Resized event; tell OpenGL that the
   -- user has resized the window
   procedure Resize_Handler (Height : in Integer;
                             Width  : in Integer) is
   begin  -- Resize_Handler

      -- Set the new view parameters and redraw the scene
      Set_View (Width, Height);
      Display;

   end Resize_Handler;

   ---------------------------------------------------------------------------

   -- Simple event handler routine for keypresses
   procedure Key_Handler (Category  : in Events.Key_Category;
                          Symbol    : in Events.Key_Symbol;
                          Modifiers : in Events.Modifier_Set) is

      use type Events.Key_Symbol;

   begin  -- Key_Handler
      case Symbol is
         when Escape | Letter_q =>
            Finish;

         when Events.Keys.Home =>
            RotC  := 0.0;
            Scale := 1.0;
            XPan  := 0.0;
            YPan  := 0.0;
            Display;

         when others =>
            null;
      end case;
   end Key_Handler;

   ----------------------------------------------------------------------------

   -- Mouse button has been pressed
   procedure Button_Handler (X         : in Integer;
                             Y         : in Integer;
                             Button    : in Window.Button_Enum;
                             Modifiers : in Events.Modifier_Set) is

      use type Window.Button_Enum;

   begin  -- Button_Handler

      -- Record starting position and current rotation/scale
      StartX := GL.Double (X);
      StartY := GL.Double (Curr_H - Y);
      Curr_RotC  := RotC;
      Curr_Scale := Scale;
      Curr_XPan  := XPan;
      Curr_YPan  := YPan;

      -- Handle mouse wheel events
      if Button = Window.Button_4 then
         Scale := Curr_Scale - 0.1;
         Display;
      elsif Button = Window.Button_5 then
         Scale := Curr_Scale + 0.1;
         Display;
      end if;
   end Button_Handler;

   ----------------------------------------------------------------------------

   -- Mouse movement
   procedure Drag_Handler (X         : in Integer;
                           Y         : in Integer;
                           Modifiers : in Events.Modifier_Set) is

      Y_Prime : Integer := Curr_H - Y;

   begin  -- Drag_Handler

      -- If it's a drag, update the figure parameters
      if Modifiers (Events.Mod_Button_1) then
         XPan := Curr_XPan + ((GL.Double (X) - StartX) / GL.Double (Curr_W));
         YPan := Curr_YPan + ((GL.Double (Y) - StartY) / GL.Double (Curr_H));
         Display;
      elsif Modifiers (Events.Mod_Button_2) then
         RotC := GL.Double (integer (Curr_RotC - ((GL.Double (X) - StartX) + (StartY - GL.Double (Y)))) mod 360);
         Display;
      elsif Modifiers (Events.Mod_Button_3) then
         Scale := Curr_Scale + ((GL.Double (X) - StartX) / GL.Double (Curr_W)) -
                  ((GL.Double (Y) - StartY) / GL.Double (Curr_H));
         Display;
      end if;

   end Drag_Handler;

   ----------------------------------------------------------------------------

   -- Re-draw the view
   procedure Expose_Handler (Top    : in Integer;
                             Left   : in Integer;
                             Height : in Natural;
                             Width  : in Natural) is
   begin  -- Expose_Handler
      Display;
   end Expose_Handler;

   ----------------------------------------------------------------------------

   -- Called once per frame; just re-draws the scene
   function New_Frame (Frame_Delta : in Duration) return Boolean is
   begin  -- New_Frame
      Display;
      return not Terminated;
   end New_Frame;

   ----------------------------------------------------------------------------
   -----                                                                  -----
   -----                           S E T U P                              -----
   -----                                                                  -----
   ----------------------------------------------------------------------------

   -- Set up the main window and all its fiddly bits
   procedure Init is
   begin  -- Init

      -- Create the main window
      Window.Create (Win,
                     Name       => "2D Object Viewer",
                     Width      => Win_Start,
                     Height     => Win_Start);

      Win.Exposed    := Expose_Handler'Unrestricted_Access;
      Win.Resize     := Resize_Handler'Unrestricted_Access;
      Win.Key_Press  := Key_Handler'Unrestricted_Access;
      Win.Mouse_Down := Button_Handler'Unrestricted_Access;
      Win.Mouse_Move := Drag_Handler'Unrestricted_Access;

      Set_View (Win_Start, Win_Start);
      Display;

      -- Create a packing box to stuff everything into

      -- Create the OpenGL drawing area

      -- Connect the event handlers

      -- Put the OpenGL drawing area into the packing box

      -- The status bar

      -- The quit button

      -- Put any one-time OpenGL initialization code here:

   end Init;

-------------------------------------------------------------------------------
-----                                                                     -----
-----                             M A I N                                 -----
-----                                                                     -----
-------------------------------------------------------------------------------

-- The main procedure
begin  -- Simple_2D
   Init;

   -- Framerate assumed to be 24Hz
   Lumen.Events.Animate.Run (Win, 24,New_Frame'Unrestricted_Access);

exception
   when Program_Exit =>
      null;  -- just exit this block, which terminates the app

end Simple_2D;

-- Simple template program to allow viewing of 2D objects using OpenGL.
-- All setup is done already--just add the OpenGL code to draw the objects
-- below.  You may also add any special initialization you need.  Search
-- for the text "here:" to find the insertion points.  The optimum viewing
-- area lies between -1 and +1 on both axes.
--
-- W. M. Richards, NiEstu, Phoenix AZ, January 2001
-- Ported to Lumen February 2011 by WMR

-- This code is covered by the GNU GPL, http://www.gnu.org/copyleft/gpl.html
--
-- Copyright 2001, 2011  W. M. Richards

-- Environment
with Ada.Characters.Latin_1;
with Ada.Text_IO;

with Lumen.Events;
with Lumen.Events.Animate;
with Lumen.Events.Keys;
with Lumen.Font.Txf;
with Lumen.GL;
with Lumen.GLU;
with Lumen.Image;
with Lumen.Window;

-- Enclosing procedure
procedure Simple_2D is

   ----------------------------------------------------------------------------

   use Lumen;  -- yes, we're definitely using Lumen

   ----------------------------------------------------------------------------

   -- Constants
   Win_Start : constant GL.SizeI := 500;  -- in pixels; adjust to suit your scene's needs

   -- Keystrokes we care about
   Escape    : constant Events.Key_Symbol := Events.Key_Symbol (Character'Pos (Ada.Characters.Latin_1.ESC));
   Letter_q  : constant Events.Key_Symbol := Events.Key_Symbol (Character'Pos (Ada.Characters.Latin_1.LC_Q));

   ---------------------------------------------------------------------------

   -- App-specific exceptions
   Program_Error : exception;
   Program_Exit  : exception;

   ----------------------------------------------------------------------------

   -- Program variables
   Win          : Window.Window_Handle;
   Curr_W       : Natural   := Win_Start;
   Curr_H       : Natural   := Win_Start;
   Aspect       : GL.Double := GL.Double (Win_Start) / GL.Double (Win_Start);
   StartX       : GL.Double := 0.0;
   StartY       : GL.Double := 0.0;
   RotC         : GL.Double := 0.0;
   Scale        : GL.Double := 1.0;
   XPan         : GL.Double := 0.0;
   YPan         : GL.Double := 0.0;
   Curr_RotC    : GL.Double := 0.0;
   Curr_Scale   : GL.Double := 1.0;
   Curr_XPan    : GL.Double := 0.0;
   Curr_YPan    : GL.Double := 0.0;
   Terminated   : Boolean := False;

   ----------------------------------------------------------------------------
   -----                                                                  -----
   -----                         L O C A L S                              -----
   -----                                                                  -----
   ----------------------------------------------------------------------------

   -- Drop out of the main Gtk loop
   procedure Finish is
   begin  -- Finish
      Terminated := True;
   end Finish;

   ----------------------------------------------------------------------------

   -- Format a string showing current view status
   function Sts_String return String is

      package IntIO is new Ada.Text_IO.Integer_IO (integer);
      package FltIO is new Ada.Text_IO.Float_IO (GL.Double);

      Pad       : String (1 .. 10) := "          ";
      XPanStr   : String (1 .. 6);
      YPanStr   : String (1 .. 6);
      RotCStr   : String (1 .. 6);
      SclStr    : String (1 .. 6);

   begin  -- Sts_String
      FltIO.Put (XPanStr, XPan, Aft => 2, Exp => 0);
      FltIO.Put (YPanStr, YPan, Aft => 2, Exp => 0);
      IntIO.Put (RotCStr, (360 - Integer (RotC)) mod 360);
      FltIO.Put (SclStr,  Scale, Aft => 2, Exp => 0);
      return Pad & "Pan:  (" & XPanStr & ", " & YPanStr & ") " &
             Pad & "Rotation:  " & RotCStr &
             Pad & "Scale:  " & SclStr;
   end Sts_String;

   ----------------------------------------------------------------------------

   -- Set or reset the window view parameters
   procedure Set_View (W, H : in Natural) is
   begin  -- Set_View

      -- Set the globals used in some calculations
      Curr_W := W;
      Curr_H := H;

      -- Viewport dimensions
      GL.Viewport (0, 0, GL.SizeI (W), GL.SizeI (H));

      -- Set up the projection matrix based on the window's shape--wider than
      -- high, or higher than wide
      GL.Matrix_Mode (GL.GL_PROJECTION);
      GL.Load_Identity;
      if W <= H then
         Aspect := GL.Double (H) / GL.Double (W);
         GLU.Ortho_2D (-2.0, 2.0, -2.0 * Aspect, 2.0 * Aspect);
      else
         Aspect := GL.Double (W) / GL.Double (H);
         GLU.Ortho_2D (-2.0 * Aspect, 2.0 * Aspect, -2.0, 2.0);
      end if;
   end Set_View;

   ----------------------------------------------------------------------------

   -- Update the drawing area
   procedure Display is

      ------------------------------------------------------------------------

      -- Local utility routine to draw a line segment
      procedure Draw_Line (X1, Y1, X2, Y2 : in GL.Double) is
      begin  -- Draw_Line
         GL.Begin_Primitive (GL.GL_LINES);
         GL.Vertex (X1, Y1);
         GL.Vertex (X2, Y2);
         GL.End_Primitive;
      end Draw_Line;

      ------------------------------------------------------------------------

      -- Draw visible axes in space
      procedure Draw_Axes is
      begin  -- Draw_Axes
         GL.Color (Float (1.0), 0.0, 0.0, 1.0);   Draw_Line (-1.0,  0.0, 1.0, 0.0);
         GL.Color (Float (0.0), 1.0, 0.0, 1.0);   Draw_Line ( 0.0, -1.0, 0.0, 1.0);
      end Draw_Axes;

      ------------------------------------------------------------------------

   begin  -- Display

      -- Clear to black (the default)
      GL.Clear (GL.GL_COLOR_BUFFER_BIT);

      -- Set up the viewing transforms
      GL.Matrix_Mode (GL.GL_MODELVIEW);
      GL.Load_Identity;
      GL.Translate (XPan, YPan, 0.0);
      GL.Scale (Scale, Scale, Scale);
      GL.Rotate (RotC, 0.0, 0.0, 1.0);

      -- Draw simple 2D axes
      Draw_Axes;
      GL.Flush;

      -- Put the code to draw your objects here:

      -- Swap the drawing we just did into the display area
      Window.Swap (Win);

      -- Update the status bar

   end Display;

   ----------------------------------------------------------------------------
   -----                                                                  -----
   -----                      C A L L B A C K S                           -----
   -----                                                                  -----
   ----------------------------------------------------------------------------

   -- Callback triggered by the Resized event; tell OpenGL that the
   -- user has resized the window
   procedure Resize_Handler (Height : in Integer;
                             Width  : in Integer) is
   begin  -- Resize_Handler

      -- Set the new view parameters and redraw the scene
      Set_View (Width, Height);
      Display;

   end Resize_Handler;

   ---------------------------------------------------------------------------

   -- Simple event handler routine for keypresses
   procedure Key_Handler (Category  : in Events.Key_Category;
                          Symbol    : in Events.Key_Symbol;
                          Modifiers : in Events.Modifier_Set) is

      use type Events.Key_Symbol;

   begin  -- Key_Handler
      case Symbol is
         when Escape | Letter_q =>
            Finish;

         when Events.Keys.Home =>
            RotC  := 0.0;
            Scale := 1.0;
            XPan  := 0.0;
            YPan  := 0.0;
            Display;

         when others =>
            null;
      end case;
   end Key_Handler;

   ----------------------------------------------------------------------------

   -- Mouse button has been pressed
   procedure Button_Handler (X         : in Integer;
                             Y         : in Integer;
                             Button    : in Window.Button_Enum;
                             Modifiers : in Events.Modifier_Set) is

      use type Window.Button_Enum;

   begin  -- Button_Handler

      -- Record starting position and current rotation/scale
      StartX := GL.Double (X);
      StartY := GL.Double (Y);
      Curr_RotC  := RotC;
      Curr_Scale := Scale;
      Curr_XPan  := XPan;
      Curr_YPan  := YPan;

      -- Handle mouse wheel events
      if Button = Window.Button_4 then
         Scale := Curr_Scale - 0.1;
         Display;
      elsif Button = Window.Button_5 then
         Scale := Curr_Scale + 0.1;
         Display;
      end if;
   end Button_Handler;

   ----------------------------------------------------------------------------

   -- Mouse movement
   procedure Drag_Handler (X         : in Integer;
                           Y         : in Integer;
                           Modifiers : in Events.Modifier_Set) is

      Y_Prime : Integer := Curr_H - Y;

   begin  -- Drag_Handler

      -- If it's a drag, update the figure parameters
      if Modifiers (Events.Mod_Button_1) then
         XPan := Curr_XPan + ((GL.Double (X) - StartX) / GL.Double (Curr_W));
         YPan := Curr_YPan + ((GL.Double (Y_Prime) - StartY) / GL.Double (Curr_H));
         Display;
      elsif Modifiers (Events.Mod_Button_2) then
         RotC := GL.Double (Integer (Curr_RotC - ((GL.Double (X) - StartX) + (StartY - GL.Double (Y_Prime)))) mod 360);
         Display;
      elsif Modifiers (Events.Mod_Button_3) then
         Scale := Curr_Scale + ((GL.Double (X) - StartX) / GL.Double (Curr_W)) -
                  ((GL.Double (Y_Prime) - StartY) / GL.Double (Curr_H));
         Display;
      end if;

   end Drag_Handler;

   ----------------------------------------------------------------------------

   -- Re-draw the view
   procedure Expose_Handler (Top    : in Integer;
                             Left   : in Integer;
                             Height : in Natural;
                             Width  : in Natural) is
   begin  -- Expose_Handler
      Display;
   end Expose_Handler;

   ----------------------------------------------------------------------------

   -- Called once per frame; just re-draws the scene
   function New_Frame (Frame_Delta : in Duration) return Boolean is
   begin  -- New_Frame
      Display;
      return not Terminated;
   end New_Frame;

   ----------------------------------------------------------------------------
   -----                                                                  -----
   -----                           S E T U P                              -----
   -----                                                                  -----
   ----------------------------------------------------------------------------

   -- Set up the main window and all its fiddly bits
   procedure Init is
   begin  -- Init

      -- Create the main window
      Window.Create (Win,
                     Name       => "2D Object Viewer",
                     Width      => Win_Start,
                     Height     => Win_Start);

      Win.Exposed    := Expose_Handler'Unrestricted_Access;
      Win.Resize     := Resize_Handler'Unrestricted_Access;
      Win.Key_Press  := Key_Handler'Unrestricted_Access;
      Win.Mouse_Down := Button_Handler'Unrestricted_Access;
      Win.Mouse_Move := Drag_Handler'Unrestricted_Access;

      Set_View (Win_Start, Win_Start);
      Display;

      -- Create a packing box to stuff everything into

      -- Create the OpenGL drawing area

      -- Connect the event handlers

      -- Put the OpenGL drawing area into the packing box

      -- The status bar

      -- The quit button

      -- Put any one-time OpenGL initialization code here:

   end Init;

-------------------------------------------------------------------------------
-----                                                                     -----
-----                             M A I N                                 -----
-----                                                                     -----
-------------------------------------------------------------------------------

-- The main procedure
begin  -- Simple_2D
   Init;

   -- Framerate assumed to be 24Hz
   Lumen.Events.Animate.Run (Win, 24,New_Frame'Unrestricted_Access);

exception
   when Program_Exit =>
      null;  -- just exit this block, which terminates the app

end Simple_2D;

Use inverted Y coordinate value that we carefully calculated and then ignored


-----------------------------------------------------------------------
--  atlas -- atlas applications
-----------------------------------------------------------------------
--  Copyright (C) 2011 unknown
--  Written by unknown (unknown@company.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.IO_Exceptions;

with Util.Log.Loggers;
with Util.Properties;

with ASF.Applications;
with ASF.Applications.Main;
with ASF.Applications.Main.Configs;

--  with Atlas.XXX.Module;
package body Atlas.Applications is

   use AWA.Applications;

   Log     : constant Util.Log.Loggers.Logger := Util.Log.Loggers.Create ("Atlas");

   --  ------------------------------
   --  Initialize the application:
   --

   --
Register the servlets and filters.
   --
Register the application modules.
   --
Define the servlet and filter mappings.
   --

   --  ------------------------------
   procedure Initialize (App : in Application_Access) is
      Fact  : ASF.Applications.Main.Application_Factory;
      C     : ASF.Applications.Config;
   begin
      App.Self := App;
      begin
         C.Load_Properties ("atlas.properties");
         Util.Log.Loggers.Initialize (Util.Properties.Manager (C));

      exception
         when Ada.IO_Exceptions.Name_Error =>
            Log.Error ("Cannot read application configuration file {0}", CONFIG_PATH);
      end;
      App.Initialize (C, Fact);

      App.Set_Global ("contextPath", CONTEXT_PATH);
   end Initialize;

   --  ------------------------------
   --  Initialize the servlets provided by the application.
   --  This procedure is called by Initialize.
   --  It should register the application servlets.
   --  ------------------------------
   overriding
   procedure Initialize_Servlets (App : in out Application) is
   begin
      Log.Info ("Initializing application servlets...");

      AWA.Applications.Application (App).Initialize_Servlets;
      App.Add_Servlet (Name => "faces", Server => App.Self.Faces'Access);
      App.Add_Servlet (Name => "files", Server => App.Self.Files'Access);
      App.Add_Servlet (Name => "ajax", Server => App.Self.Ajax'Access);
      App.Add_Servlet (Name => "measures", Server => App.Self.Measures'Access);
      App.Add_Servlet (Name => "auth", Server => App.Self.Auth'Access);
      App.Add_Servlet (Name => "verify-auth", Server => App.Self.Verify_Auth'Access);
   end Initialize_Servlets;

   --  ------------------------------
   --  Initialize the filters provided by the application.
   --  This procedure is called by Initialize.
   --  It should register the application filters.
   --  ------------------------------
   overriding
   procedure Initialize_Filters (App : in out Application) is
   begin
      Log.Info ("Initializing application filters...");

      AWA.Applications.Application (App).Initialize_Filters;
      App.Add_Filter (Name => "dump", Filter => App.Dump'Access);
      App.Add_Filter (Name => "measures", Filter => App.Measures'Access);
      App.Add_Filter (Name => "service", Filter => App.Service_Filter'Access);
   end Initialize_Filters;

   --  ------------------------------
   --  Initialize the AWA modules provided by the application.
   --  This procedure is called by Initialize.
   --  It should register the modules used by the application.
   --  ------------------------------
   overriding
   procedure Initialize_Modules (App : in out Application) is
   begin
      Log.Info ("Initializing application modules...");
      ASF.Applications.Main.Configs.Read_Configuration (App, "web/WEB-INF/web.xml");

      Register (App    => App.Self.all'Access,
                Name   => AWA.Users.Module.NAME,
                URI    => "user",
                Module => App.User_Module'Access);

      Register (App    => App.Self.all'Access,
                Name   => "workspaces",
                URI    => "workspaces",
                Module => App.Workspace_Module'Access);

      Register (App    => App.Self.all'Access,
                Name   => AWA.Mail.Module.NAME,
                URI    => "mail",
                Module => App.Mail_Module'Access);

      Register (App    => App.Self.all'Access,
                Name   => AWA.Storages.Modules.NAME,
                URI    => "storages",
                Module => App.Storage_Module'Access);

      Register (App    => App.Self.all'Access,
                Name   => AWA.Blogs.Module.NAME,
                URI    => "blogs",
                Module => App.Blog_Module'Access);

      Register (App    => App.Self.all'Access,
                Name   => AWA.Comments.Module.NAME,
                URI    => "comments",
                Module => App.Comment_Module'Access);
   end Initialize_Modules;

end Atlas.Applications;

-----------------------------------------------------------------------
--  atlas -- atlas applications
-----------------------------------------------------------------------
--  Copyright (C) 2011 unknown
--  Written by unknown (unknown@company.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.IO_Exceptions;

with Util.Log.Loggers;
with Util.Properties;

with ASF.Applications;
with ASF.Applications.Main;
with ASF.Applications.Main.Configs;
with AWA.Applications.Factory;

--  with Atlas.XXX.Module;
package body Atlas.Applications is

   use AWA.Applications;

   Log     : constant Util.Log.Loggers.Logger := Util.Log.Loggers.Create ("Atlas");

   --  ------------------------------
   --  Initialize the application:
   --

   --
Register the servlets and filters.
   --
Register the application modules.
   --
Define the servlet and filter mappings.
   --

   --  ------------------------------
   procedure Initialize (App : in Application_Access) is
      Fact  : AWA.Applications.Factory.Application_Factory;
      C     : ASF.Applications.Config;
   begin
      App.Self := App;
      begin
         C.Load_Properties ("atlas.properties");
         Util.Log.Loggers.Initialize (Util.Properties.Manager (C));

      exception
         when Ada.IO_Exceptions.Name_Error =>
            Log.Error ("Cannot read application configuration file {0}", CONFIG_PATH);
      end;
      App.Initialize (C, Fact);

      App.Set_Global ("contextPath", CONTEXT_PATH);
   end Initialize;

   --  ------------------------------
   --  Initialize the servlets provided by the application.
   --  This procedure is called by Initialize.
   --  It should register the application servlets.
   --  ------------------------------
   overriding
   procedure Initialize_Servlets (App : in out Application) is
   begin
      Log.Info ("Initializing application servlets...");

      AWA.Applications.Application (App).Initialize_Servlets;
      App.Add_Servlet (Name => "faces", Server => App.Self.Faces'Access);
      App.Add_Servlet (Name => "files", Server => App.Self.Files'Access);
      App.Add_Servlet (Name => "ajax", Server => App.Self.Ajax'Access);
      App.Add_Servlet (Name => "measures", Server => App.Self.Measures'Access);
      App.Add_Servlet (Name => "auth", Server => App.Self.Auth'Access);
      App.Add_Servlet (Name => "verify-auth", Server => App.Self.Verify_Auth'Access);
   end Initialize_Servlets;

   --  ------------------------------
   --  Initialize the filters provided by the application.
   --  This procedure is called by Initialize.
   --  It should register the application filters.
   --  ------------------------------
   overriding
   procedure Initialize_Filters (App : in out Application) is
   begin
      Log.Info ("Initializing application filters...");

      AWA.Applications.Application (App).Initialize_Filters;
      App.Add_Filter (Name => "dump", Filter => App.Dump'Access);
      App.Add_Filter (Name => "measures", Filter => App.Measures'Access);
      App.Add_Filter (Name => "service", Filter => App.Service_Filter'Access);
   end Initialize_Filters;

   --  ------------------------------
   --  Initialize the AWA modules provided by the application.
   --  This procedure is called by Initialize.
   --  It should register the modules used by the application.
   --  ------------------------------
   overriding
   procedure Initialize_Modules (App : in out Application) is
   begin
      Log.Info ("Initializing application modules...");
      ASF.Applications.Main.Configs.Read_Configuration (App, "web/WEB-INF/web.xml");

      Register (App    => App.Self.all'Access,
                Name   => AWA.Users.Module.NAME,
                URI    => "user",
                Module => App.User_Module'Access);

      Register (App    => App.Self.all'Access,
                Name   => "workspaces",
                URI    => "workspaces",
                Module => App.Workspace_Module'Access);

      Register (App    => App.Self.all'Access,
                Name   => AWA.Mail.Module.NAME,
                URI    => "mail",
                Module => App.Mail_Module'Access);

      Register (App    => App.Self.all'Access,
                Name   => AWA.Storages.Modules.NAME,
                URI    => "storages",
                Module => App.Storage_Module'Access);

      Register (App    => App.Self.all'Access,
                Name   => AWA.Blogs.Module.NAME,
                URI    => "blogs",
                Module => App.Blog_Module'Access);

      Register (App    => App.Self.all'Access,
                Name   => AWA.Comments.Module.NAME,
                URI    => "comments",
                Module => App.Comment_Module'Access);
   end Initialize_Modules;

end Atlas.Applications;

Fix initialization of Atlas

Fix initialization of Atlas


-----------------------------------------------------------------------
--  awa-blogs-module -- Blog and post management module
--  Copyright (C) 2011, 2012, 2013, 2014 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 ASF.Applications;

with ADO;
with AWA.Modules;
with AWA.Blogs.Models;

with Security.Permissions;

--  == Integration ==
--  The <tt>Blog_Module</tt> manages the creation, update, removal of blog posts in an application.
--  It provides operations that are used by the blog beans or other services to create and update
--  posts.  An instance of the <tt>Blog_Module</tt> must be declared and registered in the
--  AWA application.  The module instance can be defined as follows:
--
--    type Application is new AWA.Applications.Application with record
--       Blog_Module : aliased AWA.Blogs.Modules.Blog_Module;
--    end record;
--
--  And registered in the `Initialize_Modules` procedure by using:
--
--    Register (App    => App.Self.all'Access,
--              Name   => AWA.Blogs.Modules.NAME,
--              URI    => "blogs",
--              Module => App.Blog_Module'Access);
--
package AWA.Blogs.Modules is

   NAME : constant String := "blogs";

   --  Define the permissions.
   package ACL_Create_Blog is new Security.Permissions.Definition ("blog-create");
   package ACL_Delete_Blog is new Security.Permissions.Definition ("blog-delete");
   package ACL_Create_Post is new Security.Permissions.Definition ("blog-create-post");
   package ACL_Delete_Post is new Security.Permissions.Definition ("blog-delete-post");
   package ACL_Update_Post is new Security.Permissions.Definition ("blog-update-post");

   Not_Found : exception;

   type Blog_Module is new AWA.Modules.Module with private;
   type Blog_Module_Access is access all Blog_Module'Class;

   --  Initialize the blog module.
   overriding
   procedure Initialize (Plugin : in out Blog_Module;
                         App    : in AWA.Modules.Application_Access;
                         Props  : in ASF.Applications.Config);

   --  Get the blog module instance associated with the current application.
   function Get_Blog_Module return Blog_Module_Access;

   --  Create a new blog for the user workspace.
   procedure Create_Blog (Model        : in Blog_Module;
                          Workspace_Id : in ADO.Identifier;
                          Title        : in String;
                          Result       : out ADO.Identifier);

   --  Create a new post associated with the given blog identifier.
   procedure Create_Post (Model   : in Blog_Module;
                          Blog_Id : in ADO.Identifier;
                          Title   : in String;
                          URI     : in String;
                          Text    : in String;
                          Comment : in Boolean;
                          Status  : in AWA.Blogs.Models.Post_Status_Type;
                          Result  : out ADO.Identifier);

   --  Update the post title and text associated with the blog post identified by <b>Post</b>.
   procedure Update_Post (Model   : in Blog_Module;
                          Post_Id : in ADO.Identifier;
                          Title   : in String;
                          URI     : in String;
                          Text    : in String;
                          Comment : in Boolean;
                          Status  : in AWA.Blogs.Models.Post_Status_Type);

   --  Delete the post identified by the given identifier.
   procedure Delete_Post (Model   : in Blog_Module;
                          Post_Id : in ADO.Identifier);

private

   type Blog_Module is new AWA.Modules.Module with null record;

end AWA.Blogs.Modules;

-----------------------------------------------------------------------
--  awa-blogs-module -- Blog and post management module
--  Copyright (C) 2011, 2012, 2013, 2014, 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 ASF.Applications;

with ADO;
with AWA.Modules;
with AWA.Blogs.Models;
with AWA.Counters.Definition;

with Security.Permissions;

--  == Integration ==
--  The <tt>Blog_Module</tt> manages the creation, update, removal of blog posts in an application.
--  It provides operations that are used by the blog beans or other services to create and update
--  posts.  An instance of the <tt>Blog_Module</tt> must be declared and registered in the
--  AWA application.  The module instance can be defined as follows:
--
--    type Application is new AWA.Applications.Application with record
--       Blog_Module : aliased AWA.Blogs.Modules.Blog_Module;
--    end record;
--
--  And registered in the `Initialize_Modules` procedure by using:
--
--    Register (App    => App.Self.all'Access,
--              Name   => AWA.Blogs.Modules.NAME,
--              URI    => "blogs",
--              Module => App.Blog_Module'Access);
--
package AWA.Blogs.Modules is

   NAME : constant String := "blogs";

   --  Define the permissions.
   package ACL_Create_Blog is new Security.Permissions.Definition ("blog-create");
   package ACL_Delete_Blog is new Security.Permissions.Definition ("blog-delete");
   package ACL_Create_Post is new Security.Permissions.Definition ("blog-create-post");
   package ACL_Delete_Post is new Security.Permissions.Definition ("blog-delete-post");
   package ACL_Update_Post is new Security.Permissions.Definition ("blog-update-post");

   --  Define the read post counter.
   package Read_Counter is new AWA.Counters.Definition (Models.POST_TABLE, "read_count");

   Not_Found : exception;

   type Blog_Module is new AWA.Modules.Module with private;
   type Blog_Module_Access is access all Blog_Module'Class;

   --  Initialize the blog module.
   overriding
   procedure Initialize (Plugin : in out Blog_Module;
                         App    : in AWA.Modules.Application_Access;
                         Props  : in ASF.Applications.Config);

   --  Get the blog module instance associated with the current application.
   function Get_Blog_Module return Blog_Module_Access;

   --  Create a new blog for the user workspace.
   procedure Create_Blog (Model        : in Blog_Module;
                          Workspace_Id : in ADO.Identifier;
                          Title        : in String;
                          Result       : out ADO.Identifier);

   --  Create a new post associated with the given blog identifier.
   procedure Create_Post (Model   : in Blog_Module;
                          Blog_Id : in ADO.Identifier;
                          Title   : in String;
                          URI     : in String;
                          Text    : in String;
                          Comment : in Boolean;
                          Status  : in AWA.Blogs.Models.Post_Status_Type;
                          Result  : out ADO.Identifier);

   --  Update the post title and text associated with the blog post identified by <b>Post</b>.
   procedure Update_Post (Model   : in Blog_Module;
                          Post_Id : in ADO.Identifier;
                          Title   : in String;
                          URI     : in String;
                          Text    : in String;
                          Comment : in Boolean;
                          Status  : in AWA.Blogs.Models.Post_Status_Type);

   --  Delete the post identified by the given identifier.
   procedure Delete_Post (Model   : in Blog_Module;
                          Post_Id : in ADO.Identifier);

private

   type Blog_Module is new AWA.Modules.Module with null record;

end AWA.Blogs.Modules;

Define the Read_Counter package for the definition of post read counter