/* 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_TVCARD_STRUCTS_HPP
#define __NMM_TVCARD_STRUCTS_HPP

#include "nmm/nmm_prefix.hpp"

#include "nmm/comm/serialize/TValue.hpp"
#include "nmm/comm/serialize/TConstructor.hpp"

namespace NMM {
  
  /** TV Audio Input.
   * This structure describes an audio input of a TV Card.
   */
  class TVAudio
    : public SerializedValue
  {
  public:
    /** Capability flags.
     */
    enum CapabilityFlags {
      CAPS_STEREO = 1, ///< This input is a stereo input
      CAPS_AVL    = 2  ///< Automatic Volume Level mode is supported
    };
    
    /** Mode flags.
     */
    enum ModeFlags {
      MODE_AVL    = 1  ///< Automatic Volume Level mode is active
    };
    
  public:
    /** @name Constructor & Destructor
     */
    //@{
    /** Default constructor.
     */
    TVAudio();
    
    /** Copy constructor.
     */
    TVAudio(const TVAudio& other);
    
    /** Constructor
     * @param index Index of this audio input
     * @param name Name of this audio input
     * @param caps Capability flags
     * @param mode Mode flags
     */
    TVAudio(unsigned int index, const string& name, unsigned int caps, unsigned int mode);
    
    /** virtual copy constructor
     */
    virtual TVAudio* copy() const { return new TVAudio(*this); }
    //@}
    
    
    /** @name Operators
     */
    //@{
    /** Assignment operator.
     */
    const TVAudio& operator=(const TVAudio& other);
    //@}
    
    
    /** @name Access Methods
     */
    //@{
    /** This method returns the index of this audio input.
     */
    inline unsigned int getIndex()        const { return __index.getRValue(); }
    
    /** This method returns the name of this audio input.
     */
    inline string       getName()         const { return __name.getRValue(); }
    
    /** This method returns the capability flags of this audio input.
     */
    inline unsigned int getCapabilities() const { return __caps.getRValue(); }
    
    /** This method returns the mode flags of this audio input.
     */
    inline unsigned int getMode()         const { return __mode.getRValue(); }
    //@}
    
  private:
    /** This method copies all attributes from another object.
     */
    void assign(const TVAudio& other);
    
    /** This method adds all attributes by the base class.
     */
    void registerAttributes();
    
  private:
    TValue<nmm_uint32> __index; ///< Index of this audio input
    TValue<string>       __name;  ///< Name of this audio input
    TValue<nmm_uint32> __caps;  ///< Capability flags
    TValue<nmm_uint32> __mode;  ///< Audio mode flags
  };
  
  
  /** TV Input properties.
   * This structure describes an input of a TV card.
   */
  class TVInput
    : public SerializedValue
  {
  public:
    /** Type of input.
     * These constants directly correspond to the Video4Linux input types
     */
    enum Type {
      TYPE_UNKNOWN = 0, ///< Unknown type
      TYPE_TUNER   = 1, ///< This input uses a tuner (RF demodulator)
      TYPE_ANALOG  = 2  ///< Analog baseband input, for example CVBS / Composite Video, S-Video, RGB
    };
    
  public:
    /** @name Constructor & Destructor
     */
    //@{
    /** Default constructor.
     */
    TVInput();
    
    /** Copy constructor.
     */
    TVInput(const TVInput& other);
    
    /** Constructor
     * @param num Numeric ID of input
     * @param name Name of input
     * @param type Type of input
     * @param audio_set Audio set of input
     * @param tuner Tuner ID of input
     * @param standard Standard ID of input
     * @param status Status flags of input
     */
    TVInput(unsigned int num, const string& name, unsigned int type, unsigned int audio_set,
            unsigned int tuner, unsigned int standard, unsigned int status);
    
    /** virtual copy constructor
     */
    virtual TVInput* copy()                     const { return new TVInput(*this); }
    //@}
    
    /** @name Operators
     */
    //@{
    /** Assignment operator.
     */
    const TVInput& operator=(const TVInput& other);
    //@}
    
    /** @name Access methods.
     */
    //@{
    /** This method returns the numeric ID of this input.
     */
    inline unsigned int           getNum()      const { return __num.getRValue(); }
    
    /** This method returns the name of this input.
     */
    inline const string&          getName()     const { return __name.getRValue(); }
    
    /** This method returns the type of this input.
     */
    inline unsigned int           getType()     const { return __type.getRValue(); }
    
    /** This method returns the audio set of this input.
     */
    inline unsigned int           getAudioSet() const { return __audio_set.getRValue(); }
    
    /** This method returns the tuner ID of this input.
     */
    inline unsigned int           getTuner()    const { return __tuner.getRValue(); }
    
    /** This method returns the standard ID of this input.
     */
    inline unsigned int           getStandard() const { return __standard.getRValue(); }
    
    /** This method returns the status of this input.
     */
    inline unsigned int           getStatus()   const { return __status.getRValue(); }
    
    /** This method sets the numeric ID of this input.
     */
    inline void setNum(unsigned int num)              { __num.setValue(num); }
    
    /** This method sets the name of this input.
     */
    inline void setName(const string& name)           { __name.setValue(name); }
    
    /** This method sets the type of this input.
     */
    inline void setType(Type type)                    { __type.setValue(type); }
    
    /** This method sets the audio set of this input.
     */
    inline void setAudioSet(unsigned int audio_set)   { __audio_set.setValue(audio_set); }
    
    /** This method sets the tuner ID of this input.
     */
    inline void setTuner(unsigned int tuner)          { __tuner.setValue(tuner); }
    
    /** This method sets the standard ID of this input.
     */
    inline void setStandard(unsigned int standard)    { __standard.setValue(standard); }
    
    /** This method sets the status of this input.
     */
    inline void setStatus(unsigned int status)        { __status.setValue(status); }
    //@}
    
    /** @name Helper Methods
     */
    //@{
    /** This method checks if the input can be combined with a given audio input.
     * @param index The index of the audio input
     * @return True, if this input combines with the given audio input
     */
    inline bool combinesWithAudio(unsigned int index) {
      if (index >= 32) {
        return false;
      }
      return ((__audio_set.getRValue() & (1 << index)) != 0);
    }
    //@}
    
  private:
    /** This method copies all attributes from another object.
     */
    void assign(const TVInput& other);
    
    /** This method adds all attributes by the base class.
     */
    void registerAttributes();
    
  private:
    TValue<nmm_uint32> __num;                   ///< Input number
    TValue<string>       __name;                  ///< Name of input
    TValue<nmm_uint32> __type;                  ///< Input type
    TValue<nmm_uint32> __audio_set;             ///< Input audio set
    TValue<nmm_uint32> __tuner;                 ///< Input tuner number
    TValue<nmm_uint32> __standard;              ///< Input standard identifier
    TValue<nmm_uint32> __status;                ///< Input status
  };
  
  /** TV Standard.
   * This structure describes a standard supported by a TV card.
   */
  class TVStandard
    : public SerializedValue
  {
  public:
    /** @name Constructor & Destructor
     */
    //@{
    /** Default constructor.
     */
    TVStandard();
    
    /** Copy constructor.
     */
    TVStandard(const TVStandard& other);
    
    /** Constructor
     * @param id Numeric ID of standard
     * @param name Name of standard
     * @param fp_numerator Numerator of frame period
     * @param fp_denominator Denominator of frame period
     * @param lines Number of scanlines per frame
     */
    TVStandard(unsigned int id, const string& name, unsigned int fp_numerator, unsigned int fp_denominator,
               unsigned int lines);
    
    /** virtual copy constructor
     */
    virtual TVStandard* copy()                       const { return new TVStandard(*this); }
    //@}
    
    /** @name Operators
     */
    //@{
    /** Assignment operator.
     */
    const TVStandard& operator=(const TVStandard& other);
    //@}
    
    /** @name Access methods.
     */
    //@{
    /** This method returns the numeric ID of the standard.
     */
    inline unsigned int  getID()                     const { return __id.getRValue(); }
    
    /** This method returns the name of the standard.
     */
    inline const string& getName()                   const { return __name.getRValue(); }
    
    /** This method returns the numerator of the frame period of the standard.
     */
    inline unsigned int  getFramePeriodNumerator()   const { return __fp_numerator.getRValue(); }
    
    /** This method returns the denominator of the frame period of the standard.
     */
    inline unsigned int  getFramePeriodDenominator() const { return __fp_denominator.getRValue(); }
    
    /** This method returns the number of lines per frame of the standard.
     */
    inline unsigned int  getFrameLines()             const { return __lines.getRValue(); }
    //@}
    
  private:
    /** This method copies all attributes from another object.
     */
    void assign(const TVStandard& other);
    
    /** This method adds all attributes by the base class.
     */
    void registerAttributes();
    
  private:
    TValue<nmm_uint32> __id;                    ///< Standard identifier
    TValue<string>       __name;                  ///< Standard name
    TValue<nmm_uint32> __fp_numerator;          ///< Frame period numerator
    TValue<nmm_uint32> __fp_denominator;        ///< Frame period numerator
    TValue<nmm_uint32> __lines;                 ///< Number of scanlines
  };
  
  
  /** TV Tuner.
   * This structure describes a tuner on a TV card.
   */
  class TVTuner
    : public SerializedValue
  {
  public:
    /** Types of tuners.
     */
    enum Type {
      TYPE_UNKNOWN   = 0,                         ///< Unknown tuner
      TYPE_RADIO     = 1,                         ///< Radio tuner
      TYPE_ANALOG_TV = 2                          ///< Analog TV tuner
    };
    
    /** @name Constructor & Destructor
     */
    //@{
    /** Default constructor.
     */
    TVTuner();
    
    /** Copy constructor.
     */
    TVTuner(const TVTuner& other);
    
    /** Constructor
     * @param index Index of the tuner
     * @param name Name of the tuner
     * @param type Tuner type
     * @param range_min Minimum tunable frequency in MHz
     * @param range_max Maximum tunable frequency in MHz
     * @param granularity Frequency granularity in MHz
     */
    TVTuner(unsigned int index, const string& name, unsigned int type,
            float range_min, float range_max, float granularity);
    
    /** virtual copy constructor
     */
    virtual TVTuner* copy() const { return new TVTuner(*this); }
    //@}
    
    /** @name Operators
     */
    //@{
    /** Assignment operator.
     */
    const TVTuner& operator=(const TVTuner& other);
    //@}

    /** @name Access methods.
     */
    //@{
    /** This method returns the index of the tuner.
     */
    inline unsigned int  getIndex()         const { return __index.getRValue(); }
    
    /** This method returns the name of the tuner.
     */
    inline const string& getName()          const { return __name.getRValue(); }
    
    /** This method returns the type of the tuner.
     */
    inline unsigned int  getType()          const { return __type.getRValue(); }
    
    /** This method returns the minimum tunable frequency in MHz.
     */
    inline float         getMinFrequency()  const { return __range_min.getRValue(); }
    
    /** This method returns the maximum tunable frequency in MHz.
     */
    inline float         getMaxFrequency()  const { return __range_max.getRValue(); }
    
    /** This method returns the frequency granularity in MHz.
     */
    inline float         getGranularity()   const { return __granularity.getRValue(); }
    
  private:
    /** This method copies all attributes from another object.
     */
    void assign(const TVTuner& other);
    
    /** This method adds all attributes by the base class.
     */
    void registerAttributes();
    
  private:
    TValue<nmm_uint32> __index;                 ///< Index of the tuner
    TValue<string>       __name;                  ///< Name of the tuner
    TValue<nmm_uint32> __type;                  ///< Tuner type
    TValue<nmm_float>        __range_min;             ///< Minimum tunable frequency in MHz
    TValue<nmm_float>        __range_max;             ///< Maximum tunable frequency in MHz
    TValue<nmm_float>        __granularity;           ///< Frequency granularity in MHz
  };
  
  
  /* Begin> operator<< for STL and these structs */
  IValueStream& operator>>(IValueStream& iv, list<TVAudio>& tv_audio_list);
  IValueStream& operator>>(IValueStream& iv, list<TVInput>& tv_input_list);
  IValueStream& operator>>(IValueStream& iv, list<TVStandard>& tv_standard_list);
  IValueStream& operator>>(IValueStream& iv, list<TVTuner>& tv_tuner_list);
  
  OValueStream& operator<<(OValueStream& ov, const list<TVAudio>& tv_audio_list);
  OValueStream& operator<<(OValueStream& ov, const list<TVInput>& tv_input_list);
  OValueStream& operator<<(OValueStream& ov, const list<TVStandard>& tv_standard_list);
  OValueStream& operator<<(OValueStream& ov, const list<TVTuner>& tv_tuner_list);
  /* End< */
  
} // namespace NMM

#include "nmm/nmm_suffix.hpp"

#endif // __NMM_TVCARD_STRUCTS_HPP
