//  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.

#ifndef BMP_UI_PART_JAMENDO_HH
#define BMP_UI_PART_JAMENDO_HH

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

#include <string>
#include <sigc++/connection.h>
#include <boost/optional.hpp>

#include <glibmm/ustring.h>
#include <gtkmm/treemodel.h>
#include <gtkmm/treeview.h>
#include <gtkmm/uimanager.h>
#include <libglademm/xml.h>

#include "bmp/types/types-ui.hh"

#include "ui-part-base.hh"
#include "playbacksource.hh"

#include "jamendo.hh"
#include "jamendo-types.hh"

#include "bookmarkhandler.hh"

using namespace Gtk;
using namespace Glib;

namespace Bmp
{
  namespace UiPart
  {
    class Jamendo
      : public PlaybackSource,
        public Base,
        public BookmarkHandler
    {

      public:

        Jamendo (RefPtr<Gnome::Glade::Xml>  const& xml,
                 RefPtr<UIManager>          const& ui_manager);
        virtual ~Jamendo ();

      private:
  
        class JMBase
          : public TreeView
        {
          protected:

            UidIterMap m_uid_iter_map;

          public:

            JMBase (BaseObjectType                 * obj,
                    RefPtr<Gnome::Glade::Xml> const& xml) : Gtk::TreeView (obj) {}
            virtual ~JMBase () {}

            virtual void clear ();
            void select_uid (guint64 uid);
            void add_uid (guint64 uid, TreeIter const& iter);

            RefPtr<ListStore> m_store;
        };


        class JMArtists
          : public JMBase 
        {
          private:
            void cell_data_func (CellRenderer * basecell, TreeIter const& iter, int cell);
      
            UidIterMap m_uid_iter_map;

          public:
            JMArtists (BaseObjectType                       * obj,
                       RefPtr<Gnome::Glade::Xml> const& xml);
            virtual ~JMArtists () {}

            JamendoData::Artist get_current_artist ();

          public:
            class artistCR
              : public TreeModel::ColumnRecord
            {
              public:
                TreeModelColumn<JamendoData::Artist>  artist; 
                TreeModelColumn<Glib::ustring>        searchkey; 
                artistCR ()
                {
                  add (artist);
                  add (searchkey);
                }
            };
            artistCR cr;
        };

        class JMAlbums
          : public JMBase 
        {
          private:
            void cell_data_func (CellRenderer * basecell, TreeIter const& iter, int cell);
            guint64 m_playing_album;

            UidIterMap m_uid_iter_map;

          public:

            JMAlbums (BaseObjectType                 * obj,
                      RefPtr<Gnome::Glade::Xml> const& xml);
            virtual ~JMAlbums () {}

            void set_playing_album (guint64 playing_album);
            JamendoData::Album get_current_album ();

          public:
            class albumCR
              : public TreeModel::ColumnRecord
            {
              public:
                TreeModelColumn<JamendoData::Album> album; 

                albumCR ()
                {
                  add (album);
                }
            };
            albumCR cr;
        };

        class JMTracks
          : public JMBase 
        {      
          public:
            typedef sigc::signal<void> Signal;
            Signal & activated () { return signal_activated_; }           

          private:

            Signal signal_activated_;

            void  cell_data_func (CellRenderer * basecell, TreeIter const& iter, int cell); // private
            void  assign_current_track (TreeIter const& iter); // private

            RefPixbuf m_playing; // 'playing' image

            bool      m_has_playing;
            TreeIter  m_playing_iter;
            guint64  m_playing_track;

            UidIterMap m_uid_iter_map;

          public:

            JMTracks (BaseObjectType                 * obj,
                      RefPtr<Gnome::Glade::Xml> const& xml);
            virtual ~JMTracks () {}

            void  set_album (::Bmp::Jamendo & jamendo, JamendoData::Album const& a);
            void  set_playing_track (guint64 playing_track);
            void  set_playing_track (); // sets the currently selected track, if any (WARNING on no selection)
            JamendoData::Track get_current_track () const;

            bool  has_next ();
            bool  has_prev ();

            void  go_next ();
            void  go_prev ();

            virtual void clear ();

          protected:

            // Gtk::Widget
            virtual void on_row_activated (Gtk::TreeModel::Path const&, Gtk::TreeViewColumn*);

          public:
            class trackCR
              : public TreeModel::ColumnRecord
            {
              public:
                TreeModelColumn<JamendoData::Track> track; 

                trackCR ()
                {
                  add (track);
                }
            };
            trackCR cr;
        };

        JMArtists   * m_artists;
        JMAlbums    * m_albums;
        JMTracks    * m_tracks;

      protected:

        // PlaybackSource
        virtual unsigned int
        add_ui ();

        virtual ustring
        get_uri ();

        virtual ustring
        get_type ()
        {
          return "application/ogg"; // we use Jamendo's vorbis streams
        }

        virtual bool
        go_next ();

        virtual bool
        go_prev ();

        virtual void
        stop ();

        virtual bool
        play ();

        virtual void
        play_post ();

        virtual void
        prev_post ();

        virtual void
        next_post ();

        virtual void
        restore_context ();

        virtual void
        send_caps();

        // BookmarkHandler
        virtual bool 
        get_bookmark (ustring const& id, /* the id to be used as the hostname part, but otherwise ignored */
                      ustring & url,
                      ustring & title);
    
        virtual bool 
        set_bookmark (ustring const& url);

      private:

        ustring m_current_uri;
        JamendoData::Track m_current_track;
        JamendoData::Album m_current_album;
        JamendoData::Artist m_current_artist;
        ::Bmp::Jamendo * m_jamendo;

        void  update_view (); // private
        void  update_db (); // private

        void  on_artist_selection_changed (); // private
        void  on_album_selection_changed (); // private
        void  on_track_selection_changed (); // private

        void  send_metadata (); // private
    };
  }
}
#endif // !BMP_UI_PART_JAMENDO
