--------------------------------------------------------------------------------
--                                                                            --
-- 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 RASCAL.WimpIcon;
with RASCAL.ToolboxWindow; use RASCAL.ToolboxWindow;
with RASCAL.ToolboxGadget; use RASCAL.ToolboxGadget;
with Kernel;               use Kernel;
with Interfaces.C;         use Interfaces.C;


package body RASCAL.ToolboxButton is

   package WimpIcon renames RASCAL.WimpIcon;

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

   -- Reason codes
   Button_GetFlags      : constant := 16#3C0#;
   Button_SetFlags      : constant := 16#3C1#;
   Button_SetValue      : constant := 16#3C2#;
   Button_GetValue      : constant := 16#3C3#;
   Button_SetValidation : constant := 16#3C4#;
   Button_GetValidation : constant := 16#3C5#;
   Button_SetFont       : constant := 16#3C6#;

   --

   function Get_Flags (Window    : in Object_ID;
                       Component : in Component_ID;
                       Flags     : in System.Unsigned_Types.Unsigned := 0) return System.Unsigned_Types.Unsigned is

      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
   begin
      Register.R(0) := int(Unsigned_to_Int(Flags));
      Register.R(1) := int(Window);
      Register.R(2) := Button_GetFlags;
      Register.R(3) := int(Component);
      Error := Kernel.Swi (Toolbox_ObjectMiscOp, Register'Access, Register'Access);

      if Error /= null then
         pragma Debug(Report("ToolboxButton.Get_Flags: " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
      return Int_To_Unsigned(integer(Register.R(0)));
   end Get_Flags;

   --

   function Get_Validation (Window    : in Object_ID;
                            Component : in Component_ID;
                            Flags     : in System.Unsigned_Types.Unsigned := 0) return String is

      Register    : aliased Kernel.swi_regs;
      Buffer_Size : integer := 0;
      Error       : oserror_access;
   begin
      Register.R(0) := int(Unsigned_to_Int(Flags));
      Register.R(1) := int(Window);
      Register.R(2) := Button_GetValidation;
      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("ToolboxButton.Get_Validation(I): " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;

      Buffer_Size := Integer(Register.R(5));

      declare
         Buffer : String(1..Buffer_Size);
      begin
         Register.R(0) := int(Unsigned_to_Int(Flags));
         Register.R(1) := int(Window);
         Register.R(2) := Button_GetValidation;
         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("ToolboxButton.Get_Validation(II): " & To_Ada(Error.ErrMess)));
            OS.Raise_Error(Error);
         end if;
         return MemoryToString(Buffer'Address);
      end;
   end Get_Validation;

   --

   function Get_Value (Window    : in Object_ID;
                       Component : in Component_ID;
                       Flags     : in System.Unsigned_Types.Unsigned := 0) return String is

      Register    : aliased Kernel.swi_regs;
      Buffer_Size : integer := 0;
      Error       : oserror_access;
   begin
      Register.R(0) := int(Unsigned_to_Int(Flags));
      Register.R(1) := int(Window);
      Register.R(2) := Button_GetValue;
      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("ToolboxButton.Get_Value(I): " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;

      Buffer_Size := Integer(Register.R(5));

      declare
         Buffer : String(1..Buffer_Size);
      begin
         Register.R(0) := int(Unsigned_to_Int(Flags));
         Register.R(1) := int(Window);
         Register.R(2) := Button_GetValue;
         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("ToolboxButton.Get_Value(II): " & To_Ada(Error.ErrMess)));
            OS.Raise_Error(Error);
         end if;
         return MemoryToString(Buffer'Address);
      end;
   end Get_Value;

   --

   procedure Set_Flags (Window    : in Object_ID;
                        Component : in Component_ID;
                        Clear     : in System.Unsigned_Types.Unsigned;
                        EOR       : in System.Unsigned_Types.Unsigned;
                        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(Window);
      Register.R(2) := Button_SetFlags;
      Register.R(3) := int(Component);
      Register.R(4) := int(Unsigned_to_Int(Clear));
      Register.R(5) := int(Unsigned_to_Int(EOR));

      Error := Kernel.Swi (Toolbox_ObjectMiscOp, Register'Access, Register'Access);

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

   --

   procedure Set_Font (Window       : in Object_ID;
                       Component    : in Component_ID;
                       Font         : in string;
                       Font_Width   : in integer;
                       Font_Height  : in integer;
                       Flags        : in System.Unsigned_Types.Unsigned := 0) is

      Register   : aliased Kernel.swi_regs;
      Error      : oserror_access;
      Null_Font  : string := Font & Character'Val(0);
   begin
      Register.R(0) := int(Unsigned_to_Int(Flags));
      Register.R(1) := int(Window);
      Register.R(2) := Button_SetFont;
      Register.R(3) := int(Component);
      Register.R(4) := Adr_To_Int(Null_Font'Address);
      Register.R(5) := int(Font_Width);
      Register.R(5) := int(Font_Height);
      Error := Kernel.Swi (Toolbox_ObjectMiscOp, Register'Access, Register'Access);

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

   --

   procedure Set_Validation (Window       : in Object_ID;
                             Component    : in Component_ID;
                             Validation   : in string;
                             Flags        : in System.Unsigned_Types.Unsigned := 0) is

      Register         : aliased Kernel.swi_regs;
      Error            : oserror_access;
      Validation_0     : string := Validation & ASCII.NUL;
   begin
      Register.R(0) := int(Unsigned_to_Int(Flags));
      Register.R(1) := int(Window);
      Register.R(2) := Button_SetValidation;
      Register.R(3) := int(Component);
      Register.R(4) := Adr_To_Int(Validation_0'Address);
      Error := Kernel.Swi (Toolbox_ObjectMiscOp, Register'Access, Register'Access);

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

   --

   procedure Set_Value (Window    : in Object_ID;
                        Component : in Component_ID;
                        New_Value : in String;
                        Flags     : in System.Unsigned_Types.Unsigned := 0) is

      Value_0  : String := New_Value & ASCII.NUL;
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
   begin
      Register.R(0) := int(Unsigned_to_Int(Flags));
      Register.R(1) := int(Window);
      Register.R(2) := 962;
      Register.R(3) := int(Component);
      Register.R(4) := Adr_To_Int(Value_0'Address);
      Error := Kernel.Swi (Toolbox_ObjectMiscOp, Register'Access, Register'Access);

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

   --

   function Get_Foreground (Window    : in Object_ID;
                            Component : in Component_ID;
                            Flags     : in System.Unsigned_Types.Unsigned := 0) return Wimp_Colour is

      Icons : Icon_List_Type   := Get_IconList(Window,Component);
      W     : Wimp_Handle_Type := Get_WimpHandle(Window);
      Colour: Wimp_Colour      := WimpIcon.Get_Foreground(W,Icons(Icons'First));
   begin
      return Colour;
   end Get_Foreground;

   --

   function Get_Background (Window    : in Object_ID;
                            Component : in Component_ID;
                            Flags     : in System.Unsigned_Types.Unsigned := 0) return Wimp_Colour is

      Icons : Icon_List_Type   := Get_IconList(Window,Component);
      W     : Wimp_Handle_Type := Get_WimpHandle(Window);
      Colour: Wimp_Colour      := WimpIcon.Get_Background(W,Icons(Icons'First));
   begin
      return Colour;
   end Get_Background;

   --

   procedure Set_background (Window    : in Object_ID;
                             Component : in Component_ID;
                             Colour    : in Wimp_Colour;
                             Flags     : in System.Unsigned_Types.Unsigned := 0) is

      Icons : Icon_List_Type   := Get_IconList(Window,Component);
      W     : Wimp_Handle_Type := Get_WimpHandle(Window);
   begin
      WimpIcon.Set_Background(W,Icons(Icons'First),Colour);
   end Set_Background;

   --

   procedure Set_Foreground (Window    : in Object_ID;
                             Component : in Component_ID;
                             Colour    : in Wimp_Colour;
                             Flags     : in System.Unsigned_Types.Unsigned := 0) is

      Icons : Icon_List_Type   := Get_IconList(Window,Component);
      W     : Wimp_Handle_Type := Get_WimpHandle(Window);
   begin
      WimpIcon.Set_Foreground(W,Icons(Icons'First),Colour);
   end Set_Foreground;

   --
   
end RASCAL.ToolboxButton;