/* 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_VALUE_HPP
#define NMM_VALUE_HPP NMM_VALUE_HPP

#include "nmm/nmm_prefix.hpp"

#include <string>
#include <list>
#include <vector>

#include "visibility.hpp"

using namespace std;

namespace NMM {
  
  class IValueStream;
  class OValueStream;
  
  /** This class is a superclass for all "value" classes.
   */
  class DLLEXPORT Value {
  public:
    enum ValueType{ SIMPLE  = 0, ARRAY, SEQUENCE, COMPOUND};
    enum MemoryMgm{ INVALUE = 1, OUTVALUE = 2, INOUTVALUE = 4};

    Value(ValueType vt = SIMPLE, MemoryMgm memory_mgm = INOUTVALUE)
      :  _vt(vt), _memory_mgm(memory_mgm) {}

    /** The main destructor.
     */
    virtual ~Value()                              {}

    /** Assigns Value from stream.
     *
     *  @param iv IValueStream to read from
     */
    virtual void assignFromStream(IValueStream& iv);

    /** Creates Value from stream.
     *
     *  @param iv IValueStream to read from
     */
    virtual void createFromStream(IValueStream& iv);

    /** Writes the Value to a stream.
     *
     * @param ov OValueStream to write to
     */
    virtual void toStream(OValueStream& ov)        const;

    /** Virtual copy method.
     *
     * @return pointer to copy of this Value
     */
    virtual Value* copy()                       const { return 0; };

    /** Release method for memory management.
     */
    virtual void releaseValue()                 const {};


    /** Tests if the stored value is a pointer.
     *
     * @return true if the stored value is a pointer, false otherwise.
     */
    virtual bool isPointerType()                const { return false; }

    /** This method can be used to disable certain types. 
     *
     * This mehtod is interesting for complex data structures to disable 
     * certain Memory types like In or Out-Values for (de-)serialization
     *
     * @param mgm memory type to disable
     */
    virtual void disableMemoryType(Value::MemoryMgm mgm);

    /** Resets the internal datastructure wich was disabled before.
     */
    virtual void resetMemoryType() {}

    /** Returns the value type. 
     *
     * This method is obsolete.
     *
     * @return ValueType
     */
    inline       ValueType getValueType()       const {return _vt;}

    /** Returns the used memory management strategy.
     *
     * @return used memory management strategy
     */
    inline       MemoryMgm getMemoryStrategy()  const {return _memory_mgm;}

    /** Sest the used memory management strategy.
     *
     * @param mgm memory management strategy to set
     */
    inline       void setMemoryStrategy(MemoryMgm mgm) {_memory_mgm = mgm;}

  private:
    ValueType _vt;         ///< value type
    MemoryMgm _memory_mgm; ///< type of memory management
  };

  inline void Value::assignFromStream(IValueStream&) {}
  inline void Value::createFromStream(IValueStream&) {}
  inline void Value::toStream(OValueStream&) const {}

  inline void Value::disableMemoryType(Value::MemoryMgm) {}

  
  /** Writes Value to OValueStream.
   *
   * @param ov OValueStream to write to
   * @param value Value to write
   * @return reference to OValueStream given by argument
   */
  DLLEXPORT OValueStream& operator<<(OValueStream& ov, const Value& value);

  /** Reads Value from IValueStream.
   *
   * @param iv IValueStream to read from
   * @param value Value variable to read to
   * @return reference to IValueStream given by argument
   */
  DLLEXPORT IValueStream& operator>>(IValueStream& iv, Value& value);
  
  /** Writes type of Value to OValueStream.
   *
   * @param ov OValueStream to write to
   * @param mgm memory management type to write
   * @return reference to OValueStream given by argument
   */
  DLLEXPORT OValueStream& operator<<(OValueStream& ov, const Value::MemoryMgm& mgm);

  /** Reads type of Value from IValueStream.
   *
   * @param iv IValueStream to read from
   * @param mgm MemoryMgm variable to read to
   * @return reference to IValueStream given by argument
   */
  DLLEXPORT IValueStream& operator>>(IValueStream& iv, Value::MemoryMgm& mgm);
  
}

#include "nmm/nmm_suffix.hpp"

#endif
