/* Network-Integrated Multimedia Middleware (NMM)
 * http://www.motama.com/nmm.html
 *  
 * Copyright (C) 2006-2007
 * Motama GmbH, Saarbruecken, Germany
 * http://www.motama.com
 *  
 * This file is part of NMM. 
 * 
 * NMM 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; only version 2 of the License.      
 * 
 * NMM 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 NMM; if not, write to the Free Software Foundation,    
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */
#ifndef _NMM_TIMER_HPP_
#define _NMM_TIMER_HPP_

#include "nmm/nmm_prefix.hpp"

#include "nmm/utils/thread/ThreadedObject.hpp"
#include "nmm/utils/thread/Thread.hpp"
#include "nmm/utils/thread/ThreadCondition.hpp"
#include "nmm/utils/thread/MutexGuard.hpp"
#include "visibility.hpp"
namespace NMM {

class TimerListener;

/** This class can be used to trigger a certain listener in a given interval.
  */
class DLLEXPORT Timer : public ThreadedObject {
public:
  /** Constructor */
  Timer(TimerListener& listener);

  /** Destructor */
  virtual ~Timer();

  /** starts the timer and triggers method timeout() of the listener in the given periode
    * \param sec specifies the seconds of the period
    * \param nsec specifies the nano seconds of the period
    */
  void start(int sec, int nsec = 0);

  /** Stops the timer and terminates the thread, so that the listener no longer triggerd.
    * Important note: The Listener must not call this method in its timeout() method, because
    * stop() terminates the thread used to call this timeout() method. !!!
    */
  void stop();
protected:
  /** Starts the internal thread */
  virtual void run();

private:
  bool            __is_running;           ///< specify if the thread is still running and the listener must be informed
  TimerListener&  __listener;             ///< The listener that should be informed
  ThreadMutex     __condition_mutex;      ///< Mutex for the internal thread_condition
  ThreadCondition __thread_condition;     ///< This condition is used to wait for the given time
  int __sec;                              ///< stores the seconds to wait
  int __nsec;                             ///< stores the nano seconds to wait.
};



class TimerListener
{
public:
  virtual ~TimerListener() {}
  /* This method is called from the timer */
  virtual void timeout(Timer*) = 0;        
};

}

#include "nmm/nmm_suffix.hpp"

#endif
