/* 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_C_EVENT_HPP
#define NMM_C_EVENT_HPP NMM_C_EVENT_HPP

#include "nmm/nmm_prefix.hpp"

#include "Message.hpp"

#include "nmm/comm/serialize/SequenceValue.hpp"

#ifdef BUILD_WINXP
#include "Event.hpp"
#endif

#include "visibility.hpp"

namespace NMM {
  
  class Event;
  
  /** Combines severeal single Events to one composite event.
   * 
   * This class can be used to send several Events to a Node at once. All Events are executed
   * automatically and in the specified order. The event size is dynamic.
   */
  class DLLEXPORT CEvent : public Message {
  public:
    /** Constructor.
     *
     * @param b_mgr true if object should delete itself on destruction
     */
    explicit CEvent(bool b_mgr = true);

    /** Constructor.
     *
     * @param i size of internal event array
     * @param b_mgr true if object should delete itself on destruction
     */
    explicit CEvent(size_t i, bool b_mgr = true);

    /** Constructor.
     *
     * @param event event to be inserted
     * @param b_mgr true if object should delete itself on destruction
     */
    explicit CEvent(const Event& event, bool b_mgr = true);

   /** Constructor.
     *
     * @param event event to be inserted
     * @param b_mgr true if object should delete itself on destruction
     */
    explicit CEvent(Event* event, bool b_mgr = true);

    /** Creates a CEvent with two Events.
     *
     * @param e1 first event
     * @param e2 second event
     * @param b_mgr true if object should delete itself on destruction 
     */
    explicit CEvent(const Event& e1, const Event& e2, bool b_mgr = true);

    /** Copy constructor
     *
     * @param ce CEvent to copy
     */
    explicit CEvent(const CEvent& ce);

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

    /** returns the count of stored events
     *
     * @return count of stored events
     */
    size_t size() const {return event_array.size();}

    /** Returns the i'th element.
     *
     * @param i array index of event
     * @return reference to requested event
     */
    Event& operator[](size_t i);

    /** Returns the i'th element.
     *
     * @param i array index of event
     * @return reference to requested event
     */
    const Event& operator[](size_t i) const;

    /** Returns the i'th element.
     *
     * @param i array index of event
     * @return reference to requested Event
     */
    Event& getEvent(size_t i)               {return *event_array[i];}

    /** Assigns a new Event.
     * 
     * @param i index of internal array to save event in
     * @param e event to set
     */
    void setEvent(size_t i, const Event& e);
    
    /** Assigns a new Event.
     * 
     * @param i index of internal array to save event in
     * @param e event to set
     */
    void setEvent(size_t i, Event* e);
    
    /** Inserts a new Event e at position p.
     *
     * @param p  Position of Event e.(from 0 to size-1). If p > size-1, the
     *            Event is inserted at the end.
     * @param e  The new Event.
     */
    void insertEvent(size_t p, const Event& e);

    /** Inserts a new Event e at the end.
     * 
     * @param e : The new Event.
     */
    void insertEvent(const Event& e);

    /** Inserts a new Event e at the end.
     *
     * @param e The new Event.
     */
    void insertEvent(Event* e);
    
    /** Inserts a new Event e at position p.
     *
     * @param p Position of Event e.(from 0 to size-1). If p > size-1, the Event is inserted at the end.
     * @param e  The new Event.
     */
    void insertEvent(size_t p, Event* e);

    /** Removes the i'th Event.
     *     
     * @param i Postion of Event to delete (from 0 to size-1). If i > size-1
     *            this method returns immediatly.
     */
    void removeEvent(size_t i);

    /** Assignment operator.
     *
     * Removes all previous contained events and inserts Event's from argument.
     *     
     * @param ce CEvent to copy Event's from.
     * @return reference to this CEvent
     */
    CEvent& operator=(const CEvent& ce);

    
    /** Copy this CEvent.
     *     
     * @return Pointer to new copy of this CEvent.
     */
    virtual CEvent* copy() const  {return new CEvent(*this);}
    
    /** Typename of this class.
     */
    static const std::string type_name;
    
  protected:
    /** Erase this CEvent.
     * 
     * Erase implementation for pure virtual method in superclass.
     * Protected since it gets called by method release of superclass.
     */
    virtual void erase() const;
    
  private:
    SequenceValue<Event> event_array; ///< array with this CEvent's Event objects
    bool b_mgr; ///< true if this object should destro itself on destruction, false otherwise
  };
  
}

#include "nmm/nmm_suffix.hpp"

#endif
