/*************************************************************************
 *
 *  $RCSfile: evtque.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: th $ $Date: 2001/05/10 10:49:19 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _VOS_EVTQUE_HXX_
#define _VOS_EVTQUE_HXX_

#ifndef _VOS_TYPES_HXX_
#   include <vos/types.hxx>
#endif

#ifndef _VOS_REFERNCE_HXX_
#   include <vos/refernce.hxx>
#endif

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

#ifdef _USE_NAMESPACE
namespace vos
{
#endif

class OEventQueue;
struct EventQueue_Impl;

typedef void*   EventHandle;
typedef sal_uInt32  EventId;

/** Predefined event ids.
    Add new ids here to define a new predefined id for system events.
*/
#define VOS_INVALID_EVENT_ID    0x0000
#define VOS_MAX_PREDEF_EVENT_ID 0x1000


/** IEventHandler interface.
    @see OEventQueue
*/
class IEventHandler
{
public:

    IEventHandler() { }
    virtual ~IEventHandler() { }


    /** Handle on event.
        @param id [in], the EventId for wich the event was posted.
        @param param [in], the parameter wich was posted with the event.
        @param pObject [in], the object wich was posted with the event, may be NULL.
        If the handler stores the object pointer apart from this method call
        pObject->acquire() has to be called.
        @return True, if other registered handlers should handle this event to,
        otherwise False.
    */
    virtual sal_Bool SAL_CALL handleEvent(EventId id, sal_Int32 param, IReference* pObject) = 0;
};

/** IEventQueueListener interface.
    @see OEventQueue
*/
class IEventQueueListener
{
public:

    IEventQueueListener() { }
    virtual ~IEventQueueListener() { }


    /** Notification for one posted event.
        This method is called in the context of the posting thread.
    */
    virtual void SAL_CALL eventPosted(OEventQueue* pQueue) = 0;
};

/** OEventQueue implementation.
*/
class OEventQueue
{
public:

    /** Get the global event queue.
        The application has the responsibility to dispatch this queue.
    */
    static OEventQueue* SAL_CALL getGlobalEventQueue();

    /** Default constructor.
    */
    OEventQueue();

    /** Destructor.
        All pending events will be lost.
    */
    virtual ~OEventQueue();


    /** Register a listener.
        The registered listeners are notificated each time one event is posted.
        @param pListener [in], the listener to register.
        @return True if the listener is not registered yet, otherwise False.
    */
    sal_Bool SAL_CALL registerListener(IEventQueueListener* pListener);

    /** Deregister a listener.
        @param pListener [in], the listener to deregister.
        @return False if the listener is not registered yet, otherwise True.
    */
    sal_Bool SAL_CALL deregisterListener(IEventQueueListener* pListener);

    /** Register a new event id.
        There are two kinds of event ids:
        1. predefined system ids
           (VOS_INVALID_EVENT_ID + 1) to VOS_MAX_PREDEF_EVENT_ID and
        2. registered user ids
           > VOS_MAX_PREDEF_EVENT_ID.
        Predefined event ids are only for system use. Use the registered
        user event id to register handlers and post user events.
        @param description [in], a description text of the new event.
        @return the new event id.
    */
    EventId SAL_CALL registerId(const ::rtl::OUString& strDescription);

    /** Deregister a event id.
        @param id [id], the id of an registered event.
        @return True, if the id was registered yet, otherwise False.
    */
    sal_Bool SAL_CALL deregisterId(EventId id);

    /** Query the discription of an registered event id.
        @param id [in], the id of an registered event.
        @param strDescription [out], the string that receives the description.
        @return True, if the id was registered yet, otherwise False.
    */
    sal_Bool SAL_CALL getDescription(EventId id, ::rtl::OUString& strDescription);

    /** Register a handler for a event id.
        Multible handlers could be registered for the same event id.
        They are called in reverse order of registration. Each handler
        in this calling sequence can decide whether the next handler
        has to be called or not by the return value of handleEvent().
        @param id [in], the event id to register for.
        @param pHandler [in], the handler which is to register.
        @return True, if the id is an valid event id.
    */
    sal_Bool SAL_CALL registerHandler(EventId id, IEventHandler* pHandler);

    /** Deregister a event handler.
        @param id [in] the event id for which the handler was registered.
        @param pHandler [in] the handler which is to deregister.
        @return True if the given handler was registered for the given id.
    */
    sal_Bool SAL_CALL deregisterHandler(EventId id, IEventHandler* pHandler);

    /** Query the count of registered handlers for one event id.
        @param id [in] the event id.
        @return the number of registered handlers.
    */
    sal_uInt32 SAL_CALL getHandlerCount(EventId id) const;

    /** Post one event.
        It is not checked if the id and a handler for this id is registered yet.
        Because of that and the fact, that handlers could be deregistered any
        time between posting and dispatching an event, it is possible, that a
        posted event could be removed from the event queue witout beeing handled.
        @param id [in] the event id, which determines the handler which is
        called for the event.
        @param param [in] the parameter wich is given to the handler.
        @param pObject [in] the object which is given to the handler.
        @return a handle the the posted event, which can be used to deregister
        the posted event.
    */
    EventHandle SAL_CALL postEvent(EventId id, sal_Int32 param, IReference* pObject = NULL);

    /** Remove one event.
        @param handle [in] the return value of postEvent().
        @retrurn True, if the event was found in the queue, otherwise False.
    */
    sal_Bool SAL_CALL removeEvent(EventHandle handle);

    /** Dispatch the next event.
        Dispatching means: wait until the queue is not empty, remove the first event
        in the queue and call the handlers, if any handlers are registered for the id
        of the event.
        @param timeout [in] the time to wait in milliseconds if no event is pending.
        a value < 0 means wait forever.
        @return True if a event was removed from the queue, otherwise False.
    */
    sal_Bool SAL_CALL dispatchEvent(sal_Int32 timeout = -1);

private:

    OEventQueue(const OEventQueue& );
    OEventQueue& SAL_CALL operator = (const OEventQueue& );

    sal_Bool SAL_CALL popAndDispatchEvent();

    EventQueue_Impl* m_pImpl;
};

#ifdef _USE_NAMESPACE
}
#endif


#endif  //_VOS_EVTQUE_HXX_



