-- $Date: 2004/02/14 09:46:15 $
-- $Revision: 1.10 $
-- $Author: jcrocholl $

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

with Score_Instruments.MusicXML; use Score_Instruments.MusicXML;
with Midi_Instruments.MusicXML; use Midi_Instruments.MusicXML;

with Measures; use Measures;
with Measures.MusicXML; use Measures.MusicXML;

package body Parts.MusicXML is

   -- Read score part data from an XML reader.
   function Read_Score_Part
     (XML : access XML_Reader-- Use this XML reader.
     return Part_Access        -- The newly created part.
   is
      Result : Part_Access;
   begin
      Assert_Attribute_Name(XML, "id");
      Read_Attribute_Value(XML);
      Result := Create(Get_Token(XML));
      Exit_Tag(XML);

      while Descend(XML) loop
         if Found(XML, "part-name") then
            Exit_Tag(XML);
            Set_Name(Result, Read_Data(XML));
         elsif Found(XML, "score-instrument") then
            Set_Score_Instrument(Result, Read_Score_Instrument(XML));
         elsif Found(XML, "midi-instrument") then
            Set_Midi_Instrument(Result, Read_Midi_Instrument(XML));
         else
            XML_Expect_Error(XML, "/score-part",
              "part-name" / "score-instrument" / "midi-instrument");
         end if;

         Exit_Element(XML);
      end loop;

      Exit_Tag(XML);
      return Result;
   end Read_Score_Part;

   -- Write score part data to an XML writer.
   procedure Write_Score_Part
     (XML  : access XML_Writer-- Use this XML writer.
      This : access Part)       -- Write information from this part.
   is
   begin
      Start_Element(XML, "score-part", "id", Get_Id(This));

      Write_Element(XML, "part-name", Get_Name(This));

      if Get_Score_Instrument(This) /= null then
         Write_Score_Instrument(XML, Get_Score_Instrument(This));
      end if;

      if Get_Midi_Instrument(This) /= null then
         Write_Midi_Instrument(XML, Get_Midi_Instrument(This));
      end if;

      Close_Element(XML, "score-part");
   end Write_Score_Part;

   -- Read some measures from an XML reader.
   procedure Read_Measures
     (XML  : access XML_Reader-- Use this XML reader.
      This : access Part) is    -- Add measures to this part.
   begin
      while Descend(XML) loop
         if Found(XML, "measure") then
            Add_Measure(This, Read_Measure(XML));
         else
            XML_Expect_Error(XML, "/part", "measure");
         end if;
      end loop;

      Exit_Tag(XML);
   end Read_Measures;

   -- Write a list of measures to an XML writer.
   procedure Write_Measures
     (XML  : access XML_Writer;   -- Use this XML writer.
      This : access Measure_List-- Write these measures.
   is
      use Parts.Measure_Lists;
      Measure : Measure_Access;
   begin
      Reset(This);
      while Next(This) loop
         Measure := Current(This);
         Write_Measure(XML, Measure);
      end loop;
   end Write_Measures;

   -- Read part data from an XML reader.
   procedure Read_Part
     (XML  : access XML_Reader-- Use this XML reader.
      This : access Part) is    -- Add data to this part.
   begin
      Assert_Tag_Name(XML, "part");
      Assert_Attribute_Name(XML, "id");
      Assert_Attribute_Value(XML, Get_Id(This));
      Exit_Tag(XML);
      Read_Measures(XML, This);
   end Read_Part;

   -- Write part data to an XML writer.
   procedure Write_Part
     (XML  : access XML_Writer-- Use this XML writer.
      This : access Part)       -- Write this part.
   is
   begin
      Start_Element(XML, "part", "id", Get_Id(This));
      Write_Measures(XML, Get_Measures(This));
      Close_Element(XML, "part");
   end Write_Part;

end Parts.MusicXML;