//  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 as published by
//  the Free Software Foundation; either version 2 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 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.

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

#include <glibmm/ustring.h>

using namespace std;
using namespace Glib;

#include "parser/libxml2-sax-base.hh"
using Bmp::XPath;

#include "lastfm-tags-libxml2-sax.hh"

namespace
{
  struct LastFMTagParserContext : public ParseContextBase
  {
    Bmp::LastFM::TagV  & m_tags;
    Bmp::LastFM::Tag     m_tag;

    LastFMTagParserContext (Bmp::LastFM::TagV & tags) : m_tags (tags) {}
  };

  typedef std::map < ustring, ustring > ElementAttributes; 

#define DEFAULT_REFS \
  LastFMTagParserContext & context (static_cast<LastFMTagParserContext&>(_context));

  //////////////////////////////////////////////////////////////////////////////

  namespace Handlers
  {
    namespace Tag
    {
      HANDLER(tag)
      {
        DEFAULT_REFS
        context.m_tag = Bmp::LastFM::Tag();
      }
    }
  }

  namespace HandlersEnd
  {
    namespace Tag
    {
      HANDLER_END(tag)
      {
        DEFAULT_REFS
        context.m_tags.push_back (context.m_tag);
      }
    }
  }
 
  namespace HandlersText
  {
    namespace Tag
    {
      HANDLER_Text(name)
      {
        DEFAULT_REFS
        context.m_tag.name += text;
      }

      HANDLER_Text(count)
      {
        DEFAULT_REFS
        context.m_tag.count = g_ascii_strtoull (text.c_str(), NULL, 10); 
      }
 
      HANDLER_Text(url)
      {
        DEFAULT_REFS
        context.m_tag.url += text;
      }
    }
  }


  HandlerPair
  handlers_start[] = 
  {
    HandlerPair( XPath("toptags/tag"), 
      sigc::ptr_fun( &Handlers::Tag::tag))
  };

  HandlerEndPair
  handlers_end[] =
  {
    HandlerEndPair( XPath("toptags/tag"), 
        sigc::ptr_fun( &HandlersEnd::Tag::tag))
  };
 
  HandlerTextPair
  handlers_text[] = 
  {
      HandlerTextPair( XPath("toptags/tag/name"),
        sigc::ptr_fun( &HandlersText::Tag::name)),

      HandlerTextPair( XPath("toptags/tag/count"),
        sigc::ptr_fun( &HandlersText::Tag::count)),

      HandlerTextPair( XPath("toptags/tag/url"),
        sigc::ptr_fun( &HandlersText::Tag::url)),
  };
}

namespace Bmp
{
  namespace LastFM
  {
    int parse_toptags (TagV & tags, const char * data, guint size) 
    {
      LastFMTagParserContext context (tags);

      for (unsigned int n = 0; n < G_N_ELEMENTS(handlers_start); context << handlers_start[n++]); 
      for (unsigned int n = 0; n < G_N_ELEMENTS(handlers_end); context << handlers_end[n++]); 
      for (unsigned int n = 0; n < G_N_ELEMENTS(handlers_text); context << handlers_text[n++]); 

      return SaxParserBase::xml_base_parse (data, size, context);
    }
  }
}
