//  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_PLAYBACK_SOURCE_HH
#define BMP_PLAYBACK_SOURCE_HH

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

#include <glib/ghash.h>
#include <glibmm/ustring.h>
#include <sigc++/signal.h>
#include <boost/format.hpp>

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

namespace Bmp
{
    class PlaybackSource
    {
      public:

        enum Flags
        {
          F_NONE                  = 0,
          F_ASYNC                 = 1 << 0,
          F_HANDLE_STREAMINFO     = 1 << 1,
          F_PHONY_NEXT            = 1 << 2,
          F_PHONY_PREV            = 1 << 3,
          F_ALWAYS_IMAGE_FRAME    = 1 << 4,
          F_HANDLE_LASTFM         = 1 << 5,
          F_HANDLE_LASTFM_ACTIONS = 1 << 6,
          F_USES_REPEAT           = 1 << 7,
          F_USES_SHUFFLE          = 1 << 8,
        };

        enum Caps
        {
          NONE                  = 0,
          CAN_GO_NEXT           = 1 << 0,
          CAN_GO_PREV           = 1 << 1,
          CAN_PAUSE             = 1 << 2,
          CAN_PLAY              = 1 << 3,
          CAN_SEEK              = 1 << 4,
          CAN_RESTORE_CONTEXT   = 1 << 5, 
          CAN_PROVIDE_METADATA  = 1 << 6,
          CAN_BOOKMARK          = 1 << 7,
          PROVIDES_TIMING       = 1 << 8,
        };

        typedef sigc::signal<void, Caps>                    SignalCaps;
        typedef sigc::signal<void, Flags>                   SignalFlags;
        typedef sigc::signal<void, TrackMetadata const&>    SignalTrackMetadata;
        typedef sigc::signal<void, Glib::ustring const&>    SignalMessage;
        typedef sigc::signal<void, VUri const&>             SignalEnqueueRequest;
        typedef sigc::signal<void>                          SignalSegment;
        typedef sigc::signal<void>                          SignalMessageClear;
        typedef sigc::signal<void>                          SignalPlaybackRequest;
        typedef sigc::signal<void>                          SignalStopRequest;
        typedef sigc::signal<void>                          SignalNextRequest;

        typedef sigc::signal<void>                          SignalPlayAsync;
        typedef sigc::signal<void>                          SignalNextAsync;
        typedef sigc::signal<void>                          SignalPrevAsync;


        PlaybackSource (Glib::ustring const& name, Caps caps = NONE, Flags flags = F_NONE)

        : m_caps        (caps),
          m_flags       (flags),
          m_name        (name)
        {}

        virtual ~PlaybackSource ()
        {}

        SignalCaps&
        signal_caps ();

        SignalFlags&
        signal_flags ();

        SignalTrackMetadata&
        signal_track_metadata ();

        SignalPlaybackRequest&
        signal_playback_request ();

        SignalStopRequest&
        signal_stop_request ();

        SignalNextRequest&
        signal_next_request ();

        SignalSegment&
        signal_segment ();

        SignalMessage &
        signal_message ();

        SignalMessageClear &
        signal_message_clear ();

        SignalEnqueueRequest&
        signal_enqueue_request ();


        SignalNextAsync&
        signal_next_async ();

        SignalPrevAsync&
        signal_prev_async ();

        SignalPlayAsync&
        signal_play_async ();



        virtual Glib::ustring
        get_uri () = 0; 
    
        virtual Glib::ustring
        get_type () 
        { return Glib::ustring(); }



        virtual bool
        play ()
        { return false; } 

        virtual bool
        go_next ()
        { return false; }

        virtual bool
        go_prev ()
        { return false; } 

        virtual void
        stop () = 0;
  


        virtual void
        play_async () {}

        virtual void
        go_next_async () {}
  
        virtual void
        go_prev_async () {}



        virtual void
        play_post () = 0;

        virtual void
        next_post (); 

        virtual void
        prev_post ();


        virtual void
        restore_context () = 0;


        virtual void
        skipped (); 

        virtual void
        segment (); 

        virtual void
        buffering_done (); 

        virtual void
        bad_track();



        virtual void
        send_caps ();

        virtual void
        send_flags ();



        Glib::ustring
        get_name ();

        virtual GHashTable *
        get_metadata ();



        std::string
        new_error   (std::exception const& cxe);

        std::string
        new_message (std::string const& message_in);


      protected:

        SignalCaps                      mSignalCaps;
        SignalFlags                     mSignalFlags;
        SignalTrackMetadata             mSignalMetadata;
        SignalSegment                   mSignalSegment;
        SignalMessage                   mSignalMessage;
        SignalMessageClear              mSignalMessageClear;
        SignalPlaybackRequest           mSignalPlayRequest;
        SignalStopRequest               mSignalStopRequest;
        SignalNextRequest               mSignalNextRequest;
        SignalEnqueueRequest            mSignalEnqueueRequest;

        SignalPlayAsync                 mSignalPlayAsync;
        SignalNextAsync                 mSignalNextAsync;
        SignalPrevAsync                 mSignalPrevAsync;

        Caps                            m_caps;
        Flags                           m_flags;
        Glib::ustring                   m_name;

    }; // end class PlaybackSource 
} // end namespace Bmp 
  
#endif
