/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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 <osgProducer/EventAdapter>

#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) :
            Producer::KeyboardMouseCallback(),
            _keyboardMouse(keyboardMouse),
            _mx(0.0f),_my(0.0f),_mbutton(0),
            _done(done),
            _escapeKeySetsDone(escapeKeySetsDone)            
            {}

        virtual ~KeyboardMouseCallback() {}

        // override KeyboardMouseCallback methods.
        virtual void mouseScroll( Producer::KeyboardMouseCallback::ScrollingMotion sm );
        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 std::vector< osg::ref_ptr<EventAdapter> > EventQueue;

        double getEventQueue(EventQueue& queue);

        bool done() { return _done; }
        float mx()  { return _mx; }
        float my()  { return _my; }
        unsigned int mbutton()  { return _mbutton; }
        
        void setStartTick(osg::Timer_t tick) { _startTick = tick; }
        
        double getTime() { return _timer.delta_s(_startTick,_timer.tick()); }
        
        Producer::KeyboardMouse* getKeyboardMouse() { return _keyboardMouse; }
        const Producer::KeyboardMouse* getKeyboardMouse() const { return _keyboardMouse; }
         
        EventAdapter* createEventAdapter();

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

        osg::Timer_t    _startTick;
        osg::Timer      _timer;
        OpenThreads::Mutex _eventQueueMutex;
        EventQueue      _eventQueue;
        
};

}

#endif
