//  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_UI_PART_CDDA_HH
#define BMP_UI_PART_CDDA_HH

#include <string>
#include <sigc++/signal.h>
#include <boost/optional.hpp>
#include <glibmm/ustring.h>
#include <gtkmm.h>
#include <libglademm/xml.h>

// BMP Audio
#include "audio/audio.hh"

// BMP Musicbrainz
#include "musicbrainz/mbxml-v2.hh"

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

namespace Bmp
{
  typedef std::vector<bool> BoolV;
  typedef sigc::signal<void, VUri&> SignalRequestImport;

  enum NotebookPage
  {
    PAGE_TOC,
    PAGE_LOADING,
    PAGE_CD_INSERT,
    PAGE_CD_BAD,
    PAGE_NO_SUPPORT
  };

  enum EncodeState
  {
    ES_UNPROCESSED,
    ES_WAITING,
    ES_RIPPING,
    ES_TAGGING,
    ES_DONE,
    ES_ERROR
  };

  class CR_processors
    : public Gtk::TreeModel::ColumnRecord
  {
    public:
      Gtk::TreeModelColumn<Glib::ustring> name;
      Gtk::TreeModelColumn<Bmp::Audio::ProcessorType> type;

      CR_processors ()
      {
        add (name);
        add (type);
      }
  };

  class CR_audio_cd
    : public Gtk::TreeModel::ColumnRecord
  {
    public:

      Gtk::TreeModelColumn<unsigned int>                      tracknumber;
      Gtk::TreeModelColumn<Glib::ustring>                     artist;
      Gtk::TreeModelColumn<Glib::ustring>                     title;
      Gtk::TreeModelColumn<unsigned int>                      duration;
      Gtk::TreeModelColumn<int>                               percentage;
      Gtk::TreeModelColumn<EncodeState>                       state;
      Gtk::TreeModelColumn<MusicBrainzXml::MusicBrainzTrack>  track;
      Gtk::TreeModelColumn<Glib::ustring>                     location;
      Gtk::TreeModelColumn<bool>                              audio;

      CR_audio_cd ()
      {
        add (tracknumber);
        add (artist);
        add (title);
        add (duration);
        add (percentage);
        add (state);
        add (track);
        add (location);
        add (audio);
      }
  };

  namespace UiPart
  {
    class CDDA
      : public PlaybackSource,
        public Base
    {
        struct SignalsT
        {
          SignalRequestImport RequestImport;
        };
  
        SignalsT Signals;

      public:

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

        SignalRequestImport&
        signal_request_import ();

      protected:

        virtual guint
        add_ui ();

        virtual Glib::ustring
        get_uri ();

        virtual bool
        go_next ();

        virtual bool
        go_prev ();

        virtual void
        stop ();

        virtual bool
        play ();

        virtual void
        play_post ();

        virtual void
        restore_context ();

     private:

      CR_processors  cr_processors;
      CR_audio_cd    cr_audio_cd;

      bool  on_shutdown_request ();

#ifdef HAVE_HAL

      void  on_hal_cdda_inserted     (std::string udi, std::string devicefile);
      void  on_hal_device_removed    (std::string udi);
      void  on_hal_ejected           (std::string udi);

      std::string m_current_udi;
      std::string m_current_device;

#else

      void  refresh ();

#endif //HAVE_HAL


      void  rip_start();
      void  rip_stop();

      void  stream_position(int position);
      void  stream_eos();
      void  stream_error(Glib::ustring);

      void  cell_data_func_state   (Gtk::CellRenderer* cell, Gtk::TreeIter const& m_iter);
      void  cell_data_func_playing (Gtk::CellRenderer* cell, Gtk::TreeIter const& m_iter);
      void  cell_data_func_numbers (Gtk::CellRenderer* cell, Gtk::TreeIter const& m_iter);

      void  selection_changed ();
      void  send_title ();
      void  assign_current_iter (Gtk::TreeIter const&);

      struct WidgetsT
      {
        struct ButtonsT
        {
          Gtk::Button * Rip;
          Gtk::Button * Reload;
          Gtk::Button * Stop;
        };

        struct CBoxT
        {
          Gtk::ComboBox * Format;
          Gtk::ComboBox * Quality;
        };

        struct LabelT
        {
          Gtk::Label  * Album,;
          Gtk::Label  * Artist;
          Gtk::Label  * Date;
        };
      
        struct ImageT
        {
          Gtk::Image  * Cover;
        };

        struct DisplayT
        {
          Gtk::Notebook           * Notebook;
          Gtk::TreeView           * View;
          Gtk::CellRendererPixbuf * CellPlaying;
        };

        struct MiscT
        {
        };

        ButtonsT        Buttons;    
        CBoxT           CBox;
        LabelT          Label;
        ImageT          Image;
        DisplayT        Display;
        MiscT           Misc;

      };

      WidgetsT Widgets;

      struct DataT
      {
        Glib::Mutex                         RipLock;
        Gtk::TreeIter                       RipIter;
        Glib::RefPtr<Gtk::ListStore>        Store;
        Glib::RefPtr<Gtk::ListStore>        StoreProcessors;
        Glib::RefPtr<Gdk::Pixbuf>           IconDefaultCover;
        MusicBrainzXml::MusicBrainzRelease  MBRelease;
        boost::optional<Gtk::TreeIter>      CurrentIter;
      };

      DataT Data;

      void  activate_default (Gtk::TreePath const& path, Gtk::TreeViewColumn* column);
      void  notebook_set_page (int page);

      void  view_fill (void * d, Bmp::MusicBrainzXml::MusicBrainzReleaseV const& releases, BoolV const& audiotracks);
      void  view_clear ();

      bool  get_processing_cd ();
      void  set_processing_cd (bool set);
      Glib::Mutex m_check_lock_1;

      bool  get_eos ();
      void  set_eos (bool set);
      Glib::Mutex m_check_lock_2;

      bool  m_processing_cd;
      bool  m_anonymous_cd;
      bool  m_stream_eos;

    }; // end class CDDA
  } // end namespace UiPart
} // end namespace Bmp

#endif // !BMP_UI_PART_CDDA_HH

