//  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_APPCORE_HH
#define BMP_APPCORE_HH

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

#include <glibmm/ustring.h>
#include <sigc++/signal.h>

#include "main.hh"

#ifdef USING_DBUS
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include "bmp/dbus.hh"
namespace Bmp
{
  namespace DBus
  {
    extern DBusGConnection *  dbus_session_bus;
    extern gboolean           dbus_connected;
  }
}
#endif //USING_DBUS

namespace Bmp
{
  class PlayerShell;

  struct BlockAccumulator
  {
    typedef bool result_type;
    template<typename Iterator>
    result_type
    operator () (Iterator first,
                 Iterator last) const
    {
      for (; first != last; ++first)
        {
          if (!(*first))
            return false;
        }

      return true;
    }
  };

  class Core
  {
    public:

      class BMP;
      class MprisRoot;

      typedef sigc::signal<void> SignalStartupComplete;
      typedef sigc::signal<bool>::accumulated<BlockAccumulator> SignalShutdownRequest;

      Core ();
      ~Core ();

      static Core* Obj (ObjCreateFlag F = OBJ_FLAG_NONE)
      {
        static Core* p = 0;

        if( F == OBJ_FLAG_DELETE ) 
        {
          delete p;
          p = 0;
        }

        if( F == OBJ_FLAG_CREATE ) 
        {
          p = new Core();
        }

        return p;
      }

      void
      register_application_control (sigc::slot<void> const& startup,
                                    sigc::slot<void> const& shutdown)
      {
        m_startup  = startup;
        m_shutdown = shutdown;
      }
  
      void
      run ()
      {
        m_startup ();
      }

      void
      stop ()
      {
        bool ret = s_shutdown_request_.emit ();

        if (ret)
        {
          m_shutdown ();
        }
      }

      void
      stop_no_questions_asked ()
      {
        m_shutdown ();
      }

      void
      quit ();

      void ui_stop ();
      void ui_start ();
      void dbus_init ();

      bool disable_network ()
      {
        return m_disable_network;
      }

      SignalShutdownRequest &
      signal_shutdown_request ()
      {
        return s_shutdown_request_;
      }

      SignalStartupComplete &
      signal_startup_complete ()
      {
        return s_startup_complete_;
      }

      void status_push_message (Glib::ustring const& message);

    private:

      SignalShutdownRequest s_shutdown_request_;
      SignalStartupComplete s_startup_complete_;

      // Application Control
      sigc::slot<void> m_startup;
      sigc::slot<void> m_shutdown;

      BMP         * bmp; 
      MprisRoot   * mpris;
      PlayerShell * m_shell;

      bool m_disable_network;
  };
} // Bmp namespace

#endif // !SERVICE_CORE_HH
