--------------------------------------------------------------------------------
--                                                                            --
-- 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 Kernel;            use Kernel;
with Interfaces.C;      use Interfaces.C;


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

package body RASCAL.Syslog is

   --

   procedure Log_Message(Name    : in String;
                         Message : in String;
                         Level   : in Syslog_Level_Type) is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
      Name_0   : String := Name & ASCII.NUL;
      Message_0: String := Message & ASCII.NUL;
   begin
      Register.R(0) := Adr_To_Int(Name_0'Address);
      Register.R(1) := Adr_To_Int(Message_0'Address);
      Register.R(2) := Int(Level);
      Error := Kernel.Swi (SysLog_LogMessage, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Log_Message " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
   end Log_Message;

   --

   procedure Log_Message(Handle  : in Syslog_Handle_Type;
                         Message : in String;
                         Level   : in Syslog_Level_Type) is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
      Message_0: String := Message & ASCII.NUL;
   begin
      Register.R(0) := Int(Integer(Handle));
      Register.R(1) := Adr_To_Int(Message_0'Address);
      Register.R(2) := Int(Level);
      Error := Kernel.Swi (SysLog_LogMessage, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Log_Message " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;

   end Log_Message;

   --

   function Get_LogLevel(Name : in String) return Integer is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
      Name_0   : String := Name & ASCII.NUL;
   begin
      Register.R(0) := Adr_To_Int(Name_0'Address);
      Error := Kernel.Swi (SysLog_GetLogLevel, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Get_LogLevel " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;

      return Integer(Register.R(0));
   end Get_LogLevel;

   --

   function Get_LogLevel(Handle : in Syslog_Handle_Type) return Integer is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
   begin
      Register.R(0) := Int(Integer(Handle));
      Error := Kernel.Swi (SysLog_GetLogLevel, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Get_LogLevel " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
      return Integer(Register.R(0));
   end Get_LogLevel;

   --

   procedure Flush_Log(Name : in String) is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
      Name_0   : String := Name & ASCII.NUL;
   begin
      Register.R(0) := Adr_To_Int(Name_0'Address);
      Error := Kernel.Swi (SysLog_FlushLog, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Flush_Log " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;

   end Flush_Log;

   --

   procedure Flush_Log(Handle : in Syslog_Handle_Type) is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
   begin
      Register.R(0) := Int(Integer(Handle));
      Error := Kernel.Swi (SysLog_FlushLog, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Flush_Log " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
   end Flush_Log;

   --

   procedure Set_LogLevel(Name  : in String;
                          Level : in Syslog_Level_Type) is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
      Name_0   : String := Name & ASCII.NUL;
   begin
      Register.R(0) := Adr_To_Int(Name_0'Address);
      Register.R(1) := Int(Level);
      Error := Kernel.Swi (SysLog_SetLogLevel, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Set_LogLevel " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
   end Set_LogLevel;

   --

   procedure Set_LogLevel(Handle : in Syslog_Handle_Type;
                          Level  : in Syslog_Level_Type) is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
   begin
      Register.R(0) := Int(Integer(Handle));
      Register.R(1) := Int(Level);
      Error := Kernel.Swi (SysLog_SetLogLevel, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Set_LogLevel " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;

   end Set_LogLevel;

   --

   procedure Log_UnStamped(Name    : in String;
                           Message : in String;
                           Level   : in Syslog_Level_Type) is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
      Name_0   : String := Name & ASCII.NUL;
      Message_0: String := Message & ASCII.NUL;
   begin
      Register.R(0) := Adr_To_Int(Name_0'Address);
      Register.R(1) := Adr_To_Int(Message_0'Address);
      Register.R(2) := Int(Level);
      Error := Kernel.Swi (SysLog_LogUnstamped, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Log_UnStamped " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;

   end Log_UnStamped;

   --

   procedure Log_UnStamped(Handle  : in Syslog_Handle_Type;
                           Message : in String;
                           Level   : in Syslog_Level_Type) is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
      Message_0: String := Message & ASCII.NUL;
   begin
      Register.R(0) := Int(Integer(Handle));
      Register.R(1) := Adr_To_Int(Message_0'Address);
      Register.R(2) := Int(Level);
      Error := Kernel.Swi (SysLog_LogUnstamped, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Log_UnStamped " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
   end Log_UnStamped;

   --

   procedure Increase_Indent(Name : in String) is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
      Name_0   : String := Name & ASCII.NUL;
   begin
      Register.R(0) := Adr_To_Int(Name_0'Address);
      Error := Kernel.Swi (SysLog_Indent, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Increase_Indent " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
   end Increase_Indent;

   --

   procedure Increase_Indent(Handle : in Syslog_Handle_Type) is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
   begin
      Register.R(0) := Int(Integer(Handle));
      Error := Kernel.Swi (SysLog_Indent, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Increase_Indent " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
   end Increase_Indent;

   --

   procedure Decrease_Indent(Name : in String) is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
      Name_0   : String := Name & ASCII.NUL;
   begin
      Register.R(0) := Adr_To_Int(Name_0'Address);
      Error := Kernel.Swi (SysLog_UnIndent, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Decrease_Indent " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
   end Decrease_Indent;

   --

   procedure Decrease_Indent(Handle : in Syslog_Handle_Type) is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
   begin
      Register.R(0) := Int(Integer(Handle));
      Error := Kernel.Swi (SysLog_UnIndent, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Decrease_Indent " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
   end Decrease_Indent;

   --

   procedure Reset_Indent(Name : in String) is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
      Name_0   : String := Name & ASCII.NUL;
   begin
      Register.R(0) := Adr_To_Int(Name_0'Address);
      Error := Kernel.Swi (SysLog_NoIndent, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Reset_Indent " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;

   end Reset_Indent;

   --

   procedure Reset_Indent(Handle : in Syslog_Handle_Type) is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
   begin
      Register.R(0) := Int(Integer(Handle));
      Error := Kernel.Swi (SysLog_NoIndent, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Reset_Indent " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
   end Reset_Indent;

   --

   function Open_Session(Name  : in String;
                         Level : in Syslog_Level_Type) return Syslog_Handle_Type is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
      Name_0   : String := Name & ASCII.NUL;
   begin
      Register.R(0) := Adr_To_Int(Name_0'Address);
      Register.R(1) := Int(Level);
      Error := Kernel.Swi (SysLog_OpenSessionLog, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Open_Session " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;

      return Syslog_Handle_Type(Integer(Register.R(0)));
   end Open_Session;

   --

   procedure Close_Session(Handle : in Syslog_Handle_Type) is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
   begin
      Register.R(0) := Int(Integer(Handle));
      Error := Kernel.Swi (SysLog_CloseSessionLog, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Close_Session " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
   end Close_Session;

   --

   procedure Log_Data(Name      : in String;
                      Level     : in Syslog_Level_Type;
                      Data      : in Integer;
                      Data_Size : in Integer;
                      Base      : in Address) is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
      Name_0   : String := Name & ASCII.NUL;
   begin
      Register.R(0) := Adr_To_Int(Name_0'Address);
      Register.R(1) := Int(Level);
      Register.R(2) := Int(Data);
      Register.R(3) := Int(Data_Size);
      Register.R(4) := Adr_To_Int(Base);
      Error := Kernel.Swi (SysLog_LogData, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Log_Data " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;

   end Log_Data;

   --

   procedure Log_Data(Handle    : in Syslog_Handle_Type;
                      Level     : in Syslog_Level_Type;
                      Data      : in Integer;
                      Data_Size : in Integer;
                      Base      : in Address) is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
   begin
      Register.R(0) := Int(Integer(Handle));
      Register.R(1) := Int(Level);
      Register.R(2) := Int(Data);
      Register.R(3) := Int(Data_Size);
      Register.R(4) := Adr_To_Int(Base);
      Error := Kernel.Swi (SysLog_LogData, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Log_Data " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
   end Log_Data;

   --

   function Read_ErrorMessage(Error_Number : in Integer) return String is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
   begin
      Register.R(0) := Int(Error_Number);
      Error := Kernel.Swi (SysLog_ReadErrorMessage, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Read_ErrorMessage " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
      return Memory.MemoryToString(Int_To_Adr(Register.R(0)));
   end Read_ErrorMessage;

   --

   procedure Log_Complete(Name : in String) is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
      Name_0   : String := Name & ASCII.NUL;
   begin
      Register.R(0) := Adr_To_Int(Name_0'Address);
      Error := Kernel.Swi (SysLog_LogComplete, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Log_Complete " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
   end Log_Complete;

   --

   procedure Log_Complete(Handle : in Syslog_Handle_Type) is
   
      Register : aliased Kernel.swi_regs;
      Error    : oserror_access;
   begin
      Register.R(0) := Int(Integer(Handle));
      Error := Kernel.Swi (SysLog_LogComplete, Register'Access, Register'Access);
 
      if Error /= null then
         pragma Debug(Report("Syslog:Log_Complete " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
   end Log_Complete;

   --

end RASCAL.Syslog;
