/* -*-c++-*- header - Open Producer - Copyright (C) 2002 Don Burns
 * Distributed under the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE (LGPL)
 * as published by the Free Software Foundation.
 */

#ifndef PRODUCER_KEYBOARD_MOUSE
#define PRODUCER_KEYBOARD_MOUSE 1

#include <OpenThreads/Thread>

#include <Producer/Export>
#include <Producer/Referenced>

#include <Producer/Types>
#include <Producer/BlockingQueue>
#include <Producer/RenderSurface>
#include <Producer/InputArea>
#include <Producer/Keyboard>

namespace Producer {

class PR_EXPORT KeyboardMouseCallback : public Referenced 
{
    public :
        KeyboardMouseCallback( ) { }
        enum ScrollingMotion {
            ScrollNone,
            ScrollUp,
            ScrollDown
        };
        virtual void mouseScroll( ScrollingMotion ) {}
        virtual void mouseMotion( float, float) {}
        virtual void passiveMouseMotion( float, float) {}
        virtual void buttonPress( float, float, unsigned int ) {}
        virtual void doubleButtonPress( float, float, unsigned int ) {}
        virtual void buttonRelease( float, float, unsigned int ) {}
        virtual void keyPress( KeyCharacter ) {}
        virtual void keyRelease( KeyCharacter ) {}
        virtual void specialKeyPress( KeyCharacter ) {}
        virtual void specialKeyRelease( KeyCharacter ) {}
        virtual void shutdown() {}
        virtual bool idle() { return false; }
    protected:
        ~KeyboardMouseCallback() {}
};

class PR_EXPORT KeyboardMouse : public Referenced, public OpenThreads::Thread
{
    public :
        KeyboardMouse(Producer::RenderSurface *rs);

        KeyboardMouse(Producer::InputArea *inputArea);
            
        void update(KeyboardMouseCallback &, bool block=false);
            
        void setCallback( KeyboardMouseCallback *cb );
            
        void positionPointer( float x, float y );
            
        Producer::RenderSurface *getRenderSurface() { return _rs.get(); }
        const Producer::RenderSurface *getRenderSurface() const { return _rs.get(); }

        Producer::InputArea *getInputArea() { return _inputArea.get(); }
        const Producer::InputArea *getInputArea() const { return _inputArea.get(); }

        /** compute, from normalized mouse coords (x,y) the,  for the specified 
          * RenderSurface, the pixel coordinates (pixel_x,pixel_y). return true 
          * if pixel_x and pixel_y have been successful computed, otherwise return 
          * false with pixel_x and pixel_y left unchanged.*/
        bool computePixelCoords(float x, float y, RenderSurface* rs, float& pixel_x, float& pixel_y); 

    protected:

        virtual ~KeyboardMouse();

        class KeyboardMouseImplementation *_implementation;

        Producer::ref_ptr< Producer::RenderSurface >_rs;
        Producer::ref_ptr< Producer::InputArea >_inputArea;
        Producer::ref_ptr< KeyboardMouseCallback >_cb;
        bool _initialized;
        bool init();
        virtual void run();
};

}
#endif
