#ifndef OSGEARTH_UTIL_IMAGE_OVERLAY_H
#define OSGEARTH_UTIL_IMAGE_OVERLAY_H

#include <osgEarthUtil/Common>
#include <osgEarth/GeoData>
#include <osgEarth/DrapeableNode>
#include <osgEarth/Units>

#include <osg/Group>
#include <osg/Geometry>
#include <osg/Image>
#include <osg/CoordinateSystemNode>

namespace osgEarth { namespace Util
{
    class OSGEARTHUTIL_EXPORT ImageOverlay : public DrapeableNode
    {
    public:    
        
        enum ControlPoint
        {
            CONTROLPOINT_CENTER,
            CONTROLPOINT_LOWER_LEFT,
            CONTROLPOINT_LOWER_RIGHT,
            CONTROLPOINT_UPPER_LEFT,
            CONTROLPOINT_UPPER_RIGHT
        };
        
        ImageOverlay(MapNode* mapNode, osg::Image* image = NULL);

        void setCorners(const osg::Vec2d& lowerLeft, const osg::Vec2d& lowerRight, 
                        const osg::Vec2d& upperLeft, const osg::Vec2d& upperRight);

        void setLowerLeft(double lon_deg, double lat_deg);
        const osg::Vec2d& getLowerLeft() const { return _lowerLeft; }

        void setLowerRight(double lon_deg, double lat_deg);
        const osg::Vec2d& getLowerRight() const { return _lowerRight;}

        void setUpperLeft(double lon_deg, double lat_deg);
        const osg::Vec2d& getUpperLeft() const { return _upperLeft; }

        void setUpperRight(double lon_deg, double lat_deg);
        const osg::Vec2d& getUpperRight() const { return _upperRight;}

        osg::Vec2d getCenter() const;
        void setCenter(double lon_deg, double lat_deg);

        osg::Vec2d getControlPoint(ControlPoint controlPoint);
        void setControlPoint(ControlPoint controlPoint, double lon_deg, double lat_deg, bool singleVert=false);

        struct ImageOverlayCallback : public osg::Referenced
        {
            virtual void onOverlayChanged() {};
        };

        typedef std::list< osg::ref_ptr<ImageOverlayCallback> > CallbackList;

        void addCallback( ImageOverlayCallback* callback );
        void removeCallback( ImageOverlayCallback* callback );


        osgEarth::Bounds getBounds() const;
        void setBounds(const osgEarth::Bounds& bounds);

        void setBoundsAndRotation(const osgEarth::Bounds& bounds, const Angular& rotation);

        osg::Image* getImage() const;
        void setImage( osg::Image* image );

        void setNorth(double value_deg);
        void setSouth(double value_deg);
        void setEast(double value_deg);
        void setWest(double value_deg);

        float getAlpha() const;
        void setAlpha(float alpha);

        virtual void traverse(osg::NodeVisitor& nv);

        void dirty();
    private:
        void fireCallback(ImageOverlay::ControlPoint point, const osg::Vec2d& location);

        void postCTOR();
        void init();
        void clampLatitudes();
        osg::Vec2d _lowerLeft;
        osg::Vec2d _lowerRight;
        osg::Vec2d _upperRight;
        osg::Vec2d _upperLeft;
        osg::ref_ptr< osg::Image > _image;
        bool _dirty;
        OpenThreads::Mutex _mutex;
        osg::Geode* _geode;
        osg::Geometry* _geometry;
        float _alpha;
        CallbackList _callbacks;
    };

} } // namespace osgEarth::Util

#endif // OSGEARTH_UTIL_IMAGE_OVERLAY_H

