--------------------------------------------------------------------------------
--                                                                            --
-- 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    --
--                                                                            --
--------------------------------------------------------------------------------

-- $Author$
-- $Date$
-- $Revision$

with RASCAL.OS;
with RASCAL.Utility;    use RASCAL.Utility;
with RASCAL.Memory;     use RASCAL.Memory;

with Kernel;            use Kernel;
with Interfaces.C;      use Interfaces.C;


package body RASCAL.ToolboxDraggable is

   -- SWIs
   Toolbox_ObjectMiscOp : constant Interfaces.C.unsigned :=16#44EC6#;

   -- Reason codes
   Draggable_SetSprite  : constant := 16#280#;
   Draggable_GetSprite  : constant := 16#281#;
   Draggable_SetText    : constant := 16#282#;
   Draggable_GetText    : constant := 16#283#;
   Draggable_SetState   : constant := 16#284#;
   Draggable_GetState   : constant := 16#285#;

   --

   function Get_State (Draggable : in Object_ID;
                       Component : in Object_ID) return Draggable_State is

      Register       : aliased Kernel.swi_regs;
      Error          : oserror_access;
   begin
      Register.R(0) := int(0);
      Register.R(1) := int(Draggable);
      Register.R(2) := Draggable_GetState;
      Register.R(3) := int(Component);
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

      if Error /= null then
         pragma Debug(Report("ToolboxDraggable.Get_State: " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
      return Draggable_State'Val(integer(Register.R(0)));
   end Get_State;

   --

   function Get_Sprite (Draggable : in Object_ID;
                        Component : in Object_ID;
                        Flags   : in System.Unsigned_Types.Unsigned := 0) return String is

      Register       : aliased Kernel.swi_regs;
      Error          : oserror_access;
      Buffer_Size    : integer;
   begin
      Register.R(0) := int(Unsigned_to_Int(Flags));
      Register.R(1) := int(Draggable);
      Register.R(2) := Draggable_GetSprite;
      Register.R(3) := int(Component);
      Register.R(4) := 0;
      Register.R(5) := 0;
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

      if Error /= null then
         pragma Debug(Report("ToolboxDraggable.Get_Sprite(I): " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
      Buffer_Size := integer(Register.R(4)) + 1;
      declare
         Buffer : String(1..Buffer_Size);
      begin
         Register.R(0) := int(Unsigned_to_Int(Flags));
         Register.R(1) := int(Draggable);
         Register.R(2) := Draggable_GetSprite;
         Register.R(3) := int(Component);
         Register.R(4) := Adr_To_Int(Buffer'Address);
         Register.R(5) := int(Buffer_Size);
         Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

         if Error /= null then
            pragma Debug(Report("ToolboxDraggable.Get_Sprite(II): " & To_Ada(Error.ErrMess)));
            OS.Raise_Error(Error);
         end if;
         return MemoryToString(Buffer'Address);
      end;
   end Get_Sprite;
   
   --

   function Get_Text (Draggable : in Object_ID;
                      Component : in Object_ID;
                      Flags   : in System.Unsigned_Types.Unsigned := 0) return String is

      Register       : aliased Kernel.swi_regs;
      Error          : oserror_access;
      Buffer_Size    : integer;
   begin
      Register.R(0) := int(Unsigned_to_Int(Flags));
      Register.R(1) := int(Draggable);
      Register.R(2) := Draggable_GetText;
      Register.R(3) := int(Component);
      Register.R(4) := 0;
      Register.R(5) := 0;
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

      if Error /= null then
         pragma Debug(Report("ToolboxDraggable.Get_Text(I): " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
      Buffer_Size := integer(Register.R(4)) + 1;
      declare
         Buffer : String(1..Buffer_Size);
      begin
         Register.R(0) := int(Unsigned_to_Int(Flags));
         Register.R(1) := int(Draggable);
         Register.R(2) := Draggable_GetText;
         Register.R(3) := int(Component);
         Register.R(4) := Adr_To_Int(Buffer'Address);
         Register.R(5) := int(Buffer_Size);
         Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

         if Error /= null then
            pragma Debug(Report("ToolboxDraggable.Get_Text(II): " & To_Ada(Error.ErrMess)));
            OS.Raise_Error(Error);
         end if;
         return MemoryToString(Buffer'Address);
      end;
   end Get_Text;

   --

   procedure Set_State (Draggable : in Object_ID;
                        Component : in Object_ID;
                        State     : in Draggable_State;
                        Flags   : in System.Unsigned_Types.Unsigned := 0) is

      Register       : aliased Kernel.swi_regs;
      Error          : oserror_access;
   begin
      Register.R(0) := int(Flags);
      Register.R(1) := int(Draggable);
      Register.R(2) := Draggable_SetState;
      Register.R(3) := int(Component);
      Register.R(4) := int(Draggable_State'Pos(State));
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

      if Error /= null then
         pragma Debug(Report("ToolboxDraggable.Set_State: " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
   end Set_State;

   --

   procedure Set_Sprite (Draggable : in Object_ID;
                         Component : in Object_ID;
                         Sprite  : in string;
                         Flags   : in System.Unsigned_Types.Unsigned := 0) is

      Register       : aliased Kernel.swi_regs;
      Error          : oserror_access;
      Sprite_0       : string := Sprite & ASCII.NUL;
   begin
      Register.R(0) := int(Unsigned_to_Int(Flags));
      Register.R(1) := int(Draggable);
      Register.R(2) := Draggable_SetSprite;
      Register.R(3) := int(Component);
      Register.R(4) := Adr_To_Int(Sprite_0'Address);
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

      if Error /= null then
         pragma Debug(Report("ToolboxDraggable.Set_Sprite: " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
   end Set_Sprite;

   --

   procedure Set_Text (Draggable : in Object_ID;
                       Component : in Object_ID;
                       Text      : in string;
                       Flags     : in System.Unsigned_Types.Unsigned := 0) is

      Register       : aliased Kernel.swi_regs;
      Error          : oserror_access;
      Text_0         : string := Text & ASCII.NUL;
   begin
      Register.R(0) := int(Unsigned_to_Int(Flags));
      Register.R(1) := int(Draggable);
      Register.R(2) := Draggable_SetText;
      Register.R(3) := int(Component);
      Register.R(4) := Adr_To_Int(Text_0'Address);
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

      if Error /= null then
         pragma Debug(Report("ToolboxDraggable.Set_Text: " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
   end Set_Text;

   --

end RASCAL.ToolboxDraggable;
