/* 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_PROPERTY_HPP
#define _NMM_PROPERTY_HPP

#include "nmm/nmm_prefix.hpp"

#include "definition.hpp"
#include <memory>

#include "visibility.hpp"

namespace NMM {

class IValueStream;
class OValueStream;

    /* This class represents the property of one NMM-Node.
     *
     * Depending on the node-type, a node has the following properties:
     * SOURCE        : Output-Property
     * SINK          : Input-Property
     * FILTER        : Input- / Output-Property
     * CONVERTER     : Input- / Output-Property
     * MULTIPLEXER   : Input- / Output-Property
     * DEMULTIPLEXER : Input- / Output-Property
     * The propertys consists of the formats, which on their part consists
     * of several parameters.
     */

class DLLEXPORT Property {
    
private:
   
  std::string         m_property_type; ///< The type of the property

  std::list<Format *> m_format_list; ///< STL-List of all the supported formats.
  
  std::map<const std::string, Format *>  m_default_formats; ///< The default format of this property.

private:
public:

  /** The default constructor.
   */
  Property();  

  /* The default destructor.
   */
   ~Property();  

  /** Copy constructor.
   *
   * @param property Property to copy
   */
  Property(const Property& property);

  /** Assignment operator.
   *
   * Assigns values of given property to this property.
   *
   * @param property Property with values to assign 
   * @return reference to this Property
   */
  const Property& operator=(const Property& property);
  
  /** Adds new format.
   *
   * This method creates a new format and adds it to the m_format_list.
   * For every format you have to specifie the type/subtype.
   *
   * @param format_type the type/subtype of the new format.
   * @return Format *: pointer to the new format.
  **/
  Format * addNewFormat(const std::string & format_type);
  
  /** Adds new format.
   *
   * Add a new Format to the list of formats. The new format is already complete.
   *
   * @param new_format the new format that will be added to the list of formats.
  **/
  void addNewFormat(Format * new_format);

  /** Deletes format.
   *
   * This method deletes the format specified by the argument pFormat.
   *
   * @param pFormat the format which will be deleted.
   * @return true in success otherwise false.
  */
  void deleteFormat(Format *pFormat);
  
  /** Get list of formats with given type.
   *
   * This function returns a list of Formats specified by the desired Type/subType.
   * If no format is machting, the returned format_list will be empty.
   *
   * @param pFormatType the Type/SubType of the desired Format.
   * @return FormatList: all the formats matching the desired Type/SubType.
   */
  format_list getFormat(const std::string & pFormatType) const;
  
  /**  Get list of formats matching given parameters.
   *
   * This functions returns a list of formats matching several defined parameters,
   * specified by the desired argument of function 'pFormat'.
   * By filling out the parameter-list of the 'pFormat', you can specify the desired parameters.
   *
   * @param pFormat *Format: the template format.
   * @return format_list: all formats that fulfil the requirements of the template.
   */
  format_list getFormat(const Format *pFormat) const;
  
  /** Get list of all parameters.
   *
   * This function returns the complete list of formats of the Property.
   *
   * @return FormatList: list of all formats.
   */
  const format_list & getFormatList() const;

  /** Returns the desired IOPartner of the specified Format.
   *
   * If the Format has no IOPartner (it's a sink or source), the function returns NULL.
   *
   * @param pFormat the format which IOPartner is given back.
   * @return the appropriate IOPartner for the format.
   */
  const Format * getIOPartner(const Format * pFormat) const;

  /** Shows all parameters of all formats.
   *
   * Just a debugging function.
   */
  void showFormats() const;

  /** Sets the default Format.
   *
   * @param pFormat the default format.
   * @param jack_tag the jack - specified by its jack tag, whose default format should be set.
   */
  void setDefaultFormat(Format *pFormat, const std::string jack_tag = "default");

  /** Gets the default format.
   *
   * @param jack_tag the jack - specified by its jack tag, whose default format should be returned.
   * @return The default format (of the specified jack) if it is set or NULL otherwise.
  */
  const Format * getDefaultFormat(const std::string jack_tag = "default") const;

  /** deletes all Formats stored in the property
    */
  void erase();

  /** Tests if format is inluded in this property.
   *
   * @return true if one of the format stored in this property includes the given format, false otherwise.
   */
  bool isFormatIncluded(const Format& format, const std::string& jack_tag = "default") const;

  /** Tests if there is a matching format in this property.
   *
   * @return true if one of the format stored in this property matches the given format and jack tag, false otherwise.
   */
  bool isFormatMatching(const Format& format, const std::string& jack_tag = "default") const;

  /** Creates list of formats that match given format and its jack tag.
   * 
   * @param format format to match 
   * @param property_jack_tag specifies with which formats in this property the intersection should be done
   * @param include_def_format if true default format will also be matched and eventually included in list
   * @returns format list
   */
  const_format_list createIntersectionFormats(const Format* format, 
					      const std::string& property_jack_tag, 
					      bool include_def_format = true) const;

  /** Creates list of formats that match within this and given property.
   * 
   * @param out_jack_tag jack tag within this property
   * @param property other property (should be an input property)
   * @param in_jack_tag jack tag within other property
   * @param include_def_format if true default format will also be matched and eventually included in list
   * @returns format list
   */
  const_format_list createIntersectionFormats(const std::string& out_jack_tag, 
					      const Property* property, const std::string& in_jack_tag, 
					      bool include_def_format = true) const ;

  /** Reads Property from IValueStream.
   *
   * @param v IValueStream to read Property from.
   * @param property reference to Property variable to read Property to
   * @return reference to given IValueStream
   */
  friend DLLEXPORT IValueStream& operator>>(IValueStream& v, Property& property);
  
  /** Writes Property to OValueStream.
   *
   * @param v OValueStream to write Property to.
   * @param property Property to write to OValueStream
   * @return reference to given OValueStream
   */
  friend DLLEXPORT OValueStream& operator<<(OValueStream& v, const Property& property);
};

typedef auto_ptr<Property> Property_var;

}


#include "nmm/nmm_suffix.hpp"

#endif
