/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
 *
 * This library is open source and may be redistributed and/or modified under  
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 * 
 * 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 
 * OpenSceneGraph Public License for more details.
*/

#ifndef OSGPRODUCER_EVENTCALLBACK
#define OSGPRODUCER_EVENTCALLBACK 1

#include <OpenThreads/Mutex>

#include <osgProducer/Export>      // To disable MSVC warnings

#include <Producer/RenderSurface> // For definition of KeySymbol
#include <Producer/KeyboardMouse>
#include <osgGA/EventQueue>

#include <osg/ref_ptr>
#include <osg/Timer>

namespace osgProducer {


class OSGPRODUCER_EXPORT KeyboardMouseCallback : public Producer::KeyboardMouseCallback
{
    public:
        KeyboardMouseCallback(Producer::KeyboardMouse* keyboardMouse, bool &done, bool escapeKeySetsDone=true);

        virtual ~KeyboardMouseCallback() {}

        // override KeyboardMouseCallback methods.
        virtual void mouseScroll( Producer::KeyboardMouseCallback::ScrollingMotion sm );
        virtual void mouseScroll2D( float, float);
        virtual void penPressure(float pressure);
        virtual void penProximity(Producer::KeyboardMouseCallback::TabletPointerType, bool);
        virtual void mouseMotion( float mx, float my);
        virtual void passiveMouseMotion( float mx, float my);
        virtual void mouseWarp( float mx, float my);

        virtual void buttonPress( float mx, float my, unsigned int mbutton );
        virtual void doubleButtonPress( float mx, float my, unsigned int mbutton);
        virtual void buttonRelease( float mx, float my, unsigned int mbutton );

        virtual void keyPress( Producer::KeyCharacter key );
        virtual void keyRelease( Producer::KeyCharacter key );

        virtual void specialKeyPress( Producer::KeyCharacter key);
        virtual void specialKeyRelease( Producer::KeyCharacter key);
        
        virtual void windowConfig( int x, int y, unsigned int width, unsigned int height );

        virtual void shutdown();


        void setEscapeSetDone(bool esc) { _escapeKeySetsDone = esc; }
        bool getEscapeSetDone() const { return _escapeKeySetsDone; }


        // local methods and members
        typedef osgGA::EventQueue::Events EventQueue;

        void setEventQueue(osgGA::EventQueue* eventQueue) { _eventQueue = eventQueue; }
        osgGA::EventQueue* getEventQueue() { return _eventQueue.get(); }
        
        bool takeEventQueue(EventQueue& queue);
        bool copyEventQueue(EventQueue& queue) const;
        void setEventQueue(EventQueue& queue);
        void appendEventQueue(EventQueue& queue);

        bool done() const { return _done; }
        
        double getTime() const { return _eventQueue->getTime(); }
        
        Producer::KeyboardMouse* getKeyboardMouse() { return _keyboardMouse; }
        const Producer::KeyboardMouse* getKeyboardMouse() const { return _keyboardMouse; }
         
        osgGA::GUIEventAdapter* createEventAdapter();

        void updateWindowSize();
         
    protected:
    
    
        Producer::KeyboardMouse* _keyboardMouse;
        float _mx, _my;
        unsigned int _mbutton;
        bool &_done;
        bool _escapeKeySetsDone;

        osg::ref_ptr<osgGA::EventQueue>      _eventQueue;
        
};

}

#endif
