--------------------------------------------------------------------------------
--                                                                            --
-- 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 Toolbox Task related types and methods.
-- $Author$
-- $Date$
-- $Revision$

with Interfaces.C;              use Interfaces.C;
with System.Storage_Elements;   use System.Storage_Elements;
with Ada.Strings.Unbounded;     use Ada.Strings.Unbounded;
with Ada.Strings;               use Ada.Strings;
with Ada.Strings.Fixed;         use Ada.Strings.Fixed;
with Ada.Strings.Maps;          use Ada.Strings.Maps;
with Ada.Strings.Maps.Constants;use Ada.Strings.Maps.Constants;
with Ada.Characters.Handling;   use Ada.Characters.Handling;

with Kernel;                    use Kernel;
                                
with RASCAL.OS;                 use RASCAL.OS;
with RASCAL.Error;              use RASCAL.Error;
with RASCAL.Toolbox;            use RASCAL.Toolbox;
with RASCAL.Utility;            use RASCAL.Utility;

package RASCAL.ToolboxTask is

   Unknown_Deleted_Event     : Exception;
   Is_Toolbox_Event          : Exception;
   No_Toolbox_Res_Path       : Exception;
   After_Task_Init           : Exception;
      
   type ToolBox_Task_Type is private;
   type ToolBox_Task_Pointer is access all ToolBox_Task_Type;

   subtype Poll_Mask_Type    is unsigned;
   type Task_Status_Type     is new boolean;
   type Task_Handle_Type     is new integer;
   type Wimp_Version_Type    is new integer;
   
   --
   -- Initilise Toolbox task.
   --
   procedure Initialise (The : in Toolbox_Task_Pointer);

   --
   -- Start multitasking / polling.
   --
   procedure Poll (The : in Toolbox_Task_Pointer);

   --
   -- Make a single poll to ensure multitasking during calculations.
   --
   procedure Single_Poll (The : in Toolbox_Task_Pointer;
                          Mask: in Integer := 0);

   --
   -- Add a toolbox event listener.
   --
   procedure Add_Listener (The      : in ToolBox_Task_Pointer;
                           Listener : in Event_Pointer);

   --
   -- Remove event listener, only wimp and message events.
   --
   procedure Remove_Listener (The      : in Toolbox_Task_Pointer;
                              Listener : in Event_Pointer);

   --
   -- Returns Wimp version.
   --
   function Get_Wimp_Version (The : in Toolbox_Task_Pointer) return Wimp_Version_Type;

   --
   -- Returns Task handle.
   --
   function Get_Task_Handle (The : in Toolbox_Task_Pointer) return Task_Handle_Type;

   --
   -- Returns task name.
   --
   function Get_Name (The : in Toolbox_Task_Pointer) return String;

   --
   -- Returns Wimp block.
   --
   function Get_Wimp_Block (The : in Toolbox_Task_Pointer) return Wimp_Block_Pointer;

   --
   -- Returns task status.
   --
   function Get_Status (The : in Toolbox_Task_Pointer) return Task_Status_Type;

   --
   -- Returns the poll mask.
   --
   function Get_Poll_Mask (The : in Toolbox_Task_Pointer) return Poll_Mask_Type;

   --
   -- Gets the return time for Wimp_Poll_Idle
   --
   function Get_WakeUp_Time (The : in Toolbox_Task_Pointer) return Integer;

   --
   -- Returns list of messages.
   --
   function Get_Messages (The : in Toolbox_Task_Pointer) return Messages_List_Pointer;

   --
   -- Returns message block.
   --
   function Get_Message_Block (The : in Toolbox_Task_Pointer) return Messages_Handle_Type;

   --
   -- Returns error block.
   --
   function Get_Error (The : in Toolbox_Task_Pointer) return Error.Error_Pointer;

   --
   -- Returns the path of the toolbox resource file.
   --
   function Get_Resources_Path (The : in Toolbox_Task_Pointer) return String;

   --
   --
   --
   function Get_Self_Id (The : in Toolbox_Task_Pointer) return Object_ID;

   --
   --
   --
   function Get_Self_Component (The : in Toolbox_Task_Pointer) return Component_ID;

   --
   --
   --
   function Get_Parent_Id (The : in Toolbox_Task_Pointer) return Object_ID;

   --
   --
   --
   function Get_Parent_Component (The : in Toolbox_Task_Pointer) return Component_ID;

   --
   --
   --
   function Get_Ancestor_Id (The : in Toolbox_Task_Pointer) return Object_ID;

   --
   --
   --
   function Get_Ancestor_Component (The : in Toolbox_Task_Pointer) return Component_ID;
   
   --
   -- Returns the spritearea of the toolbox task.
   --
   function Get_Sprite_Area (The : in Toolbox_Task_Pointer) return System_Sprite_Pointer;


   --
   -- Sets the required Wimp version.
   --
   procedure Set_Wimp_Version (The : in Toolbox_Task_Pointer;
                               Nr  : in Wimp_Version_Type);

   --
   -- Sets the task handle.
   --
   procedure Set_Task_Handle (The      : in Toolbox_Task_Pointer;
                              Handle   : in Task_Handle_Type);

   --
   -- Sets the task name.
   --
   procedure Set_Name (The  : in Toolbox_Task_Pointer;
                       Name : in String);

   --
   -- Sets the task status.
   --
   procedure Set_Status (The    : in Toolbox_Task_Pointer;
                         Status : in Task_Status_Type);

   --
   -- Sets the poll mask.
   --
   procedure Set_Poll_Mask (The       : in Toolbox_Task_Pointer;
                            Poll_Mask : in Poll_Mask_Type);

   --
   -- Changes the poll mask.
   --
   procedure Change_Mask (The   : in Toolbox_Task_Pointer;
                          Value : in unsigned;
                          Set   : in Boolean := true);

   --
   -- Sets the return time for Wimp_Poll_Idle
   --
   procedure Set_WakeUp_Time (The  : in Toolbox_Task_Pointer;
                              Time : in Integer);

   --
   -- Sets the error block.
   --
   procedure Set_Error (The : in Toolbox_Task_Pointer;
                        E   : in Error_Pointer);

   --
   -- Defines the path of the toolbox resource file.
   --
   procedure Set_Resources_Path(The : in ToolBox_Task_Pointer;
                                Path: in String);

   --
   -- Sets the spritearea for the toolbox task.
   --
   procedure Set_Sprite_Area (The : in ToolBox_Task_Pointer;
                              Area: in System_Sprite_Pointer);

   --
   -- Writes the contents of the ID block to 'Reporter'.
   --
   procedure Report_ID_Block (The : in Toolbox_Task_Pointer);

   subtype Message_Pointer is Event_Pointer;
   
