/* 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_BENCHMARK_HPP
#define NMM_BENCHMARK_HPP NMM_BENCHMARK_HPP

#include "nmm/nmm_prefix.hpp"

#include "Clock.hpp"

#include <string>

#include "visibility.hpp" 
namespace NMM {
  
  class NamedObject;
  
  /** Benchmark utility class.
   *
   * This is a utility class which can be used to measure bytes per
   * frame, frames per second, and bytes per second.
   *
   * Typical use:
   *
   * Initialization:
   * @code
   * Benchmark benchmark;
   * benchmark.setEnabled(true);
   * benchmark.setNameObject(this);
   * benchmark.setMessage("compression performance");
   * @endcode
   *
   * Every frame (e.g. in processBuffer):
   * @code
   * benchmark.benchmark(out->getUsed());
   * where out is a Buffer.
   * @endcode
   */
  class DLLEXPORT Benchmark {
  public:
    /** Constructor.
     *
     * @param obj the NamedObject-Object
     * @param msg the message which will be printed out every 10th frame.
     */
    Benchmark(NamedObject* obj = 0, const char* msg = 0);
    
    /** Destructor
     */
    ~Benchmark(); 
      
    /** Sets the enabled status of the object.
     *
     * @param enabled true to enable benchmarking, falso to disable
     */
    void setEnabled(const bool enabled); 
    
    /** Sets the message which is be displayed every 10 frames.
     *
     * If no message was set, 'Benchmark' will be printed out.
     *
     * @param str the message which will be printed out every 10th frame.
     */
    void setMessage(const char *str);
    
    /** Set the %NamedObject of this benchmark. Benchmark results are written to this NamedObject.
     *
     * @param obj pointer to the NamedObject
     */
    void setNamedObject(NamedObject *obj);
    
    /** This method should be called every frame.
     *
     * @param usedBytes the bytes which were produced/consumed for this frame
     */
    void benchmark(const long usedBytes);
    
    /** Returns the NamedObject.
     *
     * @return pointer to the NamedObject
     */
    inline const NamedObject* getNamedObject() const {return master;}

    /** Returns the message string.
     *
     * @return method string that is written in front of benchmark results
     */
    inline const std::string& getMessage() const{return message;}

    /** Returns true if benchmarking is enabled, otherwise false.
     *
     * @return true if benchmarking is enabled, otherwise false.
     */
    inline const bool getEnabled() const{return enabled;}

    /** Returns frames per seconds.
     *
     * @return frames per seconds
     */
    inline const float getFPS() const {return fps;}

    /** Returns bytes per frame
     *
     * @return bytes per frame
     */
    inline const long getBPF() const {return bpf;}

    /** Returns bytes per seconds
     *
     * @return bytes per seconds
     */
    inline const long getBPS() const {return bps;}

    /** Returns the number of received frames
     *
     * @return number of received frames
     */
    inline const long getFrameCount() const {return frame_count; }
    
  private:
    long frame_count;
    long total_bytes;
    long fps_looptimer_diff;
    Clock fps_clock;
    Time fps_looptimer1;
    Time fps_looptimer2;
    
    bool enabled;
    std::string message;
    
    float fps;
    long bpf;
    long bps;
    
    NamedObject *master;
  };
  
}

#include "nmm/nmm_suffix.hpp"

#endif
