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

with Interfaces.C;              use Interfaces.C;

with RASCAL.OS;                 use RASCAL.OS;
with RASCAL.Error;              use RASCAL.Error;

package RASCAL.WimpTask is

   Unknown_Deleted_Event     : Exception;
   Is_Toolbox_Event          : Exception;
   
   type Wimp_Task_Type      is private;
   type Wimp_Task_Pointer   is access Wimp_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;
   
   --
   -- Initialise Wimp task.
   --
   procedure Initialise (The : in out Wimp_Task_Pointer);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

   --
   -- Sets the error block.
   --
   procedure Set_Error (The : in Wimp_Task_Pointer;
                        E   : in Error_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;
                  
   --

   type Wimp_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)              := (1..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;
   end record;

   --

end RASCAL.WimpTask;
