--------------------------------------------------------------------------------
--                                                                            --
-- 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.Memory;     use RASCAL.Memory;
with RASCAL.OS;         use RASCAL.OS;

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


package body RASCAL.ToolboxColourDBox is

   -- SWIs
   Toolbox_ObjectMiscOp         : constant := 16#44EC6#;

   ColourDbox_ClassSWI          : constant := 16#829C0#;
   ColourDbox_PostFilter        : constant := 16#829C1#;
   ColourDbox_PreFilter         : constant := 16#829C2#;

   -- Reason codes
   ColourDbox_GetWimpHandle     : constant := 16#0#;
   ColourDbox_GetDialogueHandle : constant := 16#1#;
   ColourDbox_SetColour         : constant := 16#2#;
   ColourDbox_GetColour         : constant := 16#3#;
   ColourDbox_SetColourModel    : constant := 16#4#;
   ColourDbox_GetColourModel    : constant := 16#5#;
   ColourDbox_SetNoneAvailable  : constant := 16#6#;
   ColourDbox_GetNoneAvailable  : constant := 16#7#;

   --

   function Get_Colour (ColourDbox : in Object_ID;
                        Flags      : in System.Unsigned_Types.Unsigned := 0) return Colour_Type is

      Register             : aliased Kernel.swi_regs;
      Error                : oserror_access;
      Buffer_Size          : System.Unsigned_Types.Unsigned;
   begin
      Register.R(0) := int(Unsigned_to_Int(Flags));
      Register.R(1) := int(ColourDbox);
      Register.R(2) := ColourDbox_GetColour;
      Register.R(3) := 0;
      Register.R(4) := 0;
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

      Buffer_Size := Int_To_Unsigned ( Integer (Register.R(4)));

      declare
         Colour : Colour_Type(Buffer_Size);
      begin
         Register.R(0) := int(Unsigned_to_Int(Flags));
         Register.R(1) := int(ColourDbox);
         Register.R(2) := ColourDbox_GetColour;
         Register.R(3) := Adr_To_Int(Colour'Address);
         Register.R(4) := int(Unsigned_to_Int(Buffer_Size));
         Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);
         
         if Error /= null then
            pragma Debug(Report("ToolboxColourDbox.Get_Colour(II): " & To_Ada(Error.ErrMess)));
            OS.Raise_Error(Error);
         end if;
         return Colour;
      end;
   end Get_Colour;

   --

   function Get_ColourModel (ColourDbox : in Object_ID;
                             Flags      : in System.Unsigned_Types.Unsigned := 0) return Colour_Model_Type is

      Register             : aliased Kernel.swi_regs;
      Error                : oserror_access;
      Buffer_Size          : System.Unsigned_Types.Unsigned;
   begin
      Register.R(0) := int(Unsigned_to_Int(Flags));
      Register.R(1) := int(ColourDbox);
      Register.R(2) := ColourDbox_GetColourModel;
      Register.R(3) := 0;
      Register.R(4) := 0;
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

      Buffer_Size := Int_To_Unsigned ( Integer (Register.R(4)));

      declare
         Model : Colour_Model_Type(Buffer_Size);
      begin
         Register.R(0) := int(Unsigned_to_Int(Flags));
         Register.R(1) := int(ColourDbox);
         Register.R(2) := ColourDbox_GetColourModel;
         Register.R(3) := Adr_To_Int(Model'Address);
         Register.R(4) := int(Unsigned_to_Int(Buffer_Size));
         Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);
         
         if Error /= null then
            pragma Debug(Report("ToolboxColourDbox.Get_Model(II): " & To_Ada(Error.ErrMess)));
            OS.Raise_Error(Error);
         end if;
         return Model;
      end;
   end Get_ColourModel;

   --

   function Get_DialogueHandle (ColourDbox : in Object_ID;
                                Flags      : in System.Unsigned_Types.Unsigned := 0) return Wimp_Handle_Type is

      Register             : aliased Kernel.swi_regs;
      Error                : oserror_access;
   begin
      Register.R(0) := int(Unsigned_to_Int(Flags));
      Register.R(1) := int(ColourDbox);
      Register.R(2) := ColourDbox_GetDialogueHandle;
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

      if Error /= null then
         pragma Debug(Report("ToolboxColourDbox.Get_Dialogue_Handle: " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
      return Wimp_Handle_Type(Register.R(0));
   end Get_DialogueHandle;

   --

   function Get_NoneAvailable (ColourDbox : in Object_ID;
                               Flags      : in System.Unsigned_Types.Unsigned := 0) return boolean is

      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
   begin
      Register.R(0) := int(Unsigned_to_Int(Flags));
      Register.R(1) := int(ColourDbox);
      Register.R(2) := ColourDbox_GetNoneAvailable;
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

      if Error /= null then
         pragma Debug(Report("ToolboxColourDbox.Get_None_Available: " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
      return "And"(1,int_to_unsigned(integer(Register.R(0))))=1;
   end Get_NoneAvailable;

   --

   function Get_WimpHandle (ColourDbox : in Object_ID;
                            Flags      : in System.Unsigned_Types.Unsigned := 0) return Wimp_Handle_Type is

      Register             : aliased Kernel.swi_regs;
      Error                : oserror_access;
   begin
      Register.R(0) := int(Unsigned_to_Int(Flags));
      Register.R(1) := int(ColourDbox);
      Register.R(2) := ColourDbox_GetWimpHandle;
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

      return Wimp_Handle_Type(Register.R(0));

   end Get_WimpHandle;

   --

   procedure Set_Colour (ColourDbox : in Object_ID;
                         Colour     : in Colour_Type;
                         Flags      : in System.Unsigned_Types.Unsigned := 0) is

      Register             : aliased Kernel.swi_regs;
      Error                : oserror_access;
   begin
      Register.R(0) := int(Unsigned_to_Int(Flags));
      Register.R(1) := int(ColourDbox);
      Register.R(2) := ColourDbox_SetColour;
      Register.R(3) := Adr_To_Int(Colour'Address);
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

   --

   procedure Set_ColourModel (ColourDbox : in Object_ID;
                              Model      : in Colour_Model_Type;
                              Flags      : in System.Unsigned_Types.Unsigned := 0) is

      Register             : aliased Kernel.swi_regs;
      Error                : oserror_access;
   begin
      Register.R(0) := int(Unsigned_to_Int(Flags));
      Register.R(1) := int(ColourDbox);
      Register.R(2) := ColourDbox_SetColourModel;
      Register.R(3) := Adr_To_Int(Model'Address);
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

   --

   procedure Set_NoneAvailable (ColourDbox     : in Object_ID;
                                None_Available : in boolean;
                                Flags          : in System.Unsigned_Types.Unsigned := 0) is

      Register             : aliased Kernel.swi_regs;
      Error                : oserror_access;
   begin
      Register.R(0) := int(Unsigned_to_Int(Flags));
      Register.R(1) := int(ColourDbox);
      Register.R(2) := ColourDbox_SetNoneAvailable;
      Register.R(3) := boolean'Pos(None_Available);
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

   --

end RASCAL.ToolboxColourDbox;
