--------------------------------------------------------------------------------
--                                                                            --
-- 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.OS;

package body RASCAL.Text is

   Wimp_TextOp : constant := 16#400F9#;

   --

   procedure Set_Colour (Foreground : in Integer;
                         Background : in Integer) is

      Error      : OSError_Access;
      Register   : aliased Kernel.SWI_Regs;
   begin
      Register.R(0) := 0;
      Register.R(1) := int(Foreground);
      Register.R(2) := int(Background);

      Error := Kernel.SWI (Wimp_TextOp,Register'access,Register'access);
      if Error /= null then
         pragma Debug(Report("Text.Set_Colour: " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
   end Set_Colour;

   --

   function Get_Width (Text : in String) return Integer is

      Text_0     : String := Text & ASCII.NUL;
      Error      : OSError_Access;
      Register   : aliased Kernel.SWI_Regs;
   begin
      Register.R(0) := 1;
      Register.R(1) := Adr_To_Int(Text_0'Address);
      Register.R(2) := 0;

      Error := Kernel.SWI (Wimp_TextOp,Register'access,Register'access);
      if Error /= null then
         pragma Debug(Report("Text.Get_Width: " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
      return Integer(Register.R(0));
   end Get_Width;

   --

   procedure Plot (Text : in String;
                   X    : in Integer;
                   Y    : in Integer;
                   Flags: in Integer := 0) is

      Text_0     : String := Text & ASCII.NUL;
      Error      : OSError_Access;
      Register   : aliased Kernel.SWI_Regs;
   begin
      Register.R(0) := int(2+Flags);
      Register.R(1) := Adr_To_Int(Text_0'Address);
      Register.R(2) := -1;
      Register.R(3) := -1;
      Register.R(4) := int(X);
      Register.R(5) := int(Y);

      Error := Kernel.SWI (Wimp_TextOp,Register'access,Register'access);
      if Error /= null then
         pragma Debug(Report("Text.Plot: " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;
   end Plot;

   --

   function Truncate (Text : in String;
                      Width: in Integer) return String is

      Text_0     : String := Text & ASCII.NUL;
      Error      : OSError_Access;
      Register   : aliased Kernel.SWI_Regs;
      Buffer_Size: Integer;
   begin
      Register.R(0) := 4;
      Register.R(1) := Adr_To_Int(Text_0'Address);
      Register.R(2) := 0;
      Register.R(3) := 0;
      Register.R(4) := int(Width);

      Error := Kernel.SWI (Wimp_TextOp,Register'access,Register'access);
      if Error /= null then
         pragma Debug(Report("Text.Truncate: " & To_Ada(Error.ErrMess)));
         OS.Raise_Error(Error);
      end if;

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

      declare
         Buffer : String(1..Buffer_Size);
      begin
         Register.R(0) := 4;
         Register.R(1) := Adr_To_Int(Text_0'Address);
         Register.R(2) := Adr_To_Int(Buffer'Address);
         Register.R(3) := int(Buffer_Size);
         Register.R(4) := int(Width);
   
         Error := Kernel.SWI (Wimp_TextOp,Register'access,Register'access);
         if Error /= null then
            pragma Debug(Report("Text.Truncate II: " & To_Ada(Error.ErrMess)));
            OS.Raise_Error(Error);
         end if;
         return Buffer;
      end;
   end Truncate;

   --

   function Get_SplitPoint (Text  : in String;
                            Width : in Integer;
                            Split : in Character) return Integer is

      Text_0     : String := Text & ASCII.NUL;                      
      Error      : OSError_Access;
      Register   : aliased Kernel.SWI_Regs;
   begin
      Register.R(0) := 3;
      Register.R(1) := Adr_To_Int(Text_0'Address);
      Register.R(2) := int(Width);
      Register.R(3) := int(Character'Pos(Split));
      Error := Kernel.SWI (Wimp_TextOp,Register'access,Register'access);

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

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

   --
    
end RASCAL.Text;
