--------------------------------------------------------------------------------
--                                                                            --
-- 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 Kernel;            use Kernel;

package body RASCAL.ToolboxSaveAs is

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

   SaveAs_PostFilter         : constant := 16#82BC1#;
   SaveAs_PreFilter          : constant := 16#82BC2#;

   -- Reason Codes
   SaveAs_GetWindowID        : constant := 16#0#;
   SaveAs_SetTitle           : constant := 16#1#;
   SaveAs_GetTitle           : constant := 16#2#;
   SaveAs_SetFileName        : constant := 16#3#;
   SaveAs_GetFileName        : constant := 16#4#;
   SaveAs_SetFileType        : constant := 16#5#;
   SaveAs_GetFileType        : constant := 16#6#;
   SaveAs_SetFileSize        : constant := 16#7#;
   SaveAs_GetFileSize        : constant := 16#8#;
   SaveAs_SelectionAvailable : constant := 16#9#;
   SaveAs_SetDataAddress     : constant := 16#A#;
   SaveAs_BufferFilled       : constant := 16#B#;
   SaveAs_FileSaveCompleted  : constant := 16#C#;

   --

   function Get_Window_ID (SaveAs : in 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(SaveAs);
      Register.R(2) := SaveAs_GetWindowID;
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

      if Error /= null then
         pragma Debug(Report("ToolboxSaveAs.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 (SaveAs : 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(SaveAs);
      Register.R(2) := SaveAs_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("ToolboxSaveAs.Get_Title: " & 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(SaveAs);
         Register.R(2) := SaveAs_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("ToolboxSaveAs.Get_Title: " & To_Ada(Error.ErrMess)));
            OS.Raise_Error(Error);
         end if;
         return MemoryToString(Buffer'Address);
      end;
   end Get_Title;

   --

   procedure Set_Title (SaveAs : in Object_ID;
                        Title  : in string;
                        Flags  : in System.Unsigned_Types.Unsigned := 0) is

      Register     : aliased Kernel.swi_regs;
      Error        : oserror_access;
      Title_0      : string := Title & ASCII.NUL;
   begin
      Register.R(0) := int(Unsigned_to_Int(Flags));
      Register.R(1) := int(SaveAs);
      Register.R(2) := SaveAs_SetTitle;
      Register.R(3) := Adr_To_Int(Title_0'Address);
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

   --

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

      if Error /= null then
         pragma Debug(Report("ToolboxSaveAs.Get_FileName: " & 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(SaveAs);
         Register.R(2) := SaveAs_GetFileName;
         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("ToolboxSaveAs.Get_FileName: " & To_Ada(Error.ErrMess)));
            OS.Raise_Error(Error);
         end if;
         return MemoryToString(Buffer'Address);
      end;
   end Get_FileName;

   --

   procedure Set_FileName (SaveAs   : in Object_ID;
                           FileName : in string;
                           Flags    : in System.Unsigned_Types.Unsigned := 0) is

      Register      : aliased Kernel.swi_regs;
      Error         : oserror_access;
      FileName_0    : string := FileName & ASCII.NUL;
   begin
      Register.R(0) := int(Unsigned_to_Int(Flags));
      Register.R(1) := int(SaveAs);
      Register.R(2) := SaveAs_SetFileName;
      Register.R(3) := Adr_To_Int(FileName_0'Address);
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

   --

   function Get_File_Size (SaveAs : in 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(SaveAs);
      Register.R(2) := SaveAs_GetFileSize;
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

   --

   procedure Set_File_Size (SaveAs    : in Object_ID;
                            File_Size : 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(SaveAs);
      Register.R(2) := SaveAs_SetFileSize;
      Register.R(3) := int(File_Size);
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

   --

   function Get_File_Type (SaveAs : in 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(SaveAs);
      Register.R(2) := SaveAs_GetFileType;
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

   --

   procedure Set_File_Type (SaveAs    : in Object_ID;
                            File_Type : 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(SaveAs);
      Register.R(2) := SaveAs_SetFileType;
      Register.R(3) := int(File_Type);
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

   --

   procedure Save_Completed (SaveAs   : in Object_ID;
                             FileName : in string;
                             Flags    : in System.Unsigned_Types.Unsigned := 1) is

      Register             : aliased Kernel.swi_regs;
      Error                : oserror_access;
      FileName_0           : string := FileName & ASCII.NUL;
   begin
      Register.R(0) := int(Unsigned_to_Int(Flags));
      Register.R(1) := int(SaveAs);
      Register.R(2) := SaveAs_FileSaveCompleted;
      Register.R(3) := Adr_To_Int(FileName_0'Address);
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

   --

   procedure Set_Data_Address (SaveAs         : in Object_ID;
                               Data           : in Address;
                               Data_Size      : in integer;
                               Selection      : in Address;
                               Selection_Size : 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(SaveAs);
      Register.R(2) := SaveAs_SetDataAddress;
      Register.R(3) := Adr_To_Int(Data);
      Register.R(4) := int(Data_Size);
      Register.R(5) := Adr_To_Int(Selection);
      Register.R(6) := int(Selection_Size);

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

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

   --

   procedure Buffer_Filled  (SaveAs      : in Object_ID;
                             Buffer      : in Address;
                             Buffer_Size : 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(SaveAs);
      Register.R(2) := SaveAs_BufferFilled;
      Register.R(3) := Adr_To_Int(Buffer);
      Register.R(4) := int(Buffer_Size);
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

   --

   procedure Selection_Available  (SaveAs      : in Object_ID;
                                   Selection   : 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(SaveAs);
      Register.R(2) := SaveAs_SelectionAvailable;
      Register.R(3) := boolean'Pos(Selection);
      Error := Kernel.swi(Toolbox_ObjectMiscOp,Register'Access,Register'Access);

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

   --
   
end RASCAL.ToolboxSaveAs;
