--------------------------------------------------------------------------------
--                                                                            --
-- Copyright (C) 2004, RISC OS Ada Library (RASCAL) developers.               --
--                                                                            --
-- This library is free software; you can redistribute it and/or              --
-- modify it under the terms of the GNU Lesser General Public                 --
-- License as published by the Free Software Foundation; either               --
-- version 2.1 of the License, or (at your option) any later version.         --
--                                                                            --
-- This library is distributed in the hope that it will be useful,            --
-- but WITHOUT ANY WARRANTY; without even the implied warranty of             --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           --
-- Lesser General Public License for more details.                            --
--                                                                            --
-- You should have received a copy of the GNU Lesser General Public           --
-- License along with this library; if not, write to the Free Software        --
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA    --
--                                                                            --
--------------------------------------------------------------------------------

-- @brief Thin binding to OS_DynamicArea.
-- $Author$
-- $Date$
-- $Revision$

with RASCAL.Utility;             use RASCAL.Utility;
with RASCAL.Memory;              use RASCAL.Memory;
with System;                     use System;

with Ada.Strings.Unbounded;      use Ada.Strings.Unbounded;

package RASCAL.DynamicArea is

   Dynamic_Area_No_Buffer      : constant := 2#000010000#;
   Dynamic_Area_No_Cache       : constant := 2#000100000#;
   Dynamic_Area_Double_Mapped  : constant := 2#001000000#;
   Dynamic_Area_No_Drag        : constant := 2#010000000#;
   Dynamic_Area_Physical_Pages : constant := 2#100000000#;

   Default_Flags  : constant := Dynamic_Area_No_Cache +
                                Dynamic_Area_No_Buffer+
                                Dynamic_Area_No_Drag;

   Default_Max_Size : constant := 32*1024*1024;

   unable_to_delete_dynamic_area : exception;
   unable_to_resize_dynamic_area : exception;
   nonexisting_dynamic_area      : exception;

   type Dynamic_Area_Type is private;
   type Dynamic_Area_Ptr is access Dynamic_Area_Type;

   type DA_List_Type is array(Natural range <>) of Dynamic_Area_Type;

   OS_DynamicArea       : constant := 16#66#;
   OS_ChangeDynamicArea : constant := 16#2A#;
   OS_ReadDynamicArea   : constant := 16#5C#;

   --
   -- This creates a new dynamic area.
   --
   procedure Create (Area       : in out Dynamic_Area_Type;
                     Name       : in String;
                     Start_Size : in Integer := 0;
                     Max_Size   : in Integer := 32*1024*1024;
                     Flags      : in Integer := Default_Flags);

   --
   -- Removes a dynamic area.
   --
   procedure Remove (Area : in Dynamic_Area_Type);

   --
   -- Lets you enlarge or shrink the dynamic area.
   --
   procedure Resize (Area   : in out Dynamic_Area_Type;
                     Change : in Integer);

   --
   --
   --
   function Enumerate (area : in Integer) return Integer;


   --
   --
   --
   procedure Read (Area_nr      : in  Integer;
                   Base         : out Address;
                   Current_Size : out Integer;
                   Max_Size     : out Integer);

   --
   --
   --
   procedure Read_Detailed (Area_Nr       : in  Integer;
                            Current_Size  : out Integer;
                            Base          : out Address;
                            Flags         : out Integer;
                            Max_Size      : out Integer;
                            Name          : out Unbounded_String);

   --
   -- Returns true if there is a dynamic area with this name.
   --
   function Exists (Name : in String) return Boolean;

   --
   -- Returns true if there is an area with that area nr.
   --
   function Exists (Nr : in Integer) return Boolean;

   --
   -- Searches for a DA with the given name and returns the area nr.
   --Raises nonexisting_dynamic_area exception.
   --
   function Find_Nr (Name : in String) return Integer;

   --
   -- Returns how many dynamic areas currently exist.
   --
   function Get_Nr_Of_DAs return Natural;

   --
   -- Returns an array containg detailed information about every existing dynamic area.
   --
   function Get_DA_List return DA_List_Type;

   --
   -- Returns the area nr of the dynamic area.
   --
   function Get_Nr (Area : in Dynamic_Area_Type) return Integer;

   --
   -- Returns the max size of the dynamic area.
   --
   function Get_Max_Size (Area : in Dynamic_Area_Type) return Integer;

   --
   -- Returns the current size of the dynamic area.
   --
   function Get_Current_Size (Area : in Dynamic_Area_Type) return integer;

   --
   -- Returns the flag word of the dynamic area.
   --
   function Get_Flags (Area : in Dynamic_Area_Type) return integer;

   --
   -- Returns the base addresse of the dynamic area.
   --
   function Get_Base (Area : in Dynamic_Area_Type) return Address;

private
  
   type Dynamic_Area_Type is
   record
   Area_Nr        : Integer       := -1;
   Max_Size       : Integer       := Default_Max_Size;
   Current_Size   : Integer       := 0;
   Flags          : Integer       := Default_Flags;
   Base           : Address;
   Name           : Char_Array(1..31);
   end record;

end RASCAL.DynamicArea;
