//  BMP
//  Copyright (C) 2005-2007 BMP development.
//
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License Version 2
//  as published by the Free Software Foundation.
//
//  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 General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
//  --
//
//  The BMPx project hereby grants permission for non-GPL compatible GStreamer
//  plugins to be used and distributed together with GStreamer and BMPx. This
//  permission is above and beyond the permissions granted by the GPL license
//  BMPx is covered by.

#ifndef BMP_LAST_FM_PARSERS_HH
#define BMP_LAST_FM_PARSERS_HH

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif //HAVE_CONFIG_H

#include "bmp/types/types-basic.hh"
#include "bmp/types/types-library.hh"
#include "bmp/types/types-lastfm.hh"

#include <vector>
#include <queue>
#include <exception>

#include <glibmm/markup.h>
#include <glibmm/ustring.h>

#define N_LQM         "lqm"
#define N_LQM_QUEUE   "lqm-queue"
#define N_LQM_TRACK   "lqm-track"

namespace Bmp
{
  namespace LastFM
  {
    class LqmParser
      : public Glib::Markup::Parser
    {
      public:

        LqmParser (LQM & q) : m_queue (q), m_state (0) {}
        virtual ~LqmParser () {}

        void check_sanity ();

      protected:

        virtual void
        on_start_element  (Glib::Markup::ParseContext & context,
                           Glib::ustring const&         name,
                           AttributeMap  const&         props);
        virtual void
        on_end_element    (Glib::Markup::ParseContext & context,
                           Glib::ustring const&         name);

      private:

        enum Element
        {
          E_NONE        = 0,
          E_LQM         = 1 << 0,
          E_QUEUE       = 1 << 1,
          E_TRACK       = 1 << 2,
        };

        LQM & m_queue;
        int m_state;
    };

    namespace WS
    {
      class UserParser
        : public Glib::Markup::Parser
      {
        public:
          UserParser (UserV & x) : m_users (x), m_state (0) {}
          virtual ~UserParser () {}
        protected:
          virtual void
          on_start_element  (Glib::Markup::ParseContext   &context,
                             Glib::ustring const          &element_name,
                             AttributeMap const           &attributes);
          virtual void
          on_end_element    (Glib::Markup::ParseContext   &context,
                             Glib::ustring const          &element_name);
          virtual void
          on_text	          (Glib::Markup::ParseContext   &context,
                             Glib::ustring const          &text);
        private:

          enum Element
          {
            E_NONE	= 0,
            E_USER  = 1 << 0,
            E_URL 	= 1 << 1,
            E_IMAGE = 1 << 2,
            E_MATCH = 1 << 3,
          };

          UserV & m_users;
          User    m_current;
          int     m_state;
      };

      class TagParser
        : public Glib::Markup::Parser
      {
        public:
          TagParser (TagV & x) : m_tags (x), m_state (0) {}
          virtual ~TagParser () {}
        protected:
          virtual void
          on_start_element  (Glib::Markup::ParseContext & context,
                             Glib::ustring const& element_name,
                             AttributeMap  const& attributes);
          virtual void
          on_end_element    (Glib::Markup::ParseContext & context,
                             Glib::ustring const& element_name);
          virtual void
          on_text	          (Glib::Markup::ParseContext & context,
                             Glib::ustring const& text);
        private:

          enum Element
          {
            E_NONE	= 0,
            E_TAG   = 1 << 0,
            E_NAME  = 1 << 1,
            E_COUNT = 1 << 2,
            E_URL   = 1 << 3,
          };

          TagV &  m_tags;
          Tag     m_current;
          int     m_state;
      };


      class ArtistParser
        : public Glib::Markup::Parser
      {
        public:
          ArtistParser (LastFMArtistV & x) : m_artists (x), m_state (0) {}
          virtual ~ArtistParser () {}
        protected:
          virtual void
          on_start_element  (Glib::Markup::ParseContext   &context,
                             Glib::ustring const          &element_name,
                             AttributeMap const           &attributes);
          virtual void
          on_end_element    (Glib::Markup::ParseContext   &context,
                             Glib::ustring const          &element_name);
          virtual void
          on_text	          (Glib::Markup::ParseContext   &context,
                             Glib::ustring const          &text);
        private:

          enum Element
          {
            E_NONE	      = 0,
            E_ARTIST      = 1 << 0,
            E_NAME        = 1 << 1,
            E_MBID        = 1 << 2,
            E_COUNT       = 1 << 3,
            E_RANK        = 1 << 4,
            E_URL         = 1 << 5,
            E_THUMBNAIL   = 1 << 6,
            E_IMAGE       = 1 << 7,
            E_IMAGE_SMALL = 1 << 8,
            E_MATCH       = 1 << 9,
            E_STREAMABLE  = 1 << 10
          };

          LastFMArtistV & m_artists;
          LastFMArtist    m_current;
          int             m_state;
      };

    } // namespace WS
  } // namespace LastFM
} // namespace Bmp

#endif // !BMP_LASTFM_PARSERS_HH
