-- $Date: 2004/02/23 08:40:10 $
-- $Revision: 1.2 $
-- $Author: jcrocholl $

with Readers; use Readers;
with Token_Readers; use Token_Readers;

with Writers; use Writers;
with Indent_Writers; use Indent_Writers;

with Real_Vectors; use Real_Vectors;
with Integer_Strings; use Integer_Strings;
with Messages; use Messages;

with Lines; use Lines;

package body Outlines.SVG is

   SVG_Error : exception;

   -- Read an outline from an XML reader.
   function Read
     (XML : access XML_Reader-- Use this reader.
     return Outline_Access     -- The newly created outline.
   is
      XS, YS : Real;
      X1, Y1 : Real;
      X2, Y2 : Real;
      X3, Y3 : Real;
      XE, YE : Real;
      Result : Outline_Access := Create;
   begin
      -- Debug("reading outline");
      Skip_Whitespace(XML);
      Assert_Char(XML, 'M');
      Skip_Whitespace(XML);

      XS := Read_Real(XML);
      YS := Read_Real(XML);
      XE := XS;
      YE := YS;

      loop
         if End_Of_File(XML) then
            Error(XML, "unexpected end of file");
            raise SVG_Error;
         end if;

         if Found_Char(XML, 'Z') or Found_Char(XML, 'M') then
            if XS /= XE or YS /= YE then
               Error(XML, "previous outline not closed");
               raise SVG_Error;
            end if;
            exit;
         end if;

         if Found_Char(XML, 'L') then
            Get(XML); Skip_Whitespace(XML);
            X1 := Read_Real(XML); Y1 := Read_Real(XML);
            Add_Straight(Result, (X1, Y1));
            XE := X1; YE := Y1;
         elsif Found_Char(XML, 'C') then
            Get(XML); Skip_Whitespace(XML);
            X1 := Read_Real(XML); Y1 := Read_Real(XML);
            X2 := Read_Real(XML); Y2 := Read_Real(XML);
            X3 := Read_Real(XML); Y3 := Read_Real(XML);
            Add_Cubic(Result, (X1, Y1), (X2, Y2), (X3, Y3));
            XE := X3; YE := Y3;
         else
            Expect_Error(XML, "" & Get_Char(XML),
              "Z" / "M" / "L" / "C");
         end if;
      end loop;

      return Result;
   end Read;

   -- Write an outline to an XML writer.
   procedure Write
     (XML       : access XML_Writer-- Use this writer.
      This      : access Outline;    -- Write this outline.
      Tolerance : in Real)           -- Tolerance level.
   is
      use Outlines.Line_Lists;
   begin
      Put_Line(XML, "M " & To_String(Last(This).To, Tolerance));
      Reset(This);
      while Line_Lists.Next(This) loop
         Put_Line(XML, To_SVG(Current(This), Tolerance));
         -- if Debug then
         -- <desc>Four separate rectangles</desc>
         -- <rect x="0.5cm" y="0.5cm" width="2cm" height="1cm"/>
         -- <rect x="0.5cm" y="2cm" width="1cm" height="1.5cm"/>
         -- <rect x="3cm" y="0.5cm" width="1.5cm" height="2cm"/>
         -- <rect x="3.5cm" y="3cm" width="1cm" height="0.5cm"/>

         -- <!-- Show outline of canvas using 'rect' element -->
         -- <rect x=".01cm" y=".01cm" width="4.98cm" height="3.98cm"
         -- fill="none" stroke="blue" stroke-width=".02cm" />

         --    Put_Line(File, Postscript(Current(This).To - (2.0, 2.0)) & " 4 4 rectfill");
         -- end if;
      end loop;
   end Write;

end Outlines.SVG;