private

   --

   Start_HandlerArray_Size : constant Positive := 64;

   type Handler_Array is array (Positive range <>) of Event_Pointer;
   type HandlerArray_Pointer is access Handler_Array;

   type HandlerArray_Header is
   record
   Event_Code     : integer  := -1;       
   Current_Index  : Positive := 1;
   Handlers       : HandlerArray_Pointer := new Handler_Array(1..Start_HandlerArray_Size);
   end record;
   type HandlerArrayHeader_Pointer is access HandlerArray_Header;


   Start_EventArray_Size : constant Positive := 64;

   type Event_Array is array (Positive range <>) of HandlerArrayHeader_Pointer;
   type EventArray_Pointer is access Event_Array;

   type EventArray_Header is
   record
   Current_Index  : Positive := 1;
   Events         : EventArray_Pointer := new Event_Array(1..Start_EventArray_Size);
   end record;

   type EventArrayHeader_Pointer is access EventArray_Header;
                  
   --

   Number_of_Toolbox_Events     : integer := 0;
   Max_Number_of_Toolbox_Events : integer := 64;
   type ToolBox_Event_List_Type is
        array (Natural range <>) of integer;
   type ToolBox_Event_List_Pointer is access ToolBox_Event_List_Type;

   --

   type ToolBox_Task_Type is
   record
      WakeUpTime         : Integer                    := 0;
      Task_Handle        : Task_Handle_Type           := 0;
      Wimp_Nr            : Wimp_Version_Type          := 350;
      Continue           : Task_Status_Type           := false;
      Task_Name          : String(1..32)              := 32*(""&ASCII.NUL);
      Mask               : Poll_Mask_Type             := 2#00000000000000000011100101110011#;
      Wimp_Block         : Wimp_Block_Pointer         := new Wimp_Block_Type;
      Messages           : Messages_List_Pointer      := new Messages_List_Type;
      Events             : EventArrayHeader_Pointer   := new EventArray_Header;
      Msg_Events         : EventArrayHeader_Pointer   := new EventArray_Header;
      Msg_Block          : Messages_Handle_Type       := new Messages_Control_Block_Type;
      Error              : Error_Pointer              := new Error_Type;
      Deleted_Events     : HandlerArrayHeader_Pointer := new HandlerArray_Header;
      Res_Path           : Unbounded_String;
      TB_Wanted_Events   : ToolBox_Event_List_Pointer := new ToolBox_Event_List_Type(0..Max_Number_of_Toolbox_Events);
      TB_Block           : Toolbox_Id_Block_Pointer   := new ToolBox_Id_Block_Type;
      TB_Event_Handlers  : EventArrayHeader_Pointer   := new EventArray_Header;
      Sprite_Area        : System_Sprite_Pointer;
   end record;

   --

end RASCAL.ToolboxTask;
