/* osgEarth
 * Copyright 2008-2014 Pelican Mapping
 * MIT License
 */
#ifndef OSGEARTH_REX_LOADER
#define OSGEARTH_REX_LOADER 1

#include "Common"
#include "LoadTileData"

#include <osgEarth/Threading>
#include <osgEarth/FrameClock>
#include <osg/Node>
#include <queue>

namespace osgEarth { namespace REX
{
    using namespace osgEarth;
    using namespace osgEarth::Threading;

    /**
     * A queue that merges new tile data into the respective tile.
     */
    class Merger : public osg::Node
    {
    public:
        //! Construct a new merger
        Merger();

        //! Maximum number of merges to perform per UPDATE frame
        //! Default = unlimited
        void setMergesPerFrame(unsigned value);

        //! clear it
        void clear();

        //! Merge the tile load results into the host tile
        void merge(
            LoadTileDataOperationPtr data,
            osg::NodeVisitor& nv);

    public:
        void traverse(osg::NodeVisitor& nv) override;

        void releaseGLObjects(osg::State* state) const override;

    protected:
        virtual ~Merger();
    private:

        // GL objects compile task
        struct ToCompile {
            std::shared_ptr<LoadTileDataOperation> _data;
            Future<osg::ref_ptr<osg::Node>> _compiled;
        };

        // Queue of GL object compilations to perform per-merge,
        // if an ICO is installed
        using CompileQueue = std::list<ToCompile>;
        CompileQueue _compileQueue;
        CompileQueue _tempQueue;

        // Queue of tile data to merge during UPDATE traversal
        using MergeQueue = std::queue<LoadTileDataOperationPtr>;
        MergeQueue _mergeQueue;
        jobs::jobpool::metrics_t* _metrics;

        Mutex _mutex;
        unsigned _mergesPerFrame;

        FrameClock _clock;
    };

} }


#endif // OSGEARTH_REX_LOADER
