//  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_INOTIFY_HH
#define BMP_INOTIFY_HH

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

#include <glibmm.h>
#include <sys/inotify.h>
#include <queue>
using namespace Glib;

namespace Bmp
{
  struct INotifyEvent
  {
    int wd;
    uint32_t mask;
    uint32_t cookie;
    uint32_t len;
    std::string name;
  };

  typedef std::deque<INotifyEvent> IEventQueue;

  class INotify
    : public Glib::Object
  {
      typedef sigc::signal<void> SignalNewEvents;
      SignalNewEvents signal_new_events_;

    public:
#include "exception.hh"

      EXCEPTION(UnableToInitInotify)
      SignalNewEvents & signal_new_events () { return signal_new_events_; }

      static RefPtr<INotify>
      create (std::string const& file)
      {
        return RefPtr<INotify>( new INotify(file) );
      }

      ~INotify ();

      void
      acquire_queue_lock () { m_queue_lock.lock(); }
      void
      release_queue_lock () { m_queue_lock.unlock(); }

      IEventQueue&
      get_queue () { return m_events; }

    private:

      INotify (std::string const& file);
      void poll_fd(int x_fd);

      int               m_fd;
      RefPtr<IOSource>  m_source;
      IEventQueue       m_events; 

      Glib::Mutex       m_queue_lock;
      Glib::Thread    * m_thread;
      bool              m_eof;
      bool              m_has_eof;
      Glib::Mutex       m_has_eof_lock;
      Glib::Cond        m_has_eof_cond;
  };
}

#endif // BMP_INOTIFY_HH
