--  Copyright (2008-2011) Cédric Coussinet (cedric.coussinet@nomoseed.net)
--
--  This program is free software: you can redistribute it and/or modify
--  it under the terms of the GNU Affero General Public License as published
--  by the Free Software Foundation, either version 3 of the License, or
--  (at your option) any later version.
--
--  This program 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 Affero General Public License for more details.

--  You should have received a copy of the GNU Affero General Public License
--  along with this program. If not, see <http://www.gnu.org/licenses/>

with Ada.Text_IO;

with Ada.IO_Exceptions;

package body Basic_Sax.File_Parser is

   procedure Parse (Handler   : in out Reader'Class;
                    File_Name : in String) is
      use Ada.Text_IO;
      use Ada.Strings.Unbounded;
      F      : File_Type;
      S      : String (1 .. Size_String_Max);
      C      : Character;
      I      : Positive;
      Marker : Unbounded_String;
      Atts   : Attributes;
   begin
      Open (F, In_File, File_Name);
      Get (F, C);
      if C /= '<' then
         raise SYNTAXE_ERROR;
      end if;
      loop
         if C = '<' then
            I := 1;
            loop
               Get (F, C);
               exit when C = '>' or C = ' ';
               S (I) := C;
               I := Positive'Succ (I);
            end loop;
            if S (1) /= '/' and S (1) /= '?' and S (1) /= '-' then
               Marker := To_Unbounded_String ( S (1 .. I - 1));
               Atts.Size := 0;
               if C = ' ' then
                  loop
                     loop
                        Get (F, C);
                        exit when C /= ' ';
                     end loop;
                     if C = '/' then
                        Get (F, C);
                     end if;
                     exit when C = '>';
                     I := 1;
                     loop
                        exit when C = '=';
                        S (I) := C;
                        I := Positive'Succ (I);
                        Get (F, C);
                     end loop;
                     Atts.Size := Natural'Succ (Atts.Size);
                     Atts.Tab (Atts.Size).Name := To_Unbounded_String (S (1 .. I - 1));
                     Get (F, C);
                     I := 1;
                     loop
                        Get (F, C);
                        exit when C = '"';
                        S (I) := C;
                        I := Positive'Succ (I);
                     end loop;
                     if I > 1 then
                        Atts.Tab (Atts.Size).Value := To_Unbounded_String (S (1 .. I - 1));
                     else
                        Atts.Tab (Atts.Size).Value := To_Unbounded_String ("");
                     end if;
                  end loop;
               end if;
               Start_Element (Handler, To_String (Marker), Atts);
               Get (F, C);
            elsif S (1) = '/' then
               End_Element (Handler, S (2 .. I - 1));
               Get (F, C);
            elsif C = ' ' then
               Get (F, C);
               while C /= '>' loop
                  Get (F, C);
               end loop;
            end if;
         else
            I := 1;
            loop
               S (I) := C;
               I := Positive'Succ (I);
               Get (F, C);
               exit when C = '<';
            end loop;
            Characters (Handler, S (1 .. I - 1));
         end if;
      end loop;
   exception
      when Ada.IO_Exceptions.End_Error =>
         Close (F);
      when Ada.IO_Exceptions.Name_Error =>
         Ada.Text_IO.Put_Line ("NAME_ERROR"&File_Name);
         raise FILE_NAME_ERROR;
   end Parse;

end Basic_Sax.File_Parser;
