--------------------------------------------------------------------------------
--                                                                            --
-- 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.ToolboxPrint is

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

   PrintDbox_ClassSWI       : constant := 16#82B00#;
   PrintDbox_PostFilter     : constant := 16#82B01#;
   PrintDbox_PreFilter      : constant := 16#82B02#;

   -- Reason codes
   PrintDbox_GetWindowId    : constant := 16#0#;
   PrintDbox_SetPageRange   : constant := 16#1#;
   PrintDbox_GetPageRange   : constant := 16#2#;
   PrintDbox_SetCopies      : constant := 16#3#;
   PrintDbox_GetCopies      : constant := 16#4#;
   PrintDbox_SetScale       : constant := 16#5#;
   PrintDbox_GetScale       : constant := 16#6#;
   PrintDbox_SetOrientation : constant := 16#7#;
   PrintDbox_GetOrientation : constant := 16#8#;
   PrintDbox_GetTitle       : constant := 16#9#;
   PrintDbox_SetDraft       : constant := 16#A#;
   PrintDbox_GetDraft       : constant := 16#B#;

   --

   function Get_Copies (Print : Object_ID;
                        Flags: in System.Unsigned_Types.Unsigned := 0) return integer is

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

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

   --

   function is_Draft (Print : 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(Print);
      Register.R(2) := PrintDbox_GetDraft;
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

      if integer(Register.R(0)) = 0 then
         return false;
      else
         return true;
      end if;
   end Is_Draft;

   --

   function Is_Upright (Print : 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(Print);
      Register.R(2) := PrintDbox_GetOrientation;
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

      if integer(Register.R(0)) = 0 then
         return true;
      else
         return false;
      end if;
   end Is_Upright;

   --

   procedure Get_Page_Range (Print      : in Object_ID;
                             Start_Page : out integer;
                             End_Page   : out integer;
                             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(Print);
      Register.R(2) := PrintDbox_GetPageRange;
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

      Start_Page := integer(Register.R(0));
      End_Page   := integer(Register.R(1));
   end Get_Page_Range;

   --

   function Get_Scale (Print : Object_ID;
                       Flags: in System.Unsigned_Types.Unsigned := 0) return integer is

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

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

   --

   function Get_Window_ID (Print : Object_ID;
                           Flags: in System.Unsigned_Types.Unsigned := 0) return Object_ID is

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

      if Error /= null then
         pragma Debug(Report("ToolboxPrint.Get_Window_ID: " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
      return Object_ID(Register.R(0));
   end Get_Window_ID;
   
   --

   function Get_Title (Print : 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(Print);
      Register.R(2) := PrintDbox_GetTitle;
      Register.R(3) := 0;
      Register.R(4) := 0;
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

      if Error /= null then
         pragma Debug(Report("ToolboxPrint.Get_Title(I): " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
      Buffer_Size := integer(Register.R(4));

      declare
         Buffer : string(1..Buffer_Size);
      begin
         Register.R(0) := int(Unsigned_to_Int(Flags));
         Register.R(1) := int(Print);
         Register.R(2) := PrintDbox_GetTitle;
         Register.R(3) := Adr_To_Int(Buffer'Address);
         Register.R(4) := int(Buffer_Size);
         Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

   --

   procedure Set_Copies (Print : Object_ID;
                         Copies: in integer;
                         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(Print);
      Register.R(2) := PrintDbox_SetCopies;
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

   --

   procedure Set_Draft (Print : Object_ID;
                        Draft : 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(Print);
      Register.R(2) := PrintDbox_SetDraft;
      Register.R(3) := int(boolean'Pos(Draft));
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

   --

   procedure Set_Orientation (Print    : Object_ID;
                              Sideways : 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(Print);
      Register.R(2) := PrintDbox_SetOrientation;
      Register.R(3) := boolean'Pos(Sideways);
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

   --

   procedure Set_Page_Range (Print      : in Object_ID;
                             Start_Page : integer;
                             End_Page   : integer;
                             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(Print);
      Register.R(2) := PrintDbox_SetPageRange;
      Register.R(3) := int(Start_Page);
      Register.R(4) := int(End_Page);
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

   --

   procedure Set_Scale (Print : Object_ID;
                        Scale: in integer;
                        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(Print);
      Register.R(2) := PrintDbox_SetScale;
      Register.R(3) := int(Scale);
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

   --

end RASCAL.ToolboxPrint;